C语言中

xiaoxiao2021-02-28  17

C语言的变量属性

C语言中的变量可以有自己的属性在定义变量的时候可以加上“属性”关键字“属性”关键字指明变量的特有意义

语法: property type var_name; 示例: int main() { auto char i; register int j; static long k; extern double m;

return 0 ; }

说明 i变量的属性是auto; j变量的属性是register; k变量的属性是static; m变量的属性是extern; auto关键字

autoz(自动变量)即C语言中局部变量的默认属性auto表明将被修饰的变量存储于栈上编译器默认所有的局部变量都是auto的

示例: void f() { int i; //局部变量默认属性为auto auto int j; //显示声明auto属性 }

register关键字

register关键字指明将局部变量存储于寄存器中register只是请求寄存器变量,但不一定请求成功register变量的值必须是CPU寄存器可以接受的值不能使用&运算符获取register变量的地址 因为&运算符只能获得内存地址的值,也就是说只有内存空间才有地址,而我们所熟知的寄存器是没有地址的

示例: #include<stdio.h> register int g_v; //error int main() { register char var; printf("0XX",&var); //error return 0; }

注意 第一个错误是因为申请了一个全局变量,并且属性为register。这是不允许的,因为register只能作用于局部变量。 第二个错误是因为打印一个寄存器变量的地址。因为寄存器变量是没有地址的。 static关键字

static关键字指明变量的“静态”属性 -static修饰的局部变量存储在程序静态区static关键字同时具有“作用域限定符”的意义 -static修饰的局部变量存储在程序静态区 -static修饰的函数作用域只是声明的文件中

#include<stdio.h> int g_v; //全局变量,程序的任意地方均能访问 static int g_vs; //静态全局变量,只有当前文件中可访问 int main() { int var;//局部变量,在栈上分配空间 static int svar;//静态局部变量,在静态数据区分配空间 return 0; }

注意 静态数据区的变量生命周期是整个程序周期。 代码示例

#include<stdio.h> int f1() { int r = 0; r++; return r; } int f2() { static int r = 0; r++; return r; } int main() { auto int i = 0; static int k = 0; register int j = 0; printf("%p\n",&i); printf("%p\n",&k); // printf("%p\n",&j); 这里会有一个错误,无法打印寄存器变量的值 for(i = 0;i < 5;i++) { printf("%d\n",f1()); } for(i = 0;i < 5;i++) { printf("%d\n",f2()); } return 0; }

运行结果

代码分析 在第22行,我们去打印寄存器地址的值,这在C语言中是不允许的,所以会有一个错误。

结果分析 我们可以看到变量i和k的地址差距很大,这是因为他们存储在不同的区域。由于在f1()这个函数中的r这个变量在栈上,每次都会被销毁,再次调用时会被重新赋值为0。所以每循环运行一次时,值为1。而在f2()这个函数中的r这个变量时存储在静态存储区的,所以他的生命周期是整个程序周期,所以每循环一次变量的值会累加起来。

将变量k的属性变更为auto后的结果 我们可以看到变量i和k的地址刚好相差四个字节,说明他们都位于同一个存储区域。

extern关键字

extern用于声明外部定义的变量和函数 -extern变量在文件的其他地方分配空间 -extern函数在文件的其他地方定义

extern用于“告诉”编译器用C方式编译 -C++编译器和一些变种C编译器默认会按“自己”的方式编译函数的变量,通过extern关键字可以命令编译器“以标准C方式进行编译”。

extern "C" { int f(int a, int b) { return a + b; } } 编译器会将上述代码按照C语言的方式编译代码。一般用于C和C++混合编程。

代码示例

/*test.c代码*/ #include<stdio.h> int main() { printf("0XX",var); return 0; } int var;

编译结果 我们可以看到编译器找不到printf打印时var这个变量,仅管我们在最后一行定义了var这个变量。

/*test.c修改后的代码*/ #include<stdio.h> extern int var; int main() { printf("0XX",var); return 0; } int var;

编译结果

结果并没有报错。当编译器编译到extern int var;时相当于告诉编译器你先编译吧。这个变量在其他地方定义的。

注释掉int var;编译结果 编译返回的结果是变量var没有定义。

添加一个文件test1.c

/*test.c的代码*/ #include<stdio.h> extern int var; int main() { printf("0XX",var); return 0; } /*test1.c的代码*/ int var;

编译结果 我们看到在另一个文件中定义变量var时,依然可以通过编译。

test1.c中添加static关键字

/*test1.c的代码*/ static int var;

编译结果 结果分析 因为添加了static关键字后,变量var的作用域变为test1.c这个文件。其他文件无法使用。故会出现错误。

test1.c中添加extern关键字修饰的函数

/*test1.c的代码*/ static int var; int GET() { return var; }
/*test.c的代码*/ #include<stdio.h> extern int GET(); int main() { printf("0XX",GET()); return 0; }

编译和运行结果 我们可以看到程序编译和运行都通过了。

转载请注明原文地址: https://www.6miu.com/read-2649964.html

最新回复(0)