关键字(●’◡’●)
所谓的关键字,就是平时代码里的指令性字符,比如咱的return 0里面 return为啥能直接用呢?它就是关键字。C语言中的关键字全部来源于C语言,不能自己创建关键字,并且关键字是不可以作变量名。
我们常见的关键字有数据类型关键字👏:
1、void:声明函数无返回值或无参数,声明无类型指针,显式丢弃运算结果
2、char:字符型类型数据,属于整型数据的一种
3、int:整型数据,通常为编译器指定的机器字长
4、float:单精度浮点型数据,属于浮点数据的一种
5、double:双精度浮点型数据,属于浮点数据的一种
类型修饰关键字👏
6、short:修饰int,短整型数据,可省略被修饰的int。
7、long:修饰int,长整形数据,可省略被修饰的int。
8、signed:修饰整型数据,有符号数据类型
9、unsigned:修饰整型数据,无符号数据类型
复杂类型关键字👏
10、struct:结构体声明
11、union:共用体声明
12、enum:枚举声明
13、typedef:声明类型别名
14、sizeof:得到特定类型或特定类型变量的大小
存储级别关键字👏
15、auto:指定为自动变量,由编译器自动分配及释放。
16、static:指定为静态变量,分配在静态变量区,修饰函数时,指定函数作用域为文件内部
17、register:指定为寄存器变量,建议编译器将变量存储到寄存器中使用,也可以修饰函数形参,建议编译器通过寄存器而不是堆栈传递参数
18、extern:指定对应变量为外部变量,即在另外的目标文件中定义。
19、const:与volatile合称“cv特性”,指定变量不可被当前线程/进程改变(但有可能被系统或其他线程/进程改变)
20、volatile:与const合称“cv特性”,指定变量的值有可能会被系统或其他进程/线程改变,强制编译器每次从内存中取得该变量的值(如果你了解并能使用它,说明你的C语言已经有一定段位了)
跳转结构👏
21、return:用在函数体中,返回特定值(或者是void值,即不返回值)
22、continue:结束当前循环,开始下一轮循环,执行到此只结束本轮循环,继续新一轮循环
23、break:跳出当前循环或switch结构,执行到此跳出所有的循环,即结束for语句等
24、goto:无条件跳转语句
分支结构👏
25、if:条件语句
26、else:条件语句否定分支(与if连用)
27、switch:开关语句(多重分支语句)
28、case:开关语句中的分支标记
29、default:开关语句中的“其他”分支,默认子句。
循环结构👏
30、for:for循环结构,for(1;2;3)4;的执行顺序为1->2->4->3->2…循环,其中2为循环条件
31、do:do循环结构,do 1 while(2);的执行顺序是1->2->1…循环,2为循环条件
32、while:while循环结构,while(1) 2;的执行顺序是1->2->1…循环,1为循环条件
有些有意思的比如auto,自动的,用于什么场景呢?C语言中,每个局部变量都是auto修饰的,对于这个变量来说,是自动创建自动销毁的,也就是自动变量;auto在新C语言中也有新的用法,但我还没去学习,暂时就不提了(😅)。
register👏
寄存器关键字 register,比如register int num=10 ,修饰后是建议num的值存储到寄存器。为什么要建议放在寄存器呢?在计算机中的数据又可以放到哪里呢?一是网盘,二十硬盘,三是内存,四是高速缓存,还有就是寄存器。众所周知百度网盘动不动就是几个T的,硬盘呢500G,内存也8~16G,高速缓存就几十MB,再往下的寄存器就更小了。但是网盘的传输依赖于网络,传输速度自然没硬盘快,硬盘拷贝起来几十兆/秒,而内存更快,所以造价更高技术含量更高,所以寄存器就是最快的。所以就大概形成了一种金字塔结。
在CPU拿取数据时会去内存拿,但现在CPU越来越快,内存速度没跟上的同时CPU会闲置,就像我抄作业,你写作业,我抄完了你还在疯狂赶路,我就只能坐下来摸鱼了。这时寄存器就开始占据突出位置了,不到万不得已是不去内存薅数据的。其实现在计算机很聪明了,即使不用register也可以自行判断某些数据。
static👏
意为静态的,其用法可分为3种:修饰全局变量,修饰局部变量和修饰函数。比如修饰局部变量时,创建一个代码如下:
void test() { static int d = 1; d++; printf("%d\n", d); } int main() { int a = 0; while (a < 5); { test(); a++; } return 0; }
再加上static条件加以限制:
void test() { static int d = 1; d++; printf("%d\n", d); } int main() { int a = 0; while (a < 5); { test(); a++; } return 0; }
test函数结果执行五次,每个循环d=2,打印出5个2。当我们在局部变量前添加static后,会发现结果变成了递增等差数列。总结一下就是:static修饰局部变量改变了局部变量的生命周期,本质上是改变了他的存储类型,而迫使改变了生命周期。
因此咱的内存可划分为三个区域:栈区,堆区,静态区。
栈区用于放函数参数和局部变量,堆区参与动态内存分配,而静态区存放全局变量,static修饰的静态变量。也就是说在static修饰下,局部变量会从栈区变到静态区。
当static修饰全局变量时,使得全局变量只能在自己源文件内使用,其他源文件无法使用。有个误区是认为static让全局变量作用域改变,其实不是,全局变量之所以能在其他源文件内使用是因为他具有外部链接属性,修饰后为内部链接属性,其他源文件无法链接到这个静态的全局变量。
static修饰函数时其原理同全局变量一样,都是改变链接属性。