Chinaunix首页 | 论坛 | 博客
  • 博客访问: 89989
  • 博文数量: 99
  • 博客积分: 55
  • 博客等级: 民兵
  • 技术积分: 510
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-20 21:29
文章分类

全部博文(99)

文章存档

2013年(5)

2012年(94)

我的朋友

分类:

2012-06-09 13:31:49

原文地址:Const Volatile 关键词解析 作者:icybay

const是一个C语言的关键字,它限定一个变量不允许被改变。使用const在一定程度上可以提高程序的安全性和可靠性.

C中的CONST 

问题:const变量 & 常量   
为什么下面的例子在使用一个const变量来初始化数组,ANSI C的编译器会报告一个错误呢?    
const int n = 5;   int a[n];

这个问题讨论的是“常量”与“只读变量”的区别。常量肯定是只读的,例如5, “abc”,等,肯定是只读的,因为常量是被编译器放在内存中的只读区域,当然也就不能够去修改它。而“只读变量”则是在内存中开辟一个地方来存放它的 值,只不过这个值由编译器限定不允许被修改。C语言关键字const就是用来限定一个变量不允许被改变的修饰符(Qualifier)。上述代码中变量n 被修饰为只读变量,可惜再怎么修饰也不是常量。而ANSI C规定数组定义时长度必须是“常量”,“只读变量”也是不可以的。

如果const位于*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;如果const位于*的右侧,const就是修饰指针本身,即指针本身是常量。

C++中CONST 

1.const与define。两者都可以用来定义常量,但是const定义时,定义了常 量的类型,所以更精确一些。#define只是简单的文本替换,除了可以定义常量外,还可以用来定义一些简单的函数,有点类似内置函数。const和 define定义的常量可以放在头文件里面。(小注:可以多次声明,但只能定义一次)

2.const与指针

int me;
  const int * p1=&me;//p1可变,*p1不可变,但是不能用*p1来修改,p1可以转向

  int * const p2=&me;//p2不可变,*p2可变,此时允许*p2来修改其值,但是p2不能转向。

  const int *const p3=&me;


3.const与函数

限定函数的传递值参数:
void function(const int Var); //传递过来的参数在函数内不可以改变.
限定函数返回值型.
const int function(); //此时const无意义
const myclassname function(); //函数返回自定义类型myclassname.
限定函数类型.
void function()const;

const成员函数应该在函数原型说明和函数定义中都增加const限定。非常量成员函数不能被常量成员对象调用,因为它可能企图修改常量的数据成员。非常量成员函数不能被常量成员对象调用,因为它可能企图修改常量的数据成员。

为什么需要const成员函数?   
我们定义的类的成员函数中,常常有一些成员函数不改变类的数据成员,也就是说,这些函数是"只 读"函数,而有一些函数要修改类数据成员的值。如果把不改变数据成员的函数都加上const关键字进行标识,显然,可提高程序的可读性。其实,它还能提高 程序的可靠性,已定义成const的成员函数,一旦企图修改数据成员的值,则编译器按错误处理。

const成员函数还有另外一项作用,即常量对象相关。对于内置的数据类型,我们可以定义它们的常量,用户自定义的类也一样,可以定义它们的常量对象。例如,定义一个整型常量的方法为:   
const int i=1 ;   
同样,也可以定义常量对象,假定有一个类classA,定义该类的常量对象的方法为:   
const classA a(2);

const成员函数表示该成员函数只能读类数据成员,而不能修改类成员数据。定义const成员函数时,把const关键字放在函数的参数表和函数体之间。任何不修改成员数据的函数都应该声明为const函数,这样有助于提高程序的可读性和可靠性。

Volatile
定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。主要应用于:
1). 并行设备的硬件寄存器(如:状态寄存器)   
2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)   
3). 多线程应用中被几个任务共享的变量

当一个对象的值可能在编译器的控制或者检测之外被改变时,例如被系统时钟更新的变量,那么该对象应该声明成voliate,以便防止编译器的某些优化行为。

volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。

volatile对应的变量可能在你的程序本身不知道的情况下发生改变 ,比如多线程的程序,共同访问的内存当中,多个程序都可以操纵这个变量 。你自己的程序,是无法判定合适这个变量会发生变化 。还比如,他和一个外部设备的某个状态对应,当外部设备发生操作的时候,通过驱动程序和中断事件,系统改变了这个变量的数值,而你的程序并不知道。

对于volatile类型的变量,系统每次用到他的时候都是直接从对应的内存当中提取,而不会利用cache当中的原有数值,以适应它的未知何时会发生的变化,系统对这种变量的处理不会做优化——显然也是因为它的数值随时都可能变化的情况。

一般说来,volatile用在如下的几个地方:

1、中断服务程序中修改的供其它程序检测的变量需要加volatile;
2、多任务环境下各任务间共享的标志应该加volatile;
3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;
另外,以上这几种情况经常还要同时考虑数据的完整性(相互关联的几个标志读了一半被打断了重写),在1中可以通过关中断来实 现,2中可以禁止任务调度,3中则只能依靠硬件的良好设计了。
阅读(229) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~