C语言进阶:5、变量属性

C语言中的变量可以有自己的属性,只需在定义变量的时候加上“属性”关键字即可。

“属性”关键字指明变量的特有属性。

1、auto关键字:

auto是C语言中局部变量的默认属性,表明被修饰的变量存储在栈上。

编译器默认所有的局部变量都是auto属性。

2、register关键字:

表明局部变量存储在寄存器中,要注意的是,这只是请求寄存器变量,但是不一定成功。register变量必须是CPU寄存器可以接受的值。

不能用“&”运算符获取register变量的地址。

观察下面代码

#include <stdio.h>

register int g_v;  //error

int main()
{
	register char var;
	
	printf("%ox08X", &var);  //error

	return 0;
}

linux下使用Gcc进行编译:

delphi@delphi-vm:~/will$ gcc test.c
test.c: In function ‘main’:
test.c:10: error: address of register variable ‘var’ requested

3、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;
}

示例代码:观察下面代码,判断输出,并体会auto、register、static关键字的作用

#include <stdio.h>

int f1()
{
	int i=0;
	
	i++;
	
	return i;
}

int f2()
{
	static i=0;
	
	i++;
	
	return i;
}

int main()
{
	auto int i=0;  //栈上
	register int j=0;  //向编译器申请将j存储在寄存器中
	static int k=0;  //静态数据区,作用域在mian中
	
	printf("%p\n", &i);
	//printf("%p\n", &j);   //error
	printf("%p\n", &k);
	
	for(i=0; i<5; i++)  //C99不允许声明的时候定义在循环中
	{
		printf("%d\n", f1());
	}
	
	for(i=0; i<5; i++)
	{
		printf("%d\n", f2());
	}

	return 0;
}

在Linux下使用gcc进行编译并运行,结果如下:

delphi@delphi-vm:~/will$ gcc test.c
delphi@delphi-vm:~/will$ ./a.out
0xbfc222ec
0x804a01c
1
1
1
1
1
1
2
3
4
5

4、extern关键字

extern用于声明“外部”定义的变量和函数

            extern变量在文件的其他地方分配空间;

            extern函数在文件的其他地方定义。

extern用于“告诉”编译器使用C的方式编译代码:

            C++编译器和一些变种C编译器默认会按照“自己”的方式编译函数和变量。

示例:

extern "C"  //C++和C的桥梁
{
	int f(int a, int b)
	{
		return a+b;
	}
}

观察下面代码,体会extern的作用,注意static全局变量和extern的“互斥性”

#include<stdio.h>   //test.c

extern int g_i;

int mian()
{
	printf("%d\n", g_i);
	
	return 0;
}
g.c:
int g_i=10;  //gcc test.c g.c

static g_i=10; //编译错误,static作用域缩小

static和extern“互斥性”;

那么如何访问其他文件中的static全局变量呢?——定义函数

g.c:

int getI()
{
	return g_i;
}

在main()中
extern int getI();

小结:

auto变量存储在程序的栈上,并且是默认属性;

static局部变量存储在程序的静态区,修饰的全局变量(函数)只能在声明的文件中访问(作用域限定)。

register变量请求存储于CPU寄存器中,访问速度快;

extern变量在文件的其他地方分配空间;

extern能够指示编译器按照标准C方式进行编译。


猜你喜欢

转载自blog.csdn.net/qq_28388835/article/details/80156178