linux c类型限定符const、volatile、inline

2018-05-14 13:06:10

const

const类型限定符是用来设定对象为只读。

const int num;
num = 2;    //报错
    
const int num = 2;  //没问题

//声明数组只读
const int days[4] = {1,2,3,4};


声明普通变量和数组使用const比较简单,指针则复杂一些,主要是要区分是限定指针本身还是限定指针指向的数据。

//p指向的值不可改变,p本身可改变
//等同于int const * p;
const int * p;

//p本身不可改变(也就是必须指向同一个地址)
//而p指向的内容可以改变
int * const p;

//同时限制
const int * const p;

同样可作用于函数

//代表在函数内不可改变第一个接收到的数组arr
void bee(const int arr[], int n);


文件间共享const全局数据

在a.c中定义,在b.c中读取

//a.c
const int n = 1;
//b.c
extern int n;


另一种方法在comm.h头文件中定义,然后a.c和b.c同时包含

//comm.c
static const int n = 1;
//a.c
#include "comm.c"
//b.c
#include "comm.c"

如果去掉了comm.c有些编译器就会报错,因为a.c和b.c重复声明了n,加上static就没有关系,因为关键字static会让n只在当前文件内可见。


volatile

这个关键字用来告诉计算机这个变量是易变的,主要是用来处理数据共享的。

我们知道寄存器里也有少量的内存(高速缓存),有时候聪明的编译器为了加快运行速度,把读取频繁的但又没有改变的变量会临时放在寄存器里,当然在不共享数据的程序里完全没有问题。

int x = 1;
int val1 = x;

//一些额外的代码,但是都没有改变x

int val2 = x;

经过优化的编译器在编译上面的代码时,发现x被读取了2次,但是在读取中间又没有改变x,于是它就会优化编译结果,执行代码时,第一次读取x后x就会存入高速缓存,第二次直接在高速缓存读取。假设在2次读取x的中间其他程序修改了x为3,那么第二次读取x(因为是从高速缓存里读出来的)就还是1。

所以在声明时加上volatile,这样编译器就不会对它进行优化,每次都会从内存里读,不会从高速缓存里读取x

volatile int x = 1;


inline 是用来声明内联函数的,内联函数可以减少频繁的入栈和出栈。

#include <stdio.h>

inline void test(){
    printf("haha\n");
}

int main(){
    int i = 0;
    for(; i < 100; i++){
        test();
    }
}

上面的代码编译后,类似于

#include <stdio.h>

int main(){
    int i = 0;
    for(; i < 100; i++){
        printf("haha\n");
    }
}

inline 只适合函数体内代码简单的函数数使用,不能包含复杂的结构控制语句例如 while、switch,并且内联函数本身不能是直接递归函数(自己内部还调用自己的函数)。

内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率。如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,消耗更多的内存空间。


总结

1.本文对限定符const volatile做了简单的介绍,如果有疑问可以给我留言
2.gcc4.8,运行环境centos7 64位
3.原文地址http://www.freecls.com/a/2712/22

©著作权归作者所有
收藏
推荐阅读
简介
天降大任于斯人也,必先苦其心志。