1:auto(自动的)
auto是针对局部变量和形参而言的,在C/C++中局部变量的声明或是形参的使用我们都没有加auto,编译器会默认你程序中的局部变量或是形参是auto类型存储的。这种类型的存储方式是动态存储的,例如当我们声明一个局部变量时,编译器会自动动态的为该局部变量创建存储空间。当这个局部变量被掉用完之后,之前存储它存储空间即地址会被释放,如果下次再调用的时候重新给它动态分配存储空间。即这种存储方式的变量拥有的存储空间权利是暂时性的。因此平时如果不对声明的局部变量赋初值的话,那么因为每次都会对它重新动态分配存储空间,因此它的初值是不固定的。
2:static(静态的)
和auto相对应的存储方式是static,被static修饰的变量存储空间是在静态存储区,整个程序运行期间都是不会释放的。需要注意的是它的使用范围和初值赋值问题。对于静态局部变量,它只能被定义自己的函数所引用,而不能被其他函数所引用,并且如果不赋初值将默认为0,并且以后的值是上次调用后的值,即使函数调用结束该变量也不会释放。对于全局变量来说,它的使用范围是该源文件内,不定义初值默认为零,改制不会随着被函数调用而改变。当static修饰函数时,即说明该函数只能在该源文件内调用,而不能被其他源文件调用。
3:extern(外部的)
当一个源文件想调用另外一个源文件内的函数或是变量时,那么要求被调用的变量或是函数声明方式必须是extern类型的。需要注意的时外部变量声明时不能赋初值,正确的方法如下:
char flag=1;extern char falg;
4:register(寄存器类型的)
一个建议性关键字,意思是对变量声明之后,是否采取声明的类型,是由编译器决定的。这种类型的变量因为会被cpu反复调用,因此声明的时候建议将这种类型的变量存储在cpu的寄存器中,这样cpu在调用是速度更快。需要注意的是,只有局部自动变量和形参才可以定义为寄存器变量。因为寄存器变量属于动态存储方式,凡需要采用静态存储方式的量都不能定义为寄存器变量,包括:模块间全局变量、模块内全局变量、局部static变量。
register int i,sum=0;(这里i和sum都会被频繁用到)
for(i=0;i<10000;i++)
sum+=i;
5:volatile(不是十分的理解)
和register一样是一个建议性关键字。它的作用是编译器该变量可能会在编译器未监测的情况下改变,因此程序中用到该变量时,要到该变量的内存地址中读取该变量的值。以下几种场景进场会用到volatile
1) 并行设备的硬件寄存器(如:状态寄存器)
2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3) 多线程应用中被几个任务共享的变量
下面这个函数有什么错误
int square(volatile int *ptr)
{
return *ptr * *ptr;
}
这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}
由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}