我们知道以在 C 语言中的变量有自己的属性,只要在定义变量的时候加上“属性”关键字即可。“属性”关键字指明变量的特有意义。
成都创新互联公司专注为客户提供全方位的互联网综合服务,包含不限于网站制作、成都网站建设、白银区网络推广、微信小程序开发、白银区网络营销、白银区企业策划、白银区品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;成都创新互联公司为所有大学生创业者提供白银区建站搭建服务,24小时服务热线:028-86922220,官方网址:www.cdcxhl.com
语法:property type var_name;比如:auto int i; register int j;extern float k;static double m;
auto关键字:它是 C 语言中局部变量的默认属性;表明将被修饰的变量存储于栈上;编译器默认所有的局部变量都是 auto的。
register关键字:指明将局部变量存储于寄存器中;只是请求寄存器变量,但不一定请求成功;register变量的必须是 CPU 寄存器可以接受的值;不能用 & 运算符获取 register变量的地址。
static关键字:指明变量的“静态”属性,static修饰的局部变量存储在程序静态区;它同时具有“作用域限定符”的意义,static修饰的全局变量作用域只是声明的文件中,修饰的函数作用域只是在声明的文件中。
下来我们做个实验分析下,代码如下:
#includeint f1() { int r = 0; r++; return r; } int f2() { static int r = 0; r++; return r; } int main() { auto int i = 0; // 显示声明 auto 属性,i 为栈变量 static int k = 0; // 局部变量 k 的存储区位于静态区,作用域位于 main 中 register int j = 0; // 向编译器申请将 j 存储于寄存器中 printf("%p\n", &i); printf("%p\n", &k); printf("%p\n", &j); // error for(i=0; i<5; i++) { printf("%d\n", f1()); } printf("\n"); for(i=0; i<5; i++) { printf("%d\n", f2()); } return 0; }
我们可以看出第 30 行代码会出错,因为不能用 & 运算符获取 register变量的地址。编译如下:
我们注释掉那行代码之后,再次编译,得到结果如下:
我们发现虽然 i 和 k 是挨着定义的,但是因为属性不同,所以他俩的地址也差的好大。再接着看 f1() 和 f2() 基本上都差不多,但是打印结果却差别很大呢?仔细看看在 f2() 中,我们加了 static关键字。也就是说 f1() 中的 r 是局部变量,在每次执行循环的时候都要进行初始化为0,所以打印五次结果都为 0;但 f2() 不同,r 前面加有 static,所以其相当于全局变量,在循环时只进行一次的初始化,后面的循环便依次加一了。
接下来我们来介绍 extern关键字:它是用于声明“外部”定义的变量和函数,extern 变量在文件的其他地方分配空间,extern 函数在其他地方定义;它用于“告诉”编译器用 C 的方式进行编译,C++ 编译器和一些变种 C 编译器默认会按“自己”的方式编译函数和变量,通过 extern C关键字可以命令编译器“以标准 C 方式进行编译”。
下来我们就来验证下,代码如下:
#includeextern int getI(); int main() { printf("%d\n", getI()); return 0; }
g.c 代码如下:
static int g_i; int getI() { return g_i; }
我们编译得到结果如下:
虽然我们没在 test.c 文件中定义 getI(),但是我们在 main() 之前进行 extern声明,编译器在编译到这时会先向下编译然后再 g.c 文件中进行寻找。最后成功执行 getI(),getI() 返回的是一个 static修饰的全局变量,默认为 0。所以最后结果为 0。
那么我们本次学习了变量的属性,auto 变量存储在程序的栈中,默认属性;static变量存储在程序静态区中;register变量请求存储于 CPU 寄存器中;extern变量在文件的其他地方分配空间,extern能够指示其他编译器按照标准 C 方式编译程序。
欢迎大家一起来学习 C 语言,可以加我QQ:243343083。