`
Michaelmatrix
  • 浏览: 208626 次
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

C语言中关键字auto、static、register、const、volatile、extern的作用

 
阅读更多

1)auto
  这个关键字用于声明变量的生存期为自动,即将不在任何类、结构、枚举、联合和函数中定义的变量视为全局变量,而在函数中定义的变量视为局部变量。这个关键字不怎么多写,因为所有的变量默认就是auto的。


(2)register
  这个关键字命令编译器尽可能的将变量存在CPU内部寄存器中而不是通过内存寻址访问以提高效率。
(3)static
  常见的两种用途:
    1>统计函数被调用的次数;
    2>减少局部数组建立和赋值的开销.变量的建立和赋值是需要一定的处理器开销的,特别是数组等含有较多元素的存储类型。在一些含有较多的变量并且被经常调用的函数中,可以将一些数组声明为static类型,以减少建立或者初始化这些变量的开销.
  详细说明:
    1>、变量会被放在程序的全局存储区中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与栈变量和堆变量的区别。
    2>、变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。
    3>当static用来修饰全局变量时,它就改变了全局变量的作用域,使其不能被别的程序extern,限制在了当前文件里,但是没有改变其存放位置,还是在全局静态储存区。

  使用注意:
    1>若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
    2>若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
    3>设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题(只要输入数据相同就应产生相同的输出)。

(4)const
  被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。它可以修饰函数的参数、返回值,甚至函数的定义体。
  作用:
    1>修饰输入参数
      a.对于非内部数据类型的输入参数,应该将“值传递”的方式改为“const引用传递”,目的是提高效率。例如将void Func(A a) 改为void Func(const A &a)。
      b.对于内部数据类型的输入参数,不要将“值传递”的方式改为“const引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。例如void Func(int x) 不应该改为void Func(const int &x)。
    2>用const修饰函数的返回值
      a.如果给以“指针传递”方式的函数返回值加const修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const修饰的同类型指针。
       如对于: const char * GetString(void);
       如下语句将出现编译错误:
        char *str = GetString();//cannot convert from 'const char *' to 'char *';
       正确的用法是:
       const char *str = GetString();
      b.如果函数返回值采用“值传递方式”,由于函数会把返回值复制到外部临时的存储单元中,加const修饰没有任何价值。如不要把函数int GetInt(void) 写成const int GetInt(void)。
    3>const成员函数的声明中,const关键字只能放在函数声明的尾部,表示该类成员不修改对象.

   说明:
    const type m; //修饰m为不可改变
   示例:
    typedef char * pStr; //新的类型pStr;
    char string[4] = "abc";
    const char *p1 = string;
    p1++; //正确,上边修饰的是*p1,p1可变
    const pStr p2 = string;
    p2++; //错误,上边修饰的是p2,p2不可变,*p2可变
   同理,const修饰指针时用此原则判断就不会混淆了。
    const int *value; //*value不可变,value可变
    int* const value; //value不可变,*value可变
    const (int *) value; //(int *)是一种type,value不可变,*value可变
              //逻辑上这样理解,编译不能通过,需要tydef int* NewType;
    const int* const value;//*value,value都不可变

(5)volatile
   表明某个变量的值可能在外部被改变,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。它可以适用于基础 类型如:int,char,long......也适用于C的结构和C++的类。当对结构或者类对象使用volatile修饰的时候,结构或者类的所有成 员都会被视为volatile.
  该关键字在多线程环境下经常使用,因为在编写多线程的程序时,同一个变量可能被多个线程修改,而程序通过该变量同步各个线程。
  简单示例:
   DWORD __stdcall threadFunc(LPVOID signal)
   {
     int* intSignal=reinterpret_cast(signal);
     *intSignal=2;
     while(*intSignal!=1)
     sleep(1000);
     return 0;
   }
  该线程启动时将intSignal 置为2,然后循环等待直到intSignal 为1 时退出。显然intSignal的值必须在外部被改变,否则该线程不会退出。但是实际运行的时候该线程却不会退出,即使在外部将它的值改为1,看一下对应的伪汇编代码就明白了:
     mov ax,signal
     label:
     if(ax!=1)
     goto label
   对于C编译器来说,它并不知道这个值会被其他线程修改。自然就把它cache在寄存器里面。C 编译器是没有线程概念的,这时候就需要用到volatile。volatile 的本意是指:这个值可能会在当前线程外部被改变。也就是说,我们要在threadFunc中的intSignal前面加上volatile关键字,这时 候,编译器知道该变量的值会在外部改变,因此每次访问该变量时会重新读取,所作的循环变为如下面伪码所示:
     label:
     mov ax,signal
     if(ax!=1)
     goto label
  注意:一个参数既可以是const同时是volatile,是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。

(6)extern
  extern 意为“外来的”···它的作用在于告诉编译器:有这个变量,它可能不存在当前的文件中,但它肯定要存在于工程中的某一个源文件中或者一个Dll的输出中。

分享到:
评论

相关推荐

    C语言中关键字const、static、volatile、extern、auto、register的用法分析.doc

    C语言中关键字const、static、volatile、extern、auto、register的用法分析

    初级C语言教案 auto break case char const

    里面介绍的 很详细auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef unsigned union void ...

    C_gjz.rar_float

    C语言中的关键字 auto :声明自动变量 一般不使用 double :声明双精度变量或函数 float:声明浮点型变量或函数 int: 声明整型变量或函数 short :声明短整型变量或函数 long :声明长整型变量或函数 struct:声明...

    C语言深度解剖

    1.1 最宽恒大量的关键字auto 1.2 最快的关键字register 1.3 最不实名的关键字static 1.4 基本数据类型 1.5 最冤枉的关键字sizeof 1.6 if/else组合 1.7 switch/case组合 1.8 do/while/for关键字 1.9 goto关键字 1.10 ...

    C语言 由ANSI标准定义的32个关键字

    auto double int struct break else long switch case enum register typedef char extern return union const float short unsigned continue for signed void default goto sizeof volatile do if while static

    C语言常见面试要点 必看

    笔试,面试之前必看: Const关键字; CExtern关键字; Static关键字; stdafx 头文件的意义; stdcall cdecl fastcl ...Volatile vs Register 关键字; 全局变量与局部变量初始值问题; 标准库; 字面常量; 数据对齐;

    c语言入门教程.txt

    auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while ...

    编译原理课后习题答案(蒋立源第三版)

    C语言的关键字有:auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void ...

    编译原理西北工业大学课后答案

    C语言的关键字有:auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void ...

    西北工业大学版(蒋立源第三版)编译原理课后习题答案

    C语言的关键字有:auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void ...

    哈希表查找

    //待存入表格数据 char *key_input[] = { "auto", "break", "case", "char", "const", "continue", "default", "do", "double", "else", "enum...//功能:输入一个C语言关键字,快速提示这个关键字的功能及用法

    C学习深入学习总结

    2.6 你是否知道auto、extern、register、volatile、restrict、inline的用法? 6 3 const 6 3.1 你是否经常使用const来表明不能够被更改的变量? 6 3.2 你是否经常使用const常量来代替宏? 6 3.3 下面四种情况,你...

    C语言解析教程(原书第4版)(美) 凯利.pdf

    6.19 类型限定符const和volatile 6.20 总结 6.21 练习 第7章 位操作符和枚举类型 7.1 位操作符和表达式 7.1.1 按位求反 7.1.2 补码 7.1.3 位逻辑操作符 7.1.4 左移位和右移位操作符 7.2 掩码 7.3 软件工具:打印int...

    (谭浩强)c语言学习书

    auto break case char const continue default do double else enum extern float for goto if int long register return short signed static sizof struct switch typedef union unsigned ...

    c语言深度剖析

    1.1,最宽恒大量的关键字----auto.................. 1.2,最快的关键字---- register........................ 1.2.1,皇帝身边的小太监----寄存器...... 1.2.2,使用register修饰符的注意点..... 1.3,最名不符实...

    C#编写的简单词法分析

    auto double int struct break else long switch case enum register typedef char extern return union const float short unsigned continue for signed void default goto sizeof volatile do while static f ...

    C语言深度解剖(完美版).pdf

    1.1,最宽恒大量的关键字----auto..........................................................................................11 1.2,最快的关键字---- register.................................................

    西北工业大学版(蒋立源第三版)编译原理课后习题答案

    C语言的关键字有:auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void ...

    C语言深度解剖.zip

    1.1,最宽恒大量的关键字----auto..........................................................................................11 1.2,最快的关键字---- register.................................................

Global site tag (gtag.js) - Google Analytics