①字符型:
char 字节数:1
②整型:
1)短整型 short 字节数2 bit
2)整型 int 字节数4 bit
3)长整型 long 字节数8 bit
4)双长整型 long long 字节数8 bit
③浮点型:
1)单精度浮点型 float 字节数 4 bit
2)双精度浮点型 double 字节数 8 bit
void类型,没有返回值
第八段详解
第十一段详解
①全局变量
1)定义在函数体之外的变量是全局变量。
2)作用域为从变量定义语句开始知道所在程序结束。
3)使用extern关键字可以声明全局变量,变量的作用域也更改为从声明位置开始到程序结束
②局部变量
1)局部变量是定义在函数体内的变量,也可以说是定义在一对大括号内的变量
2)作用域是定义局部变量位置的一对大括号之内
3)当局部变量和全局变量同名时,局部变量的优先级高
③静态变量和自动变量
1)自动变量
auto,C语言默认定义的变量是自动变量,初值是随机数,而且在函数结束后,空间就收回,下次在使用时,重新开辟空间。
2)静态变量
是指被static关键字修饰的变量,静态变量存放的位置是在静态常量区中,初值为0,静态变量的空间只有在整个程序运行结束时才会收回空间,所以可以起到保存程序开始到结束的结果。
值传递,只是把变量值传过去,属于单向传递,在函数中接受后并改变值,并不会改变原来的变量值
①初始化:是指在定义变量的同时给定一个值,也就是分配空间并直接把值放入内存。
②赋值:赋值操作是指对一个已经开辟空间的变量的值更改。
①常量是指不可改变的量成为常量
②常量的三种方式:
1)define 宏定义,在程序编译时期完成,不是C语句,不需要加;结尾,但要加#开头。
2)const C语言关键字,在变量之前加const可以定义常量。
3)enum 枚举类型 设定特殊串与值对应,不能更改。
①if可以单独使用,if(判断条件){满足条件执行语句}
②else必须和if配合使用,成对出现。不满足if就执行else
③连续判断:if(){} else if(){} … else{}
④if else语句可以嵌套使用 if(){ if(){} else{} } else{}.
①英译为开关,意如其名,switch就是多个开关。
②case ‘单个字符’:代表开关,满足就开,不满足就下一个。
③每个开关的末尾应有break语句,作用是吧开关堵住,若没有break,默认向下顺序执行。
④default 缺省,是指不满足所有开关时,执行default中语句
①三条语句:初始条件;while(结束条件){使循环趋向于结束条件;}
②特点:先判断,后执行,执行次数不定,但是有明确的结束条件
①三条语句:初始条件;do{是循环趋向于结束条件;}while(结束条件)
②特点:先执行,后判断,循环体至少执行一次,执行次数不定,有明确结束条件。
①三条语句:for(初始条件;结束条件;使循环趋向于结束条件){}
②特点:先判断后执行,类似于while()循环,但一般有具体的执行次数
①continue:用于跳出本层循环的本次循环,循环继续。
②break:终止循环,本层循环直接结束。
①[],数组名加[]数组成员引用
②(),函数调用操作符
③. 结构体变量或指针调用成员符
④-> 结构体指针调用成员符,结构体变量不能使用。
①! 非,非真味假,非假为真
②- 负号 +正号
③& 取地址
④* 指针取值运算符
⑤~ 按位取反
⑥++ 自增运算 --自减运算,a–相当于a=a-1;前置相当于先运算后使用后置为先使用当前值,在执行自增或自减。
⑦(类型标识符):强制转换类型
⑧sizeof() 不是函数,是运算符,求内存空间
①分类:±/%五种运算,其中%运算只能是整数之间的运算
②优先级:
1)/%一个优先级
2)±优先级低于1)
①<<左移:向左移动一位,末位补0
②>>右移:向右移动一位,首位补0(除去符号位第一位)
①>,<,>=,<=
==,双等号代表逻辑相等,相等为1不等为0
!=,逻辑不等,相等为0不等为1
①& 按位与:同为1才为1
②| 按位或:一个为1就为1
③^ 按位异或:相等为0不相等为1
④优先级&>|>^
&&,同为真则为真,前假后不做
||,一个为真即为真,前真后不做
表达式1?表达式2:表达式3;1为真执行2为假执行3
①= 单个等号代表赋值运算,把右边的值赋给左边,左边不能是常量
②复合赋值运算:+=,-=,/=,*=,%=,>>=,<<=,&=,|=;a+=b含义是a=a+b
顺序求值运算符,返回最后一个值
①char和int转为int
②int、long、long long、float转换为double
③char最低double最高
①数组无法整体赋值
②组成:类型符 数组名[常量] 数组名是数组的首地址,常量是数组包含多少个类型元素。
③定义数组时,一般要给定长度,不给定长度就必须初始化,初始化方式为一对大括号中一串数据并用逗号隔开
④数组下标从零开始。
①字符数组:由字符类型构成的数组。
②字符串:C语言中没有字符串类型,所以用字符数组表示,与字符数组的区别在于,字符串的末尾有一位’\0’表示字符串的结束标志
①二维数组,在逻辑上表示m行n列的一个矩阵。相当于m个n个元素的一维数组
②多维数组,相当于多个一维数组组成的二维数组组成…等等
在逻辑上维度可以体现出来,但在物理内存上,都是一段连续的内存空间,只不过是二维数组比一维数组多了一个行指针,一次移动可以移动n个类型位置
前面提到普通变量传递是值传递方式,数组名传递则是地址传递,是双向的,也就是说在函数中改变参数数组的值,原数组也会被改变
①数学函数 math.h头文件中
1)sqrt(a)取a的平方根
2)pow(a,b)求a的b次方
3)abs(a)求a的绝对值
②字符串和字符函数:第七条
③内存操作函数:
1)memcpy 内存拷贝函数,将一段内存内容直接复制到另一段中
2)memovefu 拷贝固定字节函数,将一段内存空间中的固定字节复制到另一段空间中
3)memset 内存赋值函数,对一段区域空间统一赋值
4)memcmp 比较两段内存空间中字节的大小,相等返回0,1>2返回1否则返回0
①用户自己定义函数,函数名不可与关键字重复
②用户自己定义形参
③函数的返回值类型与函数的类型一致
④函数可以嵌套调用但不能嵌套定义
⑤当自定义函数定义在主函数之后时,必须在主函数中声明才可以使用
⑥使用自定义函数的意义是为了实现程序的模块化,每个自定义函数都完成一个小功能,代码整洁,可读性高。
①主函数,main函数,一个程序中只有唯一一个,是每个可执行程序必须包含的函数
②程序的执行从主函数开始。
③主函数参数列表中默认有两个参数,一般隐藏,argc 是一个整形数,代表参数的个数,argv是一个字符指针数组,每一行保存的是一个参数的内容
递归调用就是函数调用自己本身,递归的过程就是递进递出的过程
strlen();返回字符串从起始位置知道结束符位置的长度,不包括结束标志。
①strcpy(str1,str2)将2中的内容全部复制到1中,1中原有元素被覆盖
②strncpy(str1,str2,size)将2中的前size个字节的内容复制到1中。
①strcat(str1,str2)将2连接到1之后,2的第一个元素覆盖1的结束标志
②strncat(str1,str2,size)将2中size个字节的元素放在1之后
①strcmp(str1,str2)自左至右挨个元素比较,直到其中一个结束,先结束的那个串小,1>2返回1相等返回0否则返回-1
②strncmp(str1,str2,size)比较两个字符串的前size个字节元素
①字符查找
1)strchr(str,c)在字符串str中自左向右查找字符c,找到返回c的地址,否则返回null
2)strrchr(str,c)自右向左查找字符c
②字符串查找:
strstr(str1,str2)在字符串str1中查找str2,找到返回查找到的子串首地址,否则返回null
①指针代表地址,指针内存空间中保存的是指针所指向的地址。
②指针类型所占用的空间和指向的内容无关,而是与系统位数有关,在32位系统中,占4个字节,64位系统中占用8个字节
类型的作用在于使用指针时,机器选择选取多少bit的内容。
使指针移动多少个指针类型的字节。
指向指针的指针,内部保存的是指向指针的地址,相当于二维数组
使用指针名,取出的是指向空间的地址,使用*指针名,取出的指向空间的值
取出的是两个指针中间的元素的个数,两个指针必须指向同一段内存空间
是指向数组的指针,例如int(*) nums[10] 相当于一个10列的二维数组
是存放指针的数组,例如int* p[10] 代表一个存放10个指针的一维数组
返回类型为指针的函数,int* f(int a,int b),f是一个返回值为整型指针的函数
指向函数的指针,指针就是函数,int (*f)(int x,int y)
对于没有指向地址的指针,成为野指针,由于指针的内存空间中是null所以无法存值
1)定义指针是直接赋值:int* p =1;
2)使用时直接使用指针名,不能用操作
3)不能使用指针名来进行修改值
预处理操作是在程勋编译时期完成的操作,所以合理的使用预处理可以缩短程序的运行时间
①定义标识符: #define name stuff
②#difine定义宏: 注意求值顺序
③使用宏:
直接替换,直接将宏定义语句直接替换到调用位置。(x)(x)和xx不一样
④嵌套:
宏定义可以使用宏定义变量,但不能实现递归
作用是移除一个宏定义
①#的作用:
1)把其他类型的数据直接转换为字符串
2)引入库函数头文件
②##的作用:
把位于##两端的符号连接为一个符号
①#IF 常量表达式 #endif
②#IF 常量表达式 #elif 常量表达式 #else… #endif
①宏的优点:
由于宏是在程序编译时期进行的工作,所以在简单的操作上,使用宏定义可以缩短程序的执行时间
②宏的缺点:
1)宏定义无法调试,错了就要重新改写然后编译运行,时间太长
2)宏定义都是字符串,与类型无关,难以控制
①小端存储:
低字节序存在低地址,高字节序存在高地址处
②大端存储:
低字节序存在高地址处,高字节序存在低地址处
①栈区:
栈区由编译器自动分配回收,存放函数的参数值和局部变量等
②堆区:
堆区由程序员动态分配,和回收。
③全局区(静态区):
存放静态变量,全局变量,并细分一个常量区,保存常量,字符串常量,其它常量,全局区在程序结束时由操作系统释放。
④代码区:
用于存放函数体的二进制码。
①静态分配方式:
静态分配,是指在程序编译时期就进入静态区,这块内存在程序的整个运行期间都存在。
②自动分配方式:
自动分配,也就是默认分配方式,由编译器在栈上开辟一块空间,存放数据,在函数循行结束时,就被释放。
③动态分配方式:
动态分配,在堆上开辟内存,由程序员使用malloc等方式开辟,当使用完时,需要程序员使用free手动释放空间。
①结构体的定义:
1)struct 结构体名称{ 成员类型 成员名;…};
2)结构体可以在大括号后直接定义结构体变量,也可以在程序中定义结构体变量
3)结构构体变量使用struct 结构体名 变量名的方式定义。
4)结构体一般定义为全局
②结构体的内存空间:
1)结构体的空间为结构体所有成员占用空间之和。
③结构体传参:
1)结构体传参时要使用地址传递方式
④结构体的赋值
1)结构体成员不能赋初值
2)同一个结构体的结构体变量可以整体赋值
3)结构体变量可以初始化赋值
①联合体定义:
1)联合体也叫共同体,共用体
2)定义方式:union 共用体名 {成员类型 成员名;…};
3)联合体和结构体类似,联合体变量的定义方式和结构体相同
4)联合体只能保存最后一次赋值的元素是有效值。
②联合体的空间:
1)和结构体不同,联合体的所有成员共用一块存储空间。
2)联合体空间最小是成员中最大的占用空间
3)占用空间可以整除所有成员的类型占用的字节数。
③联合体赋值:
1)联合体不能赋初值
2)同一个联合体变量可以整体赋值
3)联合体变量初始化赋值无效,公用空间,有效值只有最后一次赋值
①枚举定义:
1)enum 枚举定义的量是常量,不能修改。
2)默认值从0开始间隔是1
3)可以对枚举常量赋初值,就像map中的键值对,输入键获得值
②枚举的特点:
1)使用枚举可以增加代码的可维护性
2)比#difine更加严谨,多了类型检查
3)使用枚举加强命名规范,便与调试
4)使用方便,一次定义多个常量
③例:彩虹颜色
1)定义:enum Color{red,orange,yellow,green,indigo,blue,purple}
2)使用:enum Color col = yellow;
3)输出结果 :2
①使用方式
1)指针类型 指针名= (指针类型)malloc(sizeof(成员类型)长度);
2)int p = (int*)malloc(sizeof(int)*100);
②在堆中开辟一段空间,系统不会释放
①使用方式:
1)free(指针名)
2)free§;
②使用动态开辟的空间系统不会释放,使用free释放空间
①使用方式:
1)指针类型 指针名=(指针类型)calloc(元素个数,sizeof(元素类型));
2)int* p = (int*)calloc(100,sizeof(int));
②calloc函数与malloc差不多,但calloc开辟空间会直接初始化值为0,所以时间开销要大于malloc
①使用方式:
1)指针名=(指针类型)realloc(指针名,sizeof(成员类型)新长度)
2)p = (int)realloc(p,sizeof(int)*102);
②使用realloc可以重新定义空间大小
1)只能增加不能减少
2)若原空间后空间足够,则在原空间后直接开辟多的空间
3)若空间不足,则整体挪移寻找足够空间的内存块开辟空间
4)使用realloc改变空间不会破坏原空间中的数据
①输入流:stdin
②输出流:stdout
③错误:stderr
是一个数据结构,用来访问流
①使用方式:
1)FILE* fopen (char* name,char* mode)
2)name 指文件的路径名
3)mode 指文件的打开方式
②文件打开方式
1)w 只写
2)a 追加
3)r 只读
4)w+ 读写(创建新文件)
5)a+ 追加读写
6)r+ 读写(对已有文件读写)
7)wb 二进制文件只写
8)rb 二进制文件只读
9)ab 二进制文件追加
1)fclose(FILE* F)
2)成功关闭返回0否则返回EOF(文件结束标记,-1)
① 文本流
1)用于所有的流
a.输出流:
a)单个字符 fgetc(FILE* f) 成功返回取得字符失败返回-1
b)字符串 fgets(char* buffer,int bu_size,FILE* f)成功返回地址否则返回NULL
c)格式化读入 fscanf(FILE* f,char* buffer,[输入列表]) 返回取出的元素个数
b.输入流:
a)单个字符 fputc(char c,FILE* f) 成功返回字符否则返回非0值
b)字符串 fputs(char* s,FILE* f)成功返回0否则返回非0值
c)格式化写入fprintf(FILE* f,char* buffer,[参数列表])返回写入元素的个数
2)只能用于stdin和stdout
a.getchar() 输入单个字符
b.putchar() 输出单个字符
c.gets() 输入字符串
d.puts() 输出字符串
e.scanf() 格式化输入
f.printf() 格式化输出
② 二进制流
1)读 fread()
a.int fread(char* buffer,int size,int n,FILE* f)
b.buffer保存取出的数据区,n个字节数为size的元素
c.返回读到的元素个数出错返回0
2)写 fwrite()
a.int fwrite(char* buffer,int size,int n,FILE* f)
b.buffer 保存要存入的数据,n个字节数为size的元素
c.返回写入文件中元素的个数
③ 其它文件操作函数
a.移动文件指针
a)rewind(FILE* f) 将指针移动到问价开头
b)fseek(FILE*f,位移量,移动起点)
i.位移量:
i)绝对值代表移动字节数
ii)正数向左
iii)负数向右
ii.移动起点:
i)文件开头:SEEK_SET或0
ii)当前位置:SEEK_CUR或1
iii)文件末尾:SEEK_END或2