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

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

操作方法

  • 01

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

  • 02

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

  • 03

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

(0)

相关推荐

  • C语言中关键字auto、static、register的作用

    C语言中关键字auto.static.register的作用 操作方法 01 auto:这个关键字用于声明变量的生存期为自动,即将不在任何类.结构.枚举.联合和函数中定义的变量视为全局变量,而在函数中 ...

  • C语言常用关键字

    在C语言中,经常需要输入关键字,以下是C语言中常用的一些关键字说明. 操作方法 01 void,功能:声明无返回值或无参数函数,声明无类型指针. 02 char,功能:字符型类型数据. 03 int, ...

  • 在C/C++语言中使用正则表达式

    本文所有的内容都来自网络,加上一些个人的理解,不保证正确性,欢迎批评指正 说起正则表达式(Regular Expression),也许有的朋友天天都在使用,比如grep、vim、sed、awk,只是可 ...

  • 如何使用R语言中的数学函数对数函数和指数函数

    R语言中的数学函数除了三角函数之外,还有相应的指数函数和对数函数,常见的指数函数有exp,对数函数有log.log10.下面利用几个实例讲述指数函数和对数函数的用法,操作如下: 操作方法 01 第一步 ...

  • R语言中如何删除数据对象

      R语言中如何删除数据对象 首先需要打开R studio,新建文件脚本,[File]--[New Script]. 然后会发现,global environment这里之前代码留下的数据集非常麻烦, ...

  • php语言中数组怎么进行去重处理

    我们在编写代码的过程中可能会使用到PHP语言.接下来小编就教大家怎样给PHP语言的数组去重. 具体如下:1. 首先我们将需要去重的数组打印出来,然后我们可以看到数组有一部分相同的值. 2. 接下来我们 ...

  • 如何使用python语言中字符串方法替换子字符串

    跟JavaScript一样的是,replace在python语言中也是替换字符串,但是在JavaScript中只替换一次,而在python语言中是替换所有的相同的字符串.下面利用几个实例说明repla ...

  • 如何使用R语言中的函数绘制正态曲线

    正态曲线是数学中的一种概率统计函数,用于统计分析数据.R语言中也有处理正态曲线的函数dnorm(),可以使用这个函数绘制正态曲线.下面利用一个实例说明这个函数的用法,操作如下: 操作方法 01 第一步 ...

  • HTML语言中部分HTML标签的英语全称和属性

    HTML标签是HTML语言中最重要的组成部分,大部分都是英语的缩写,所以如果我们英语还可以的话,学起来会相对容易很多.如果我们知道它们的全称的话,也会大大提高我们的记忆效率. 关于标签HTML的英语全 ...