static:

作用:

1)未被初始化的静态变量初始化为0。如果一个全局或局部变量加上关键字static,则它的默认初始化值就为0。

2)隐藏(链接属性 )。如果一个变量或函数加上关键字static,则它只能在本文件内有效,其他文件是不能访问它的,从而有效的保护了改变量或函数不会被其他文件修改。

3)使局部变量内容持久化 如果一个局部变量被声明为静态的,则它的存储位置就从栈变成了静态存储区,栈的内容出了作用域就会被销毁,而静态区的直到程序结束才销毁。

4)可以用在类的成员函数以及成员变量中。

static用于类中:

静态数据成员以及静态函数,不属于任何一个对象,是所有对象所共享的。

静态数据成员不能在构造函数中初始化,需要在类外初始化。格式为:类型 类名::静态数据成员=值。

用法:类名::静态数据成员。

静态成员函数只能访问静态数据成员、静态成员函数和类以外的函数和数据,不能访问类中的非静态数据成员(因为非静态数据成员只有对象创建时才有意义)静态成员函数、静态数据成员可以被任何权限许可的函数访问。


inline:(内联)

在一个函数前加上inline 该函数就变成了内联函数。内联函数就是在它被调用的地方展开。(类似于宏,但和宏有一定的区别)必须和函数的定义在一起。

作用:主要使用在一些短小而调用非常频繁的函数中,因为其没有函数调用(压栈)的开销,所以提升了运行效率。

在类中实现的函数默认是内联函数。

内联函数和宏的区别:

1)宏是在预处理时进行替换,而内联函数是在编译时展开。

2)inline函数可以进行类型的检查,宏无法进行类型检查。

3)宏容易出现二异性、副作用等。

4)inline直接在嵌入到目标代码中,宏作简单的文本替换。

inline使用的场合:

1)使用宏定义的函数都可以用内联函数替换

2)类的成员接口函数。

哪些地方不能用内联:

1)如果函数代码较长,最好不用内联,会导致内存消耗太大。

2)函数内部有循环,函数执行时间比函数调用时间长。


const:

一个变量加上const修饰后,就变成了只读变量(不等于常亮),一般不可以被修改。

修饰指针:

const int *p 、int const *p 两条语句等价,const修饰*p,即*p不可被修改,p可以被修改。

int *const p const修饰p,即p不可以被修改,*p可被修改。

int const *const p *p、p都不可以被修改。

作用:

1)定义const变量,使变量不会被修改,有效的保护了该变量。防止被意外修改。

2)便于进行类型检查。

3)高效(编译器一般不为const变量分配存储空间,而是将它保存在符号表中)

const与宏常量的区别:

1)const常量有数据类型,宏常量没有数据类型,所以没有类型的检查,是不安全的。

2)const可以进行调试,宏不可以调试,无法检查错误。

const在类中的应用:

1)常对象:类名 const 对象名 或 const 类名 对象名

 定义常对象时必须进行初始化,而且其数据成员不能被更新。

2)常对象成员函数:类型 函数名(参数表)const

 常成员函数不更新对象的数据成员,也不能调用该类中没有用const修饰的成员函数。

 如果一个对象被声明为一个常对象,则通过常对象只能调用它的常成员函数,不能调用其他成员函数

 可以参与区分重载函数 void print(); void print() const 

3)常数据成员:构造函数只能通过初始化列表对常数据成员进行初始化。


volatile:

作用:确保指令不会因为编译器的优化而省略。即防止编译器对代码进行优化。用它声明的变量可以被某些编译器未知的因素改变。

例如:定义一个全局变量,进行多次读这个变量,不做修改,这时编译器就会做一些优化,将这个变量暂存到寄存器中,等下一次读这个变量时就不必在内存中读,而是到寄存器中读取,这样大大提高了效率。但也会出现一些问题,如果此时有另一个函数修改该变量,只会修改内存中该变量的值,不会改变寄存器中的值,这时第一个函数再从寄存器中访问这个变量,就不会是我们预期的结果。

解决方法就是加上关键字volatile,每次访问该变量都从内存中访问,修改该变量就不会出问题。

  1 #include<stdio.h>
  2 #include<signal.h>
  3 #include<stdlib.h>
  4 volatile int a = 0;
  5 void handler(int sig)
  6 {
  7     printf("the %d signal is coming\n",sig);
  8     a=a+1;
  9 }
 10 int main()
 11 {
 12     signal(SIGINT,handler);
 13     while(!a);
 14     return 0;
 15 }
//不加关键字volatile 并且使编译器进行优化
[fbl@localhost volatile]$ make clean;make
rm -f volatile
gcc -o volatile volatile.c -O2 
[fbl@localhost volatile]$ ./volatile 
^Cthe 2 signal is coming
^Cthe 2 signal is coming
^Cthe 2 signal is coming
^\Quit (core dumped)

//加关键字volatile
[fbl@localhost volatile]$ make clean;make
rm -f volatile
gcc -o volatile volatile.c -O2 
[fbl@localhost volatile]$ ./volatile 
^Cthe 2 signal is coming
[fbl@localhost volatile]$


auto:

作用:auto被解释为一个自动存储变量的关键字,也就是申明一块临时的变量内存


extern:

extern可置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量或函数时,在其它模块中寻找其定义。另外,extern也可用来进行链接指定。

在使用extern时候要严格对应声明时的格式


refister:

作用:如果一个变量被register来修辞,就意味着,该变量会作为一个寄存器变量,让该变量的访问速度达到最快。