【C语言复习(一)】auto、static、register、const、volatile关键字的分析

首先,C语言中的变量可以有自己的属性,这些属性用于赋予变量特定的含义;本篇中分析的属性关键字有以下三个:autostaticregister

1、auto

auto是C语言中局部变量默认的属性,可不用显式指定,编译器在编译前都会默认加上;

用auto关键词修饰的变量会在上分配空间,而全局变量会在程序的全局静态存储区分配空间,所以,auto关键字不能用在全局变量前面,否则会出现矛盾!

例如,下面的程序就是错误的!

#include <stdio.h>
auto int i=0;
//出现错误,不能编译
int main()
{
    auto int j=0;
    printf("%d\n",j);
    return 0;
}

2、static

static关键字修饰的变量为静态变量,又可分为静态局部变量和静态全局变量,他们的生命周期是整个程序运行期间,在运行期间该存储区不会被释放!static声明的静态局部变量会在全局静态存储区分配空间,且生命周期内,只被初始化一次!!

static关键字修饰的变量或者函数,还存在文件作用域的属性,即只在当前文件中有效

如下程序:

#include <stdio.h>
 
void func1()
{
    int i=0;
    i++;
    printf("%d\t",i);
}
void func2()
{
    static int j=0;
    //只会初始化一次
    j++;
    printf("%d\t",j);
 
}
int main()
{
    int n=0;
    for(n=0;n<5;n++)
    {
        func1();
    }
    printf("\n");
    for(n=0;n<5;n++)
    {
        func2();
    }
    return 0;
}

运行结果:

 

3、register

用于声明寄存器变量,表示请求将变量存储在CPU寄存器中,但是不一定成功!register声明的变量,要想存储在寄存器中,必须是寄存器可接受的值,且不能够通过地址运算符(&)取得该变量的地址,因为程序运行后,它可能存储在寄存器中,而不是程序内存中!同样,register关键字不能用的全局变量前,因为全局变量是存放在程序的全局静态存储区的!

 

4、const

C语言中使用const修饰的变量为只读的,但是其本质还是变量,有类型,占用存储单元,只不过不允许通过变量名来修改其值,因此有的书上称之为常变量!本质上,const修饰符只对编译器有效,在程序运行时无效,因为我们是可以通过指针来修改此变量的值的!

如下代码:

#include <stdio.h>
int main()
{
    const int num=5;
    int* p=(int*)#
    *p=10;
    printf("%d\t",*p);
    return 0;
}

const可以修饰数组;且此数组将会是只读的,虽然在C的定义中此数组将不能被修改,但是通过指针,同样能达到修改的目的;可能在有的编译器中编译如下代码会出错,或者运行错误,这应该是编译器的原因:

#include <stdio.h>
int main()
{
    const int num[5]={1,2,3,4,5};
    int* p=(int*)num;
    int i=0;
    for(i=0;i<5;i++)
    {
        p[i]+=i;
    }
    for(i=0;i<5;i++)
    {
        printf("%d\t",p[i]);
    }
    return 0;
}

codeblocks 下使用Gcc编译,运行结果:



const修饰指针:

  • const int* p; //p可变,p所指向的内存中的int型的值不能改变!
  • int const* p;  //同上,p可变,但是p所指向的内存中的int型的值不能改变!
  • int* const p;   //p不能变,p所指向的内存中的int型的值可以变;
  • const int* const p;//p不能变,p所指向的值也不能变!

综上可以看出,const修饰符其后所直接修饰的内容是不能改变的,间接修饰的内容是可以改变的!看法大概如下:

const [int* (p)];

int const[* (p)];

int* const [p];

const [int* const [p]];

方括号内为其直接修饰的部分,圆括号内为其间接修饰的部分!

 

const修饰函数参数和返回值:

const修饰函数参数表示,在函数体内部不希望改变参数的值;因为C中的规定表示,const修饰的变量的值不允许被改变,是只读的,但是本质上却能通过指针改变,所以这里可以理解成不希望被改变!

const修饰函数返回值时,表示该函数返回的值不可改变,多用于返回指针的情形!

 

5、深藏不露的volatile 关键字

volatile关键字很少见,甚至一些C的书籍中都没有提到过,它可以理解为编译器警告指示关键字,用于告诉编译器必须每次去内存中取变量值,而不可盲目的优化,它主要修饰可能被多个线程访问的变量,也可修饰可能被未知因素改变的变量!

如下示例:

#include <stdio.h>
int main()
{
    int num=5;
    
    int a=10;
    int b=10;
    a=num;  //第一处
    sleep(200);
    b=num;  //第二处
    return 0;
}

在如上程序中,编译器发现num变量没有被当作左值使用过,只被当作右值使用,所以编译器编译时,通常会“优化”一下,直接把第一处和第二处的num给替换成了5;这种情况下,第一处a的值不存在问题,但是当程序休眠暂停后,如果某种因素使得num变量的值发生了变化,不再是5,那么第二处b的值就出错了,因为它此时还是num原先的值!为了防止这种优化,所以在num变量前加volatile关键字,给编译器警告,让它不要盲目优化,老老实实的每次都去内存中取值!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值