多语言展示
当前在线:300今日阅读:113今日分享:31

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

C语言中关键字const、volatile、extern的作用
方法/步骤
1

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都不可变

2

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因为程序不应该试图去修改它。

3

extern:是指当前变量或函数不是本源文件内声明的,它是外部变量或外部函数,正所谓“外来的和尚会念经”,能很好的体现extern的价值。当我们在本文件中试图应用一个外部声明的全局变量或函数时,可以在其前面加上extern,表示它是外来“和尚”。         在C++中,还可用来指定使用另一语言进行链接,这时需要与特定的转换符一起使用。目前Microsoft C/C++仅支持”C”转换标记,来支持C编译器链接。使用这种情况有两种形式:u         extern “C” 声明语句u         extern “C” { 声明语句块 }volatilel           限定一个对象可被外部进程(操作系统、硬件或并发线程等)改变,声明时的语法如下:int volatile nVint;          这样的声明是不能达到最高效的,因为它们的值随时会改变,系统在需要时会经常读写这个对象的值。  只常用于像中断处理程序之类的异步进程进行内存单元访问。

推荐信息