c语言auto、static、extern、register、volatile存储的理解

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 square(volatile int *ptr) 
{
    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;
}








  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值