C语言——const、static、volatile、inline的用法及含义

来源:互联网 发布:如何带端口ping 编辑:程序博客网 时间:2024/06/05 16:22

static关键字

1)在函数体内,一个被声明为静态的变量在这一函数被调用过程中维持其值不变(该变量存放在静态变量区)。

2) 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。注意,只有在定义了变量后才能使用。如果变量定义在使用之后,要用extern 声明。所以,一般全部变量都会在文件的最开始处定义。

3) 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用,相当于这个函数在别的模块里是不可见的

4)一个被声明的静态变量如果没有被初始化,那么他会被自动初始化(默认)为0,不想被释放的时候,可以使用static修饰。比如修饰函数中存放在栈空间的数组。如果不想让这个数组在函数调用结束释放可以使用static修饰 .

static关键字至少有下列作用:
(1)设置变量的存储域,函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;

(2)限制变量的作用域,在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;

(3)限制函数的作用域,在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;


在C++中:

(1)、被static修饰的变量属于类变量,可以通过类名.变量名直接引用,而不需要new出一个类来.
(2)、在类中的static成员变量意味着它为该类的所有实例所共享,也就是说当某个类的实例修改了该静态成员变量,其修改值为该类的其它所有实例所见;
(3)、在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。
(4)、静态数据成员既可以通过对象名引用,也可以通过类名引用.


const关键字:const简单来说可以概括为“readonly”

先说const修饰指针的用法:
char *const cp; //到char的const指针
char const *pc1; //到const char的指针
const char *pc2; //到const char的指针(后两个声明是等同的)
用我的理解来看:
cp   const修饰的cp在*的里面,所以cp指向的地址是不能改变的,但他所指向的内容是可以改变的;
pc1  const修饰的是*pc1,也就是指针所指向的对象,所以他的内容是不能改变的,但是他指向的地址是可以改变的;
欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了


const只对它左边的东西起作用,唯一的例外就是const本身就是最左边的修饰符,那么它才会对右边的东西起作用

常量指针和指针常量:

char const *p1;
char* const p2;

根据上面那句话来判断:p1是常量指针(const修饰的是*p1,所以他所指向的对象是不可改变的,也就是常量);
                      p2是指针常量(const修饰的是p2,所以他指向的地址是不可改变的);

const修饰函数:
(1)、在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
(2)、修饰函数的返回值
如果给以“指针传递”方式的函数返回值加 const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。

const char * GetString(void);
如下语句将出现编译错误:

char *str = GetString();
正确的用法是

const char *str = GetString();

const跟宏定义的区别:const修饰的数据常量是有数据类型的,而用宏定义的数据常量是没有数据类型的,编译器可以对前者进行类型安全检查,而对后者只进行字符替换,没有类型安全检查,并且在字符替换时可能会产生意料不到的错误。

在C++中:

(1)、修饰类成员变量

用const修饰的类成员变量,只能在类的构造函数初始化列表中赋值,不能在类构造函数体内赋值。


http://blog.csdn.net/xdrt81y/article/details/24333335
这篇博文对const在C++中的使用写的非常通透

volatile关键字:

1.volatile的本意是“易变的” 因为访问寄存器要比访问内存单元快的多,所以编译器一般都会作减少存取内存的优化,但有可能会读脏数据。当要求使用volatile声明变量值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。精确地说就是,遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问;如果不使用valatile,则编译器将对所声明的语句进行优化。(简洁的说就是:volatile关键词影响编译器编译的结果,用volatile声明的变量表示该变量随时可能发生变化,与该变量有关的运算,不要进行编译优化,以免出错)
 一般说来,volatile用在如下的几个地方:
1、中断服务程序中修改的供其它程序检测的变量需要加volatile;
2、多任务环境下各任务间共享的标志应该加volatile;
3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;
另外,以上这几种情况经常还要同时考虑数据的完整性(相互关联的几个标志读了一半被打断了重写),在1中可以通过关中断来实现,2中可以禁止任务调度,3中则只能依靠硬件的良好设计了。

inline关键字:

从inline的作用来看,其放置于函数声明中应当也是毫无作用的:inline只会影响函数在translation unit(可以简单理解为C源码文件)内的编译行为,只要超出了这个范围inline属性就没有任何作用了。所以inline关键字不应该出现在函数声明中,没有任何作用不说,有时还可能造成编译错误(在包含了sys/compiler.h的情况下,声明中出现inline关键字的部分通常无法编译通过); 


yo! peace





阅读全文
0 0
原创粉丝点击