关键字register
register—寄存器关键字
register int a = 10; // a是寄存器变量
1
register 是起到的是建议作用,“建议” 编译器将a放到寄存器中,不会真的放进去,它有自己的一套判断规则。
注意:不能对寄存器变量取地址
static关键词
static 修饰局部变量
C语言中,static是用来修饰变量和函数的
修饰局部变量---静态局部变量
修饰全局变量---静态全局变量
修饰函数---静态函数
#include<stdio.h> void test() { int a = 1;//局部变量a的作用域在test()中,当a出了作用域就被销毁了,下次调用test()时,又需要重新创建a a++; printf("%d ", a); } int main() { int i = 0; for (i = 0; i < 10; i++) { test(); } return 0; }
猜一猜上面的结果是什么?
为什么会全部是2,想必我们在写这个函数的时候,我们需要打印出来的是2-10的数字吧!那么如何达到这个要求呢?我们就需要用到我们额static静态关键词了
只需要在函数内部加一个静态变量就可以
根据上述的结果推测出每一次调用test(),使用的a都是上一次函数调用时留下的a;第二次调用test()时,由于上次函数调用产生的a没有被销毁,所以不会再次创建a,直接跳到了下一步,a++
总而言之就是,计算机记住了上次的结果
注意:static修饰局部变量的时候,其实是改变了变量的存储类型,由栈区存储变成了静态区存储,从而使得静态的局部变量出了自己的作用域也不会被销毁,其实也就是相当于改变了这个变量的生命周期。
内存是一块比较大的空间,在使用内存的时候,会划分出不同的功能区域:栈区、堆区、静态区
static 修饰全局变量
//add.c文件 int g_val = 2018;//g_val是在add.c文件中定义的 //test.c文件 //如果想使用来自其他文件(外部文件)的全局变量,要先声明一下 extern int g_val; //extern是一个关键字,专门用来声明外部符号的 int main() { printf("%d\n", g_val); return 0; } //add.c文件 static int g_val = 2018; //test.c文件 extern int g_val; int main() { printf("%d\n", g_val); return 0; }
上面的两个代码只有一点点的不一样,但是最终的结果确实千差万别,最有一个代码会报错!
一个全局变量在整个工程中的其他子文件内部能被使用,是因为全局变量具有外部链接属性 ,什么叫外部链接属性,一个变量在一个文件中定义,但是在另一个文件中可以使用(访问)叫外部链接属性。
当一个全局变量被static修饰的时候,其外部链接属性就变成了内部连接属性;使得这个全局变量只能在只能在自己的源文件内部使用,其他文件不能再使用,因为它不再具有外部链接属性,从本质上来说就是:作用域变小了!
那么当然,局部变量只有内部连接属性
其次函数也具有外部链接属性,static修饰函数的时候,函数本来是具有外部链接属性的,但是被static修饰后,就变成了内部连接属性,导致这个函数只能在自己的源文件内部使用,给我们的感觉是改变了作用域。
定义常变量和宏
//define定义标识符常量 #define MAX 100 //define定义宏(宏和函数是非常相似的) #define Add(x, y) ((x) + (y))
对于常变量我们知道,也就是不可修改的变量
相对于陌生的是,定义宏
#include #define M(a,b,c) a##b##c int main(void){ printf("the M(2,3,4) is %d\n",M(2,3,4)); return 0; }
运行结果是:the M(2,3,4) is 234
具体的,我们会在后面的文章进行详细的讲述的,这里只是简单的介绍一下关于宏的概念
比如我们需要在上面定义一个简单的公式宏,每一次调用的时候,就不用写复杂的公式了
#define MAX( x, y ) ( ((x) > (y)) ? (x) : (y) )
#define MIN( x, y ) ( ((x) < (y)) ? (x) : (y) )
传送门可以查看相关宏的知识
注意:本专栏将会从基础到入门再到精通,最后达到手写C语言的效果,要想手写C语言练得如火纯情,只有反复的练习才可以,这也是为什么前期的文章讲的很广泛,就是让我们的大脑对C语言的整体有一个大概的认识,这样在进入后续的深入学习才不会感觉知识晦涩难懂,脱节比较严重的情况!