开源达人C语言汇总,学习C语言这一篇就足够了。精不经典我不管,我就喜欢这一款。

/* 

 思考:从人类的视角,从上帝的视角,从整体方面,从细节方面 
 
 1,实例化对象来考虑这个需求
 2,数据处理中数据的角度
 3,实现数据处理中的逻辑部分

*/


按装 visual studio installer 错误 windows installer 服务不可用 请重启系统 然后重试

C语言帮助手册
https://zh.cppreference.com/w/c

C语言w3cschool学习 速查手册
https://m.w3cschool.cn/c/c-intro.html

Melon库的词法分析器组件
https://www.bilibili.com/video/BV1Fh4y1S7vH/?spm_id_from=pageDriver&vd_source=46fa5bfb97ac45037f67309786366805

Melon库的词法分析器组件,并使用词法分析器实现对一个简单的配置文件的解析。
Melon是一个通用高性能C语言库,里面提供了日常开发所需要的常用组件,且Melon支持跨平台,提供docker容器以及webassembly支持。内含中英文文档,及各组件示例。无第三方软件包依赖,安装简便,开箱即用。
Github: https://github.com/Water-Melon/Melon



C语言的开源库非常丰富,以下是一些常见且受欢迎的库:

C标准库:这是C语言自带的标准库,提供了基础的输入输出操作、内存管理、字符处理等功能。

C标准库扩展:例如 GNU libc,提供了标准库中未包含的额外功能。

数据结构和算法库:

GLib供了很多常用的数据结构和算法,广泛用于GNOME等项目。

linq语言的LINQ实现。

多媒体处理库:

FFmpeg:用于处理音频和视频的开源项目。

libswresample:FFmpeg的一部分,提供音频和视频的重采样。

图形和游戏开发库:

SDLimple DirectMedia Layer,用于跨平台的游戏开发。

Allegro:一个成熟的游戏程序库,提供丰富的图形和媒体支持。

网络库:

cURL于传输数据的客户端库,支持多种协议。

libssh:用于SSH连接和操作的库。

文本处理库:

PCREerl Compatible Regular Expressions,用于正则表达式的处理。

Oniguruma:另一个正则表达式引擎,支持多语言。

并发和多线程库:

POCOPortable Component-based Server and Application Framework for C++。

libuv:跨平台的事件循环,常用于Node.js的C语言后端。

安全和加密库:

OpenSSL:用于加密通信的库,广泛应用于安全系统。

TLS:用于数据加密传输的安全协议。

物联网库:

mbedTLS:提供安全的传输层加密,适用于内存和处理能力有限的设备。

LiteOS:华为开源的物联网操作系统。

机器学习库:

darknet:一个用于计算机视觉的开源的、简单的、快速的的神经网络框架。

TensorFlow Lite:TensorFlow的轻量级版本,适用于移动和嵌入式设备。

单元测试库:

CUnit:用于C语言的单元测试框架。

CMock:用于C单元测试的模拟框架。

**


#include 
空行
main函数 主函数
函数体
执行语句 prntf();
return 
/**/ //

//==========================================

//====== 数据类型

比方:室内类型,室外类型

1,基本类型
2,构造类型
3,指针类型
4,空类型


基本类型:
	整型(基本整型,短整型,长整型)
 	字符型
 	浮点型(单精度,双精度)

构造类型(数组,结构体,共用体)
指针类型 ( *p ) 
空类型 ( void ) 


//====== 常量

1,数值型常量(整型常量,实型常量)
2,字符型常量
3,符号常量

数值型常量
   	整型常量(八进制 0前缀 0-7 ,十进制  0-9 ,十六进制 0x前缀 0-9 A-F a-f)
   	浮点型常量 - 实型常量(单精度,双精度)
   	字符型常量 (字符常量,字符串常量)

符号常量
	#define 
	const


//====== 转义字符

\n 回车换行
\t  
\v 
\b 退格
\r  回车
\f 

 
//=== 变量

1,整型变量
2,实型变量
3,字符型变量

整型变量
	有符号基本整型  int name
	无符号基本整型  unsigned name
	有符号短整型     short name
	无符号短整型     unsigned short name
	有符号长整型     long name
	无符号长整型     unsigned long name
	
实型变量
	单精度 float    -3.4*10^38 - 3.4*10^38
	双精度 double -1.7*10^-308 - 1.7*10^308 
	长双精度  -1.2*10^-4932 - 1.2*10^4932

字符型变量
char name;

 
//=== 混合运算



//=== 运算符与表达式

赋值运算与赋值表达

	类型 变量名 = 常数;
	int  name = val;
 
类型转换
	自动类型转换 
		float i = 10.1f
		int j = i;

	强制类型转换
		float i = 10.1f
		int j = (int) i;

算术运算符与算术表达式
	
	算术的一些表达式

	int ++i;
	int i++;
	int  --i;

	&& 和
	||     或
	!    非

	复合运算:
	int value;
	value+=3;

注释:

	/*注释内容*/
	//注释内容

sizeOf 运算符:

	//取得数据类型内存的空间大小
	char name;
	sizeOf(name); 

//=== 数据输入输出


putchar(); 字符输出
getchar(); 字符输入
puts(); 字符串输出
gets(); 字符串输入
printf(); 格式化输出
scanf(); 格式化输入


	
字符输出 putchar();

		#include<stdio.h>

		int main(){
			//printf("第一个c\n");
			putchar(int name);  //字符输出
			return 0;

		}


字符输入 getchar();
		#include<stdio.h>

		int main(){
			//printf("第一个c\n");
			int i = getchar("请输入单个字符");  //字符输入
			return 0;

		}

字符串输出 puts();

	puts();

字符串输入 gets();

	gets();

格式化输出 printf();
	
	printf();

格式化输入 scanf();

	scanf();


==================================================

格式控制符:
%d:用于输出十进制有符号整数。
%u:用于输出十进制无符号整数。
%f:用于输出十进制浮点数字。
%e 或 %E:用于输出指数形式的浮点数。
%g 或 %G:用于输出浮点数,根据数值大小自动选择使用 %f 或 %e。
%o :用于输出无符号八进制。
%x 或 %X:用于输出无符号十六进制。
%c:用于输出单个字符。
%s:用于输出字符串。
%p:用于输出指针地址。
%lu:用于输出无符号长整型。
%lld 或 %I64d:用于输出有符号长长整型。
%llu 或 %I64u:用于输出无符号长长整型。
%Lf:用于输出长双精度浮点数。
%% 格式控制符:用来输出百分号 %,在输出时需要使用两个百分号连在一起。

格式修饰符:
-:左对齐。
+:输出符号(正数前面加上“+”)。
#:八进制前缀(0)、十六进制前缀(0x 或 0X)或浮点数小数点(.)。
0:用 0 在左侧填充数据输出的空白,而不是默认的空格字符。
m.n:m 是指定的最小宽度,n 是指定的精度。
*:用来接收动态传入的宽度和精度。例如,%*.*f 表示输出浮点数,宽度和精度由后面带两个 int 类型的参数动态传入。
转义字符:
\a:警报(响铃)。
\b:退格(回退)一格。
\f:换页。
\n:换行。
\r:回车。
\t:水平制表符。
\v:垂直制表符。
\\:反斜杠。
\':单引号。
\":双引号。
\?:问号。
\0:字符串结束标志。

==================================================



第7章  循环控制 
 
//=== 选择结构

	if(){}

	if(){}else{}
	
	if(){}else if(){}

	if() 嵌套


//=== 条件运算符

条件运算符,PHP的三元运算符
	表达式1 ? 结果a : 结果b; 

switch(){}语句
	switch(){
		case 1:
			printf();
			break;
		case 2:
			printf();
			break:
		case 3:
			printf();
			break;
		default : 
			printf();
			break;
	}




//=== 循环控制

while语句
	while( n< 10){
		printf();	
	}

do... while语句
	do{
		int name++;
	}while(name<10);

for语句
	for(i=1; i<10; i++){
		printf
	}

//=== 转移语句

goto语句
	goto name;
	
	name:
		//代码块.........

break语句

continue语句
	continue;


	 
第8章  //=== 数组

一维数组
二维数组
多维数组
字符数组(字符数组,可以存放字符串)
多维数组


一维数组
	int arr[5];
	
	int arr[6] = { 1,2,3,4,5 }
	
	int arr[6] = { 1,2,3 }     arr[0] = 1  arr[1] = 2  arr[2] = 3
	
	int arr[] = { 1,2,3 }


二维数组
	inf arr[3][4];
		arr[0][0] arr[0][1] arr[0][2] arr[0][3] 
		arr[1][0] arr[1][1] arr[1][2] arr[1][3]  
		arr[2][0] arr[2][1] arr[2][2] arr[2][3]  
		
		00 01 02 03
		10 11 12 13
		20 21 22 23

		0 1 2 3
		1
		2


#include<stdio.h>

int main(){
	int ar[3][3];
	int i,j;

	for(i=0; i<3; i++){
		for(j=0; j<3; j++){
			printf("ar[%d][%d]",i,j);
			scanf("%d",&ar[i][j]);
		}
	}


	printf("输出二维数组\n");

	
	
	for(i=0; i<3; i++){
		for(j=0; j<3; j++){
			printf("%d\t",ar[i][j]);
		}
		printf("\n");
	}
	return 0;
}





字符数组




注: c语言中,没有字符串变量,没有String类,以字符数组的形式存放字符串。
	字符数组保存字符串时,会末尾多加一个  \0
例:
char ar[] = "abcdef";

内存中的情况如下:
a b c d e f \0

//字符数组的输入和输出
可以使用 %c   %s    前者逐个,后者整个字符串输出。


for(i=0; i<5; i++){
	printf("%c\n",ar[i])l;
}


int ar[] = "abcdef";
prntf("%s\n",ar)j;


//定义数组1
char ar[5];
 
ar[0]="a";
ar[1]="b";
ar[2]="c";
ar[3]="d";
ar[4]="e";

//定义数组2
char ar[5] = {'a','b','c','d','e',}

//定义数组3
char ar[] = {'a','b','c','d','e',}


//定义数组4   注意:这个方法用的最多!!!!
char ar[] = "abcdef";


====================================
demo:

#include<stdio.h>

int main(){
	char str[5]={'a','b','c','d'};
	int i;

	for(i=0; i<10; i++){
		printf("%c",str[i]);
	}
	return 0;
}

	
	char str[5]={'a','b','c','d'}; //字符数组

	char str[] = "abcd"  //存放字符串

	%c  逐个输出

	%s  整个字符串输出  


多维数组


数组的排序算法

嵌套循环原理: 外边循环一次,里边全部循环完。

	选择排序
	冒泡排序
	交换排序
	插入排序
	拆半排序



========================================================	



第9章   //=== 函数

#include<stdio.h>

void smfun(int a, int b);  //函数声明
int main(){
	//语块
}
void smfun(){
	//语块
}



//=函数参数:  形参,实参。

#include<stdio.h>

void smfun(int a, int b);  //函数声明    a b 函数的形参
int main(){
	//语块
	smfun(int 1, int 2); //实参  调用函数时的参数
}
void smfun(){
	//语块
}


//==数组做为函数的参数:

#include<stdio.h>
void getva(int a);

int main(){
   //声明参数
   int i,j;
   int ar[5];
    
   //建数组 for
   for(i=0; i<5; i++){
        ar[i];
   }
   
   //循环输出数组参数的函数 for
   for(j=0; j<5; j++){
        getva(ar[i]);
   }
    return 0;
}

//函数
void getva(int a){
   printf("这是一个数组函数参数的%d\n",a);
}


//==数组名做为函数的参数:
数组名表示数组中第一个元素的地址;


//==长度可变数组作为函数参数:
未指明数组大小,就属于长度可变的数组作为函数参数;


//==函数的调用和返回

语句调用        int  fun();
表达式调用     iRes = iNum3*Addnum(3,4);
函数参数调用  fun(10,funadd(3,5));

//=返回值

return 0;

//==函数的嵌套调用

不允许嵌套定义,可嵌套调用

//==函数的递归调用

函数调用自已。

涉及指针,回头再学

//==内部函数和外部函数

内部函数,static int add() 也叫静态函数,不可以源文件外调用
外部函数,extern int add() , 可以被其它源文件 调用;

//==局部变量和全局变量

局部使用的变量
全局变量,外部访问使用 extern 进行修饰;

//==常用标准函数库

编译系统会提供一些标准函数库;

数学函数库
字符判别函数库
字符串处理函数

========================================================	

//=函数
void fun(){
}

int main(){
	//.....
	return;
}


//函数定义
void fun(int a){
	//函数体
}


//函数形参和实参
void fun(形参){
}

void  fun(实参){
}


//数组做函数的参数   注:和正常的变量一样。
void fun(){}
int main(){
	int ar[10] = "0,1,2,3,4,5,6,7,8,9"
	for(i=0;i<10;i++){
		fun(ar[i]);
	}
}


//数组名作为函数的参数     注:和正常的变量一样。

数组名,为数组的第一个元素地址;


//长度可变数组作为函数的参数

2个字符串连接

#include<stdio.h>

void str(char str1[],cha str2[]){
	int i,j;
	for(i=0; str1[i]!="\0"; i++){
		for(j=0; str2[j]!="\0"; j++){
			str[i+j]=str2[j];
		}
	str[i+j]="\0";
	}
}




//=函数的调用和返回

fun(){}

fun();

fun(){
	return 0;
}

//函数的嵌套调用

在一个函数体内调用另一个函数。

void fun1(){
	//.....
}

void fun2(){
	fun1();
}

//函数的递归调用

函数自已调用自已


注:

int p       变量
int *p      指针
int **p    指向指针的指针    注意:通常用表现为指向数组的指针



//内部函数和外部函数

内部函数,又称为静态函数。只在当前源文件中调用,不被其它源文件调用。
static fun();

外部函数,是可以被其它源文件函数调用的函数。
extern fun();


//局部变量和全局变量

局部变量:函数体内变量称为局部变量,只在函数体内有效。

全局变量:在全局程序中有效的变量。



//常用标准函数库

绝对值函数:
abs();
labs();
fabs();

三角函数:
sin();
cos();
tan();

字符判别函数:
isalpha();
isdigit();
isalnum();

字符串处理函数:
strcpy();
strcat();
strcmp();
strupr();
strlwr();



========================================================	



第10章   //=== 指针

int a = 6;      //变量
int *p =&a;  //取变量 a 的内存地址; 


注:

int p        变量
int *p      指针
int **p     指向指针的指针    注意:通常用表现为指向数组的指针




//==指针的相关概念
//==地址与指针



内存的原理:

取变量i   找到地址,  占了4个内存单元,4个字节,  把地址放到CPU的寄存器中,最后通过cpu进行逻辑运算。

变量                              地址       内容

变量i    -------------->   1000        0
		    1001
  		    1002
	                    1003	   


首先要定义指针:
int *p;
int a;

*p = &a;

&a //取得内存的地址;
*p  //取得内存地址的变量内容;

================================

#include<stdio.h>

int main(){
	int i;
	int *p;

	scanf("%d",&i);

	p = &i;

	printf("%x\n",*p);
	return  0;

}


==================================
注:复习写法!!!

int i;
int *p;

scanf("%d",&i);

p=&i;
printf("%s\n",*p);
return 0;



//==指针的自增自减


int i,*ar[10]l;
i = &ar[0];  //第一个索引;

============================
这是一个写法,变量数组。

#include<stdio.h>

int main(){
	int ar[5];
	int *q;
	int i;

	for(i=0; i<5; i++){
		ar[i];
	}

	q = &ar;

	printf("%d\n",q);      //1703708

	printf("%d\n",q+1);  //1703712

	printf("%d\n",q+2);  //1703716

	return 0;
}


//==二维数组与指针



	&a[0][0]    &a[0][1]   &a[0][2]   &a[0][3]   &a[0][4]
	a[0]+0      a[0]+1      a[0]+2      a[0]+3     a[0]+4       
a
&a[0]

a+1 
&a[1]

a+2
&a[2]



//==字符串与指针


访问字符串的两种方式:
1,使用字符串
2,使用字符指针

1,
char ar[] = "abckde";
printf("%s\n",ar);


2,
注意:指针数组不需要声明;
#include<stdio.h>

int main(){
	char *str = "abckde";
	printf("%s",str);
	return 0;
}

//==指针数组

字符数组是一维数组;
指针数组是字符串为数组元素的数组;

注:为了更好的优化内存,减少内存中字节的占有数量;
5个字符的字符串,再加了末尾的\0, 长度占用内存字节6个,而内存中就要用20个字节给这个字符串,这会浪费内存的占有资源。所以这时要用到指针数组。

demo:

#include<stdio.h>

int main(){
	int i;
	char *ar[] = {"aa","bb","cc","dd"};
	for(i=0; i<4; i++){
		printf("%s\n",ar[i]);
	}
	return 0;

}


//==指向指针的指针


指针指向另一个指针的指针。

i(&i)->p1(&p1)->p2



int **p;






数组名,是内存中数组地址的首地址。

int a[10]
for(){
	print("%d",*(p+i))
}


for(){
	print("%d",*p++)
}

p=a

两者是一样的。获取的变量值是相同的。
但是,*p++  要注意移动指针到首地址。p=a 方便再去写其它的需求。





//==指针变量作函数参数

1,形参为整数变量的,交换的是形参的值,而实参未改变。
2,形参为指针变量的,可以通过改变形参指针变量指向的值,来间接改变实参指向的值。



//==返回指针的函数和指向函数的指针

定义:
int *fun(int x, int y);

调用
fun(a,b);

函数体:
int *fun(int a,int b){
	//函数体
}



//==指针数组作main函数的参数

//主入口函数
main(int argc,char *argv){
	//方法体
}






第11章 //=== 结构体和共用体   类似PHP中的对象。

struct Pro {
	char Name[10];
	char shap[10];
	char color[10];
	char cfunc[10];
	int iPrice;
}


struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
}





//==定义结构体
demo:

#include<stdio.h>






//==结构体
struct Books{
	char title[50];
	char author[50];
	char subject[100];
}

int main(){
	
	return 0;
}






//==结构体变量定义

struct Books{              //声明结构体 struct 
	char title[50];
	char author[50];
	char subject[100];
}
struct Books books1;  //声明结构体变量
struct Books books2; 

或者
struct Books{              //声明结构体 struct 
	char title[50];
	char author[50];
	char subject[100];
}boos1, books2;






//==结构体变量的引用         结构体变量名.成员名;

books1.title;
books2.title="修改后的标题";





//==结构体类型的初始化

struct Books{                                 //声明结构体 struct 
	char title[50];
	char author[50];
	char subject[100];
}books1 = {"biaoti","作者",1000}     //声明结构体变量并做类型初始化
struct Books books1;                     //声明结构体变量
struct Books books2; 




//==定义结构体数组


//结构体数组:

           name   age   sex   
ar[0]
ar[1]
ar[2]
ar[3]
ar[4]


//内存中结构体数组的存储形式:

ar[0]         name1 
	age1
	sex1
ar[1]         name2
	age2
	sex2
ar[2]         name3
	age3
	sex3

//定义结构体数组:

struct Books{                                 //声明结构体 struct 
	char title[50];
	char author[50];
	char subject[100];
}Books[5];



//初始化结构体数组

struct Books{                                 //声明结构体 struct 
	char title[50];
	char author[50];
	char subject[100];
 
}Books = {                                    //初始化结构体数组
	{"titel1","author1",subject1}	
	{"titel2","author2",subject2},
	{"titel3","author3",subject3},
	{"titel4","author4",subject4},
	{"titel5","author5",subject5},
}



//==结构体指针

//指向结构体变量的指针

指向结构体变量的指针,指向的是结构体变量的首地址;

struct Student *pstruct;




//声明定义结构体指针
struct Books *bname;  //结构体指针

//调用结构体成员,使用结构体成员。
//方法1
(*bname).title;
(*bname).title = "wulei";

//方法2
bname->title="wulei"l;



//==指向结构体数组的指针


注:指向结构体数组的指针指向的是内存中的数组首地址!请注意!!!!


//定义结构体指针
struct Books *books1;
//结构体指向结构体数组
book1=Books;

//调用结构体成员,使用结构体成员。
//方法1
(*bname).title;
(*bname).title = "wulei";

//方法2
bname->title="wulei";



//==结构体在函数中的使用


1 结构体的变量做为函数的参数
2 结构体指针作为函数的参数
3 结构体成员作为函数参数


1 结构体的变量做为函数的参数 demo:

#include<stdio.h>

struct Xs{
	char name[10];
	int age[3];
}xs={"wulei",30};


void Xss(struct Xs stu){    //函数中使用结构体的变量
	printf("%s正在学习\n",stu.name);
}

int main(){
	Xss(xs);   //函数中使用结构体的变量
	return 0;
}


2 结构体指针作为函数的参数

demo:

#include<stdio.h>

//需求学生姓名,成绩,显示。函数调用结构体的指针,节省调用结构体占用的内存空间开销;

//结构体
struct Student{
	char name[10];
	float cj[3];
}student={"wulei",60,50,90};

//函数
void Displaya(struct Student *sta){    //函数传入 定义的结构体的指针
	printf("以上是学生的成绩----\n");
	printf("他的成绩是:%.2f\n",sta->cj[2]);   //通过结构体的指针,去改变结构体的成员值
	sta->cj[2]=1000;    
}

//主入口方法
int main(){
	struct Student *stb=&student;   //引用结构体变量,传给结构体指针
	Displaya(stb);    //函数,传入结构体指针   
	printf("修改后的成绩是:%.2f\n",stb->cj[2]);   
	return 0;
}


3 结构体成员作为函数参数

Displaya(student=->cj[2]);  




//==使用函数返回结构体指针



//==嵌套的结构体

结构体的成员,也可以是结构体




//=== 链条

//=链条的相关操作



#include<stdio.h>
#include<stdlib.h>

/* 

 思考:从人类的视角,从上帝的视角,从整体方面,从细节方面 
 
 1,实例化对象来考虑这个需求
 2,数据处理中数据的角度
 3,实现数据处理中的逻辑部分

*/



//=链接

malloc(); //在内存中动态分配一块size大小的内存空间
calloc(); //在内存中动态分配N个长度的size连续内存空间(连续)
free(); //释放指针指向的内存区域

===================================

#include<stdio.h>
#include<stdlib.h>


//结构体
struct Student
{
    char cName[20];							     	    /*姓名*/
    int iNumber;								    /*学号*/
    struct Student* pNext;							    /*指向下一个结点的指针*/
};


//增加新链条的动作
int iCount;								/*全局变量表示链表长度*/
struct Student* Create()
{
    struct Student* pHead=NULL;						    /*初始化链表头指针为空*/
    struct Student* pEnd,*pNew;
    iCount=0;								    /*初始化链表长度*/
    pEnd=pNew=(struct Student*)malloc(sizeof(struct Student));
    printf("请输入名字、学号:\n");
    scanf("%s",&pNew->cName);
    scanf("%d",&pNew->iNumber);

    while(pNew->iNumber!=0)
    {
        iCount++;
        if(iCount==1)
        {
            pNew->pNext=pHead;	    /*使得指向为空*/
            pEnd=pNew;							     /*跟踪新加入的结点*/
            pHead=pNew;							     /*头指针指向首结点*/
        }
        else
        {
            pNew->pNext=NULL;		/*新结点的指针为空*/
            pEnd->pNext=pNew;		/*原来的尾结点指向新结点*/
            pEnd=pNew;						     	       /*pEnd指向新结点*/
        }
        pNew=(struct Student*)malloc(sizeof(struct Student));	/*再次分配结点内存空间*/
        scanf("%s",&pNew->cName);
        scanf("%d",&pNew->iNumber);
    }
    free(pNew);								       /*释放没有用到的空间*/
    return pHead;
}


////显示这个链接 输出节点
void Print(struct Student* pHead)
{
    struct Student *pTemp;	/*循环所用的临时指针*/
    int iIndex=1;								    /*表示链表中结点的序号*/
    printf("----有 %d 个成员:----\n",iCount);	/*消息提示*/
    printf("\n");								    /*换行*/
    pTemp=pHead;								    /*指针得到首结点的地址*/
    while(pTemp!=NULL)
    {
        printf("NO%d 成员:\n",iIndex);
        printf("姓名: %s\n",pTemp->cName);	   /*输出姓名*/
        printf("学号: %d\n",pTemp->iNumber); /*输出学号*/
        printf("\n");								        /*输出换行*/
        pTemp=pTemp->pNext; /*移动临时指针到下一个结点*/
        iIndex++;							    	        /*进行自加运算*/
    }
}


//主入口函数
int main()
{
    struct Student* pHead;							    /*定义头结点*/
    pHead=Create();								    /*创建结点*/
    Print(pHead);							    	    /*输出链表*/
    return 0; 
    /*程序结束*/
}




//==共用体


union name{
	char name;
	int age;
	//成员列表
}

union name.name;


结构体:数据成员的大小的总和
共用体:数据成员的最大内存长度的大小


union name{
	char name;
	int age;
	//成员列表
}

union name.name;




结构体:数据成员的大小的总和
共用体:数据成员的最大内存长度的大小


demo1:

#include "stdio.h"
#include <string.h>


  /*声明公交车结构体类型*/ 
  struct bus 
  {
    char name[64];
  };

  /* 声明地铁结构体类型*/
  struct plane 
  {
    char name[64];
  };

  /*声明共用体类型*/
  union Transportation 
  {
   struct bus p;
   struct plane c;
  };
int main()
{
 union Transportation t;/*定义一个共用体*/
  strcpy(t.p.name, "地铁");/*将相应的名字复制给相应的变量*/
  strcpy(t.c.name, "公交车");
  printf("员工选择%s\n",t.p.name);/*输出信息*/
  printf("员工选择%s\n",t.c.name);
  return 0;
}

=========================================

demo2:

#include<stdio.h>

union DataUnion			/*声明共用体类型*/
{
	int iInt;								/*成员变量*/
	char cChar;			
};

int main()
{
	union DataUnion Union={97};		/*定义共用体变量,并进行初始化*/
	printf("iInt: %d\n",Union.iInt);		/*输出成员变量数据*/
	printf("cChar: %c\n",Union.cChar);
	return 0;
}


==========================================
//结构体
struct Student
{
	char cName[20];	/*姓名*/
	int iNumber;	/*学号*/
	struct Student* pNext; /*指向下一个节点的指针*/
};


int iCount;								/*全局变量表示链表长度*/

//新建链表节点
struct Student* Create()
{
	struct Student* pHead=NULL;			/*初始化链表,头指针为空*/
	struct Student* pEnd,*pNew;         /*尾和新加节点*/
	iCount=0;	                         /*初始化链表长度*/

	pEnd=pNew=(struct Student*)malloc(sizeof(struct Student));  /* 建内存空间大小 */

	

	/* 输入链条的数据内容 */
	printf("请输入姓名、学号:\n");
	scanf("%s",&pNew->cName);
	scanf("%d",&pNew->iNumber);

	/* 新加的链条不等于0 也就是说 */
	while(pNew->iNumber!=0)
	{
		iCount++;
		if(iCount==1)
		{
			pNew->pNext=pHead;						/*使得指向为空*/
			pEnd=pNew;								/*跟踪新加入的节点*/
			pHead=pNew;								/*头指针指向首节点*/
		}
		else
		{
			pNew->pNext=NULL;						/*新节点的指针为空*/
			pEnd->pNext=pNew;						/*原来的尾节点指向新节点*/
			pEnd=pNew;								/*pEnd指向新节点*/
		}

		 /*再次分配节点内存空间*/
		pNew=(struct Student*)malloc(sizeof(struct Student));	
                              
		scanf("%s",&pNew->cName);
		scanf("%d",&pNew->iNumber);
	}

	free(pNew);										/*释放没有用到的空间 返回头部*/
	return pHead;      
}


//输出链条节点 要写临时的指针 参数是 pHead 头。
void Print(struct Student* pHead)
{
	struct Student *pTemp;						/*循环所用的临时指针*/
	int iIndex=1;								/*表示链表中节点的序号*/

	printf("----有 %d 名成员:----\n",iCount);	/*消息提示*/
	printf("\n");								/*换行*/
	pTemp=pHead;								/*指针得到首节点的地址*/

	while(pTemp!=NULL)
	{
		printf(" NO%d 号成员:\n",iIndex);
		printf("姓名: %s\n",pTemp->cName);	/*输出姓名*/
		printf("学号: %d\n",pTemp->iNumber);	/*输出学号*/
		printf("\n"); /*输出换行*/
		pTemp=pTemp->pNext;  /*移动临时指针到下一个节点*/
		iIndex++;	 /*进行自加运算*/
	}
}


//插入链表节点
struct Student* Insert(struct Student* pHead)
{
	struct Student* pNew;						                /*指向新分配的空间*/
	printf("----插入第1名信息----\n");	/*提示信息*/

	/*分配内存空间,并返回指向该内存空间的指针*/
	pNew=(struct Student*)malloc(sizeof(struct Student));	
                

	/* 输入姓名和学号 */
	scanf("%s",&pNew->cName);
	scanf("%d",&pNew->iNumber);

	pNew->pNext=pHead;						/*新节点指针指向原来的首节点*/
	pHead=pNew;								/*头指针指向新节点*/
	iCount++;								/*增加链表节点数量*/

	return pHead;
}


//删除链表节点
void Delete(struct Student* pHead,int iIndex)
/*pHead表示头节点,iIndex表示要删除的节点下标*/
{
	int i;  									/*控制循环变量*/
	struct Student* pTemp;		 				/*临时指针*/
	struct Student* pPre;							/*表示要删除节点前的节点*/
	pTemp=pHead;								/*得到头节点*/
	pPre=pTemp;

	printf("----删除 NO%d 名成员----\n",iIndex); /*提示信息*/
	for(i=1;i<iIndex;i++)	 /*for循环使得pTemp指向要删除的节点*/
	{
		pPre=pTemp;
		pTemp=pTemp->pNext;
	}
	pPre->pNext=pTemp->pNext;	/*连接删除节点两边的节点*/
	free(pTemp);		/*释放要删除节点的内存空间*/
	iCount--;		                /*减少链表中的元素个数*/
}

//主入口
int main()
{
	struct Student* pHead;	/*定义头节点*/
	pHead=Create();		/*创建节点*/
	pHead=Insert(pHead);	/*插入节点*/
	Delete(pHead,2);		/*删除第二个节点*/
	Print(pHead);		/*输出链表*/
	return 0;			/*程序结束*/
}






//==枚举类型

注:不能被拆分;

enum name(na,ag,red=1);

enum name(na,ag,red=1) name; //定义枚举类型,并赋初始化。





//= typedef关键字

主要作用就是,为数据类型定义一个新的名字。简化结构体的名字

typedef struct Student {
	char *name;
	int age;
} STU;

STU  为这个结构体 重命名;
同时可以 

STU data;





//=== 位运算

在线进制转换器:
https://tool.oschina.net/hexconvert/

进制转换器:
https://tool.ip138.com/hexconvert/

C语言可以代替汇编语言,因为其支持二进制按位运算。

数据在内存中是以二进制的形式存放的。

一个字节 由 8位 二进制数组成。 8位占一个字节。

8bit

11001010

byte(8-bits)

1,按位与运算符
2,按位或运算符
3,按位取返运算符
4,按位异或运算符
5,左移运算符
6,右移运算符

1,按位与运算符

1&1 = 1
1&0 = 0
0&1 = 0

     0000000001011001  十进制89
&  0000000000100110  十进制38
     0000000000000000  十进制0


#include<stdio.h>								/*包含头文件*/
void main()									/*主函数main*/
{
    unsigned result; 	/*定义无符号变量*/
    int age1, age2; 	/*定义变量*/
    printf("请输入第一个人年龄age1:");/*提示输入年龄1*/
    scanf("%d",&age1); 	/*输入年龄1*/
    printf("请输入第二个人年龄age2:"); /*提示输入年龄2*/
    scanf("%d",&age2); /*输入年龄2*/
    printf("age1=%d, age2=%d", age1, age2); /*显示年龄*/
    result = age1&age2; /*计算"与"运算的结果*/
    printf("\nage1&age2=%u\n", result); 	/*输出计算结果*/
}



2,按位或运算符

1|1 = 1
1|0 = 1
0|1 = 1
0|0 = 0

   0000000000010001
|  0000000000011111
   0000000000011111

#include<stdio.h>           /*包含头文件*/
int main()                  /*主函数main*/
{
    int a=0xEFCA,result;    /*定义变量*/
    result = a|a;  /*计算或运算的结果*/
    printf("a|a=%X\n", result);	/*输出结果*/
    return 0;                    	/*程序结束*/
}



3,按位取返运算符

#include<stdio.h>								/*包含头文件*/
void main()/*主函数main*/
{
    unsigned result; 	/*定义无符号变量*/
    int a; 		/*定义变量*/
    printf("please input a:"); 	/*提示输入一个数*/
    scanf("%d",&a); 	/*输入数据*/
    printf("a=%d", a);	 /*显示输入的数据*/
    result = ~a;  	/*求a的反 ~   shift + `  */
    printf("\n~a=%o\n", result); 	/*显示结果*/
}



4,按位异或运算符

0^0 = 0
0^1 = 1
1^0 = 1
1^1 = 0


#include<stdio.h>
main()
{
    unsigned result; 								/*定义无符号数*/
    int a, b;
    printf("please input a:");
    scanf("%d",&a);
    printf("please input b:");
    scanf("%d",&b);
    printf("a=%d,b=%d", a, b);
    result = a^b; 									/*求a与b"异或"的结果*/
    printf("\na^b=%u\n", result);
}





5,左移运算符



a<<2  向左移2位

00000000000000000000000000100111
00000000000000000000000010011100

#include<stdio.h>
main()
{
	int x=15;
	x=x<<2; 	/*x左移两位*/
	printf("左移2的结果:%d\n",x);
	x=x<<3; 	/*x左移3位*/
	printf("再左移3的结果:%d\n",x);
}




6,右移运算符


a >> 2 向右移动





//循环移位

                  32-n  
                               n
x   |                      |=====|   

x   |=====|                      |  


1, y = x>> (32-n)
2, y = x>> n
3, y = y|z




#include <stdio.h>
left(unsigned value, int n)/*自定义左移函数*/
{
    unsigned z;
    z = (value >> (32-n)) | (value << n);	/*循环左移的实现过程*/
    return z;
} 
int main()
{
    unsigned a;
    int n;
    printf("请输入一个数:\n");
    scanf("%o", &a);	/*输入一个八进制数*/
    printf("请输入要移位的位数(>0):\n");
    scanf("%d", &n);	/*输入要移位的位数*/
    printf("循环左移的结果:%o\n", left(a, n));	/*将左移后的结果输出*/
	return 0;
}





//位段


一种特殊的结构体类型,结构体中的成员被称为位段。

struct name {


}




//=== 预处理命令

程序在编译之前进行的处理;

//宏定义 #开头的代码。 
只是用于字符的替换,不分配内存空间。

1,不带参数的  #define命令
2,带参数的  #define命令
3,宏定义的删除  #undef命令
4,预定义宏简介


1,不带参数的  #define命令  行尾可不加 ; 号

//用于字符的替换,不分配内存空间。

#define TEST "替换的代码内宏"  

可以用 #undef TEST 结束宏定;

void fun(){
	printf();
	#undef TEST 
} 



2,带参数的  #define命令

//用于字符的替换,不分配内存空间。


#include<stdio.h>
#define MIX(a,b) ((a)*(b)+(b))	/*宏定义求两个数的混合运算*/
main()
{
	int x=5,y=9;
	printf("x,y:\n");
	printf("%d,%d\n",x,y);
	/*宏定义调用*/
	printf("the min number is:%d\n",MIX(x,y));
}


3,宏定义的删除  #undef命令


#include<stdio.h>
#define TEST

void fun(){
	printf();
	#undef TEST  //宏定义的删除
} 



4,预定义宏简介


__LINE__
__FILE__
__DATE__
__TIME__
__STDC__



//文件包含

#include<stdio.h> //库函数使用

#include "fun.h"   //自定义函数使用

如果希望其中一部分代码编译,只在满足一定条件下才进行编译,就需要使用条件编译命令。




//条件编译


#if
#else
#elif
#endif

判断宏名是否被定义

#ifdef
#ifndef


//其他预处理命令

#line
#error
#pragma



//=== 文件

文件是一组相关数据的有序集合

//=文件基本操作

//文件指针


FILE *fp;


//打开文件

FILE *fp;
fopen("1.txt","r");


//关闭文件

FILE *fp;
fopen("1.txt","r");
fclose(fp);


//=文件读写

打开文件后可以对文件进行读写。

//写入字符

FILE *fp;
fputc("内容",fp);

注: exit(0);

==================

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE *fp; /*定义一个指向FILE类型结构体的指针变量*/
    char ch; /*定义变量为字符型*/
    if((fp = fopen("E:\\exp01.txt", "w")) == NULL) /*以只写方式打开指定文件*/
    {
        printf("不能打开文件\n");
        exit(0);
    }
    printf("请输入名人名言:\n");
    ch = getchar();	/*getchar函数带回一个字符赋予ch*/
    while(ch != '#')/*当输入"#"时结束循环*/
    {
        fputc(ch, fp);	/*将读入的字符写到磁盘文件中*/
        ch = getchar();	/*getchar函数继续带回一个字符赋给ch*/
    }
    fclose(fp);	/*关闭文件*/
	return 0;
}



//读取字符

fgetc();

注意:在C语言循环中输出字符后,通常还需要再次调用fgetc函数是为了确保读取到文件末尾。‌ 


#include<stdio.h>
int main()
{
    FILE *fp;	/*定义一个指向FILE类型结构体的指针变量*/
    char ch;	/*定义变量及数组为字符型*/
    fp = fopen("H:\\poem.txt", "r"); /*以只读方式打开指定文件*/
    ch = fgetc(fp); /*fgetc函数带回一个字符赋予ch*/

    while(ch != EOF)	/*当读入的字符值等于EOF时结束循环*/
    {
        putchar(ch);	/*将读入的字符输出到屏幕上*/
        ch = fgetc(fp);	/*fgetc函数继续带回一个字符赋予ch*/
    }
	printf("\n");
   	fclose(fp);  /*关闭文件*/
	return 0;
}






//写入字符串

fputs();


#include<stdio.h>
#include<stdlib.h>
int main()
{
	FILE *fp;
	char filename[30],str[30];							/*定义两个字符型数组*/
	printf("请输入文件路径:\n");
	scanf("%s",filename);	 /*输入文件名*/
	if((fp=fopen(filename,"w"))==NULL)/*判断文件是否打开失败*/
	{
		printf("不能打开文件!\n请按任意键结束\n");
		getchar();
		exit(0);
	}
	printf("请输入歌词:\n");/*提示输入字符串*/
	getchar();
	gets(str);
	fputs(str,fp); /*将字符串写入fp所指向的文件中*/
	fclose(fp);
	return 0;
}



//读取字符串

fgets(字符数组,n,文件指针);
注:n表示读取的字符串的个数, sizeOf(name); 


#include<stdio.h>
#include<stdlib.h>
int main()
{
	FILE *fp;
	char filename[30],str[30]; /*定义两个字符型数组*/
	printf("请输入文件路径:\n");
	scanf("%s",filename);	  /*输入文件名*/
	if((fp=fopen(filename,"r"))==NULL) /*判断文件是否打开失败*/
	{
		printf("不能打开文件!\n请按任意键结束\n");
		getchar();
		exit(0);
	}
	fgets(str,sizeof(str),fp); /*读取磁盘文件中的内容*/
	printf("%s",str);
	printf("\n");
	fclose(fp);
	return 0;
}


//对磁盘文件格式化函数
//fprintf();
//fscanf();






//读写数据块

实际开发中,往往需要对整块数据进行读写,例如对一个结构体的变量进行读写。

fread();
fwrite();





#include<stdio.h>
#include<stdlib.h>
struct student_list									/*定义结构体,存储实习生基本信息*/
{
    char name[10];
    char adr[20];
    char tel[15];
} info[100];
void save(char *name, int n)	/*自定义save函数*/
{
    FILE *fp;	/*定义一个指向FILE类型结构体的指针变量*/
    int i;
    if((fp = fopen(name, "wb")) == NULL)/*以只写方式打开指定文件*/
    {
        printf("不能打开文件\n");
        exit(0);
    }
    for(i = 0; i < n; i++)
        if(fwrite(&info[i], sizeof(struct student_list), 1, fp) != 1)	/*将一组数据输出到fp所指的文件中*/
            printf("写入有误\n");	/*如果写入文件不成功,则输出错误*/
    fclose(fp);		/*关闭文件*/
}
void show(char *name, int n)/*自定义show函数*/
{
    int i;
    FILE *fp;	/*定义一个指向FILE类型结构体的指针变量*/
    if((fp = fopen(name, "rb")) == NULL)/*以只读方式打开指定文件*/
    {
        printf("不能打开文件\n");
        exit(0);
    } 
    for(i = 0; i < n; i++)
    {
        fread(&info[i], sizeof(struct student_list), 1, fp);	/*从fp所指向的文件读入数据存到info数组中*/
        printf("%15s%20s%20s\n", info[i].name, info[i].adr,info[i].tel);
    }
    fclose(fp);	/*关闭文件*/
}
int main()
{
    int i, n;/*变量类型为基本整型*/
    char filename[50];	/*数组为字符型*/
    printf("一共几名?\n");
    scanf("%d", &n);	/*输入实习生数*/
    printf("请输入文件路径:\n");
    scanf("%s", filename);	/*输入文件所在路径及名称*/
    printf("请输入姓名,地址,手机号\n");
    for (i = 0; i < n; i++)	/*输入实习生信息*/
    {
        printf("NO%d", i + 1);
        scanf("%s%s%s", info[i].name, info[i].adr, info[i].tel);
        save(filename, n);	/*调用函数save*/
    }
	printf("信息如下:\n");
    show(filename, n);	/*调用函数show*/
}











//=文件定位

对文件操作时,往往不需要从文件首开始,只操作指定内容即可,这时,就需要使用文件定位函数。


fseek(文件类型指针,位移量,起始点);  //移动文件内部的位置指针
rewind(文件类型指针);  //指针返回文件首。
ftell(文件类型指针); //得到流式文件的当前位置



fseek(fp,7L,0);   // 7L 是移动7个字节


#include<stdio.h>
#include<stdlib.h>
int main()
{
	FILE *fp;
	char filename[30],str[50]; /*定义两个字符型数组*/
	printf("请输入文件路径:\n");
	scanf("%s",filename); /*输入文件名*/
	if((fp=fopen(filename,"wb"))==NULL) /*判断文件是否打开失败*/
	{
		printf("不能打开文件!\n请按任意键继续\n");
		getchar();
		exit(0);
	}
	printf("请输入字符串:\n");
	getchar();
	gets(str);
	fputs(str,fp);
	fclose(fp);
	if((fp=fopen(filename,"rb"))==NULL) /*判断文件是否打开失败*/
	{
		printf("不能打开文件!\n请按任意键继续\n");
		getchar();
		exit(0);
	}
	fseek(fp,7L,0);
	fgets(str,sizeof(str),fp);
	printf("\n取货号为:\n");
	puts(str);
	fclose(fp);
    return 0;
}






rewind(文件类型指针);   //指针返回到文件首。


#include<stdio.h>
#include<stdlib.h>
int main()
{
	FILE *fp;
	char ch,filename[50];
	printf("请输入文件路径:\n");
	scanf("%s",filename);	/*输入文件名*/						 
	if((fp=fopen(filename,"r"))==NULL) 	/*以只读方式打开该文件*/			 
	{
		printf("不能打开文件\n");
		exit(0);
	}
	printf("\n输入密码:\n");
	ch = fgetc(fp);				
	while (ch != EOF)				
	{
		putchar(ch);/*输出字符*/							 
		ch = fgetc(fp); /*获取fp指向文件中的字符*/							 
	}
   
	rewind(fp);/*指针指向文件开头*/
	printf("\n请再次输入密码:\n");
	ch = fgetc(fp);			
	while (ch != EOF)					
	{
		putchar(ch); /*输出字符*/							 
		ch = fgetc(fp);			
	}
	printf("\n");
	fclose(fp); 	/*关闭文件*/								 
    return 0;
}



ftell(文件类型指针); //得到流式文件当前位置。



#include<stdio.h>
#include<stdlib.h>
int main()
{
		FILE *fp; 	/*定义一个指向FILE类型结构体的指针变量*/
		int n;
		char ch,filename[50];
		printf("请输入文件路径:\n");
		scanf("%s",filename);	 /*输入文件位置*/ 
		if((fp=fopen(filename,"r"))==NULL) /*判断是否能打开文件*/ 
		{
			printf("不能打开此文件\n");
			exit(0);
		}
		printf("密码为:");
		ch = fgetc(fp);	/*读出一个字符*/
		while (ch != EOF)				
		{
			putchar(ch);								 
			ch = fgetc(fp); 						 
		}
			n=ftell(fp);/*输出长度*/
    	if(6==n)	/*判断长度是否等于6*/
			printf("\n设置密码成功\n");
    	else
			printf("\n设置密码失败\n");
		fclose(fp); 	/*关闭文件*/		 
      return 0;
}



//=文件管理

//删除文件 remove();
//重命名文件 rename();
//复制文件




//删除文件 remove();



#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE *fp; /*定义一个指向FILE类型结构体的指针变量*/
    char filename[50];	/*定义数组为字符型*/
    printf("请输入要删除的文件名称:\n");
    scanf("%s", filename);	/*输入要删除的文件的路径及名称*/
    if ((fp = fopen(filename, "r")) != NULL)/*以只读方式打开指定文件*/
    {
        printf("%s 打开成功!", filename);/*文件打开成功输出提示信息*/
        fclose(fp);	/*关闭文件*/
    }
    else
    {
        printf("%s 不能打开!", filename);/*文件打开失败输出提示信息*/
        exit(0);
    }
    remove(filename);/*调用函数删除文件*/
    if ((fp = fopen(filename, "r")) == NULL)
        printf("\n%s 文件已被删除!", filename);	/*若要打开的文件不存在,则删除成功,输出提示信息*/
    else
        printf("错误");	/*若要打开的文件存在,则删除不成功,输出提示信息*/
}






//重命名文件 rename();



#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE *fp;/*定义一个指向FILE类型结构体的指针变量*/
    char filename1[20], filename2[20];/*定义数组为字符型*/

    printf("请输入要重命名的文件:\n");

    scanf("%s", filename1);	/*输入要重命名的文件所在的路径及名称*/

    if ((fp = fopen(filename1, "r")) != NULL)/*以只读方式打开指定文件*/
    {
        printf("%s 打开成功", filename1);
        printf("\n请输入新名字!");

		scanf("%s", filename2);	/*输入新的文件路径及名称*/

		fclose(fp);

        if(rename(filename1, filename2) == 0)
        	printf("已经把文件 %s 修改为 %s.\n",filename1,filename2);
        else
        	perror("rename");
    }
    else
    {
        printf("不能打开!");
        exit(0);
    }
}







//复制文件
把要复制的,放到临时字符串中,再把要复制的,写入到新文件中,再读出内容。

#include<stdio.h>
#include<stdlib.h>
int main()
{
    FILE *in,*out;	/*定义两个指向FILE类型结构体的指针变量*/
    char ch, infile[50], outfile[50];	/*定义数组及变量为基本整型*/
    printf("要被复制的文件名称:\n");
    scanf("%s", infile);/*输入将要被复制的文件所在路径及名称*/
    printf("输入复制出的文件名称:\n");
    scanf("%s", outfile);/*输入新建的将用于复制的文件所在路径及名称*/
    if ((in = fopen(infile, "r")) == NULL)/*以只写方式打开指定文件*/
    {
        printf("不能打开被复制文件\n");
        exit(0);
    }
    if ((out = fopen(outfile, "w")) == NULL)
    {
        printf("不能打开复制出的文件\n");
        exit(0);
    }
    ch = fgetc(in);
    while (ch != EOF)
    {
        fputc(ch, out);	/*将in指向的文件的内容复制到out所指向的文件中*/
        ch = fgetc(in);
    }
    fclose(in);
    fclose(out);
}










//=文件状态检测

//文件读取结束检测 feof();
//文件读写出错检测 ferror();
//清除状态标志 clearerr();



//文件读取结束检测 feof();



#include <stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char a;
	while ((a = fgetc(pf)) != EOF)    //fgetc读取文件时,读取失败返回EOF
	{
		putchar(a);
	}
	if (feof(pf) == 0)
	{
		printf("遇到文件末尾\n");
 
	}
	else
		printf("文件读取失败\n");
	fclose(pf);
	pf = NULL;
	return 0;
}






//文件读写出错检测 ferror();






#include <stdio.h>
int main() {
	FILE *file;
	char c;
	int ret;
	file = fopen("test.txt", "r");
	fputc('A', file);
	if (ferror(file)) {
		perror("文件file发生错误");
	}
	return 0;
}





//清除状态标志 clearerr();


#include <stdio.h>
int main(void) {
	FILE *file;
	char c;
	int ret;
	file = fopen("test.txt", "r");
	fputc('A', file);
	if (ferror(file)) {
		perror("写入文件发生错误");
	}
	clearerr(file);//清除文件的错误标志
	c = fgetc(file);
	printf("c=%c\n", c);
	if (ferror(file)) {
		perror("写入文件发生错误");
	}
	return 0;
}








//=== 内存管理


内存模型示意图:


1, 程序代码区        【静态数据区】    存储在内存的固定位置

2, 常量                  【静态数据区】    存储在内存的固定位置

      未初始化的变量  【静态数据区】    存储在内存的固定位置

      已初始化的变量  【静态数据区】    存储在内存的固定位置
          
3, 堆区  【堆区的内存池中】   动态数据区需要内存动态分配

4, 栈区  【栈区的内存池中】   局部数据对象,函数,以及调用的函数,被调用的函数





//=== 网络套接字编程

包括IP地址,OSI七层参考模型,地址解析,域名系统,TCP/IP协义端口,熟悉套接字的内容。


//=计算机网络基础

//iP地址
//OSI七层参考模型
//地址解析
//域名解析
//TCP/IP协义端口
//端口
//套接字引入
//网络字节顺序




//=套接字基础

服务端:
1,创建套接字
2,套接字绑定IP 端口
3,设置套接字的状态,准备接收客户端的请求
4,接收请求,同时返回一个用于连接的新套接字
5,使用新套接字,进行通信
6,通信完毕,释放套接字


客户端:
1,创建套接字
2,向服务器发出连接请求
3,连接后,与服务器进行通信操作
4,释放套接字。


//套接字的概述
//基于TCP的socket编程
//基于UDP的socket编程



//=套接字函数
//套接字常用函数介绍
//基于TCP的网络聊天程序





























//=== 单词背记闯关游戏
//=== 学生信息管理系统
//=== 单片机基础
//=== GSM短信控制家庭防盗报警

































以下为复习内容:

//==========================================


第3章数据类型

数据类型:
关键字,标识符,数据类型,常量,变量,混合运算符

关键字:具有特定意义的字符串,
标识符:变量,常量,函数,数组等名称,
数据类型:基本类型,构造类型,指针类型,空类型,
常量:整型常量,实型常量,字符型常量,转义字符,符号常量,
变量:  整型变量,实型变量,字符型变量,
混合运算符:不同类型之间的转换

3.1 关键字

3.3 数据类型

整数,浮点数,字符串

内存如何放数据?
数据类型,就是多大内存来存放数据。

char      1字节  单人间
short     2字节  双人间
int         4字节  4人间
double   8字节  8人间


short     2字节  双人间                  【整型】
unsigned short  无符号短整数       【整型】
int         4字节  4人间                   【整型】
unsigned int         4字节  4人间    【整型】
long int  长整型                           【整型】
unsigned long int  长整型            【整型】
char      1字节  单人间                  【字符型】
float     单精度                             【浮点】
double  双精度                            【浮点】

构造类型:
1,数组
2,  结构体
3,共用体

指针类型:
*p

空类型:
void put(){
	语句;
}

3.4.1 常量
常量固定不变的值

整型常量:

八进制 每位取值0-7 0开头
016  0101  0127

十六进制 0-9 A-F a-f
0x16 0x2F 0XFF


整型以二进制保存在系统中。

11的二进制
0000000000001011

11取反
1111111111110100

11取反后加1
1111111111110101


3.4.2 实型常量
默认double 类型

SciNum = 134.521

指数方式
SciNum1 = 134.521e2    1.34521* 10*10 =134.521
SciNum2 = 5.458e-1

3.4.3 字符型常量

字符常量   只能是一个字符,区分大小写,

字符串常量  



===================================================

复习c语言:

#include<stdio.h>

int ar[5];
int ar[6] = {123};
ar[0]=1; ar[1] = 2; ar[3] = 3;
arr[] = {1,2,3}

int ar[3][4];
/*
ar[0][0] ar[0][1] ar[0][2] ar[0][3] 
ar[1][0] ar[0][1] ar[0][2] ar[0][3] 
ar[2][0] ar[0][1] ar[0][2] ar[0][3] 
*/

char ar[]="aaddffd";  //开发中这个用的最多
aaddffd\0

for(i=0; i<5; i++){
	printf();
}

char ar[5];
ar[0]="a";
ar[1]="a";
ar[2]="a";
ar[3]="a";
ar[4]="a";

char ar[5];
ar[5] = {'a','b','c'};

for(){
	printf();
}


//函数
void fun(){
	
}
int main(){
}


========================================================

//=指针复习:

//地址与指针

编程过程中,要告诉电脑,数据类型是什么,才能在内存中布多少个字节。

变量i  --->                字节1  1000
		字节2  1001
		字节3  1002
		字节4  1003

1个变量等于4个内存单元或者说字节。


&i     取内存中的i变量的内存地址
*p  =  &i;    地址赋给指针后,就可以访问变量的值。


//变量与指针

*p  =  &i;    地址赋给指针后,就可以访问变量的值。


//指针变量

*p   指针是用来存放变量地址的。

int *p  引用指针变量把指向的值。
p=&i

注: 当先定义了指针后,就可以不在写 *p  直接写p


输出某个数的地址写法:

int a;
int *p;
scanf("%d",&a);

*p = &a;
printf("%x\n",*p);

//指针的自增自减

int i;
int *p;

scanf("%d",&i);

*p = &i
printf("%d",*p);   //1703724
p++;      //就是说 指针 增加  4个字节。
printf("%d",*p);   //1703728



//数组与指针

计算机会用一段连续的内存来存储“数组”
把数组的地址,赋给变量的话,就可以通过指针变量来引用数组;


//一维数组与指针

数组名,是内存中数组地址的首地址。

int a[10]
for(){
	print("%d",*(p+i))
}


for(){
	print("%d",*p++)
}

p=a

两者是一样的。获取的变量值是相同的。
但是,*p++  要注意移动指针到首地址。p=a 方便再去写其它的需求。

//二维数组与指针

*(a[i]+j);
*(p+i)+j;
两者相同。


#include<stdio.h>
main()
{
	int a[3][5],i,j;
	printf("please input:\n");
	for(i=0;i<3;i++)	/*控制二维数组的行数*/
	{
		for(j=0;j<5;j++)	/*控制二维数组的列数*/
		{
			scanf("%d",a[i]+j); /*给二维数组元素赋初值*/
		}
	}
	printf("the array is:\n");
	for(i=0;i<3;i++)
	{
		for(j=0;j<5;j++)
		{
			printf("%5d",*(a[i]+j)); /*输出数组中的元素*/
		}
		printf("\n");
	}
}


//字符串与指针

===================从这里再学习



=====================================================










发表评论

邮箱地址不会被公开。