5.C存储类

//C存储类
/*
存储类定义C程序中变量或者函数的范围(可见性)和生命周期,这些说明符放在所修饰的类型之前。
以下是C程序中可用的存储类:
auto
register
static
extern
*/

//auto存储类
/*
auto存储类是所有局部变量的默认存储类
{
	int mouth;
	auto int year;
}
上面的例子定义了两个带有相同存储类型的变量,auto只能用在函数内,即auto只能修饰局部变量
*/

//register存储类
/*
register用于定义存储在寄存器中的变量,而不是RAM中的局部变量。
首先我们知道,cpu只能操作内存中的数据,其实cpu自身还是有一小部分空间的。
当我们进行运算的时候,cpu会将内存中的数据读到cpu自身的寄存器中,然后将运算之后的结果返回。
因此寄存器只用于需要快速访问的变量
*/

//static存储类
/*
static指示编译器在程序的生命周期内保持局部变量的存在,而不需要每次在进入或离开作用域时进行创建和销毁。
因此使用static修饰的局部变量可以在函数调用之间保持局部变量的值
static也可以修饰全局变量,当static修饰局部变量时,会使变量的作用域限制在声明它的文件内
static是全局变量的默认存储类,以下两个变量都有一个static存储类
static int count;
int road;
*/
#include <stdio.h>
//函数声明
void func(void);
static int count = 10; //全局变量static是默认的

int main01()
{
	while (count--)
	{
		func();
	}
}

void func(void)
{
	static int a = 1;  //只会被初始化一次,当程序再次执行这个函数,不会再初始化a=1了
	int b = 1; //由于b前面没有加static,所以会初始化。
	//我们说默认会有static指的是全局变量
	printf("a=%d,b=%d\n",a,b);
	a++;
	b++;
	//先别急着执行,先来分析一下
	//因为a有static修饰,所以只会初始化一次,因此a++会使得a增加
	//b没有static修饰,因此每次执行函数的时候都会初始化,因此不管执行多少次,只会打印1
}
/*
a=1,b=1
a=2,b=1
a=3,b=1
a=4,b=1
a=5,b=1
a=6,b=1
a=7,b=1
a=8,b=1
a=9,b=1
a=10,b=1
*/
//这和我们的分析是一致的

//extern存储类
/*
extern存储类用于提供一个全局变脸过的引用,全局变量对所有的程序文件都是可见的。
当使用extern时,对于无法初始化变量,会把变量名指向之前一个已经定义过的存储位置
当有多个文件,且在文件中定义了一个可以在其它文件中使用的全局变量或者函数时,
可以在其他文件中使用extern得到已经定义的变量或者函数的引用。
可以这么理解,extern是用来在另一个文件中声明一个全局变量或者函数。
extern通常用于当有两个或者多个文件共享相同的全局变量或者函数的时候。
举个栗子:
第一个文件main.c
#include <stdio.h>
int count;
extern void write();
int main()
{
	count = 5;
	write()
}

第二个文件 support.c
#include <stdio.h>
extern int count
void write(void)
{
	printf("count is %d\n", count);
}
当我们编译main.c support.c然后执行可执行程序之后,会打印出count is 5
分析:首先在main.c中定义了count=5,然后执行write函数
	  但是main.c中没有定义write函数,但是引用了support.c中的write函数
	  所以执行support.c中的write函数,但是support.c中没有定义count
	  但是在main.c中定义了count,而support.c中通过extern int count可以引用support.c中的count
	  所以打印count is 5.
	  举个不恰当的栗子,就是两个程序中各自缺少一部分
	  main.c中有count(原料),但是没有函数write(加工的机器)
	  support.c中有write(加工的机器),但没有count(count),因此两者配合使用
	  main.c中使用了support.c的机器,发现这个机器需要一个原料(count),于是正好把自己的count给它
	  从而最终打印count is 5
注意:我们上面说对于全局变量,加不加static是一样,但在这里就不可以加static了,因为加了就变成了是本源文件可见,其他的文件就无法引用这个全局变量了
*/


//笔记
/*
auto 普通局部栈变量,自动存储,这种对象会自动创建和销毁,建议这个变量要放在堆栈上面。
调用时分配内存,函数结束时释放内存。一般隐藏auto默认为自动存储类别,程序的大多变量都是自动变量
栗子:
#include <stdio.h>
int main()
{
	auto i = 9; //声明局部变量额关键字是auto,因为可以省略,几乎没人用
	printf("%d\n", i);
}

register变量:动态变量和静态变量都是放在内存中,程序中遇到该值时用控制器发指令将变量的值送到运算器中,
需要存数再保存到内存中。如果频繁使用一个变量,比如函数体内部的多次循环每次都引用该变量,我们可以把该局部变量
的值放到CPU的寄存器当中,叫寄存器变量。不需要多次到内存中存取以提高效率,但是只能局部自动变量和形参可以作为寄存器变量。
在函数调用时,占用一些寄存器,函数结束时释放。不同系统对register要求也不一样
比如对register变量的个数和类型限制,有的默认为自动变量处理,有的一般也不用。
*/
#include <stdio.h>
#include <time.h>
#define TIME 1000000000
int m,n = TIME; //全局变量
int main()
{
	time_t start, stop;
	register int a,b = TIME; //寄存器变量 
	int x,y = TIME; //一般变量
	time(&start);
	for (a=0;a<b;a++);
	time(&stop);
	printf("cost time is %d\n", stop - start);  //cost time is 0
	
	time(&start);
	for (x=0;x<y;x++);
	time(&stop);
	printf("cost time is %d\n",stop - start); // cost time is 3
	
	time(&start);
	for (m=0;m<n;m++);
	time(&stop);
	printf("cost time is %d\n",stop - start); //cost time is 2
}
//可见寄存器变量是最快的,几乎感受不到执行时间,就执行结束了。
//都说cpu操作内存很快,但是相比cpu在自身的寄存器上操作,还是慢了不少。
//毕竟cpu是处理自己家的数据,省去了用控制器将数值从内存运到寄存器这一过程
//所以并不是cpu直接在内存中操作数据,而是将内存中的数据搬到自己的寄存器这里来执行,执行完了将结果再运回到内存中
//所以说cpu只能处理内存的数据,意思是指只有内存中的数据才可以被运到cpu中的寄存器中去执行

  

猜你喜欢

转载自www.cnblogs.com/traditional/p/9463613.html
今日推荐