2010-01-18 43 views
9

C中的const和volatile指针有什么区别?C中的const和volatile指针有什么区别?

+4

它们完全不同。你甚至浏览过文档吗? – 2010-01-18 21:52:53

+0

@Anon:但他们有相反的背景。这个问题对于新手来说是合法的。 +1来平衡。 – 2010-01-18 22:03:32

+1

@the_drow:它们看起来相反,但是“const volatile”是一个完全合法的cv限定符,意思是“程序没有改变它,但其他的东西可能,或者访问本身可能会做某些事情”。 – 2010-01-18 22:26:08

回答

16

这个差异真的归结于constvolatile之间的差异。这两个概念唯一共同的地方就是语法。 const是编译器强制执行的并且说“程序员不能改变这个。” volatile说“这个数据可能会被其他人改变”,所以编译器不会对这些数据做任何假设。如果没有volatile,编译器可能会说“我把这些数据从内存中放入了一个寄存器中,而且由于我没有对这些数据做任何事情,我相信它是一样的,我不需要再次将它读入寄存器。 “当数据标记为volatile时,编译器不会做出这样的假设(因为其他人可能已经更改了数据),因此它会将数据重新读入寄存器。

现在,你要求

const int* p; 

volatile int* q; 
之间

int *const p; 

int *volatile q; 

或差之差0

在前一种情况:p是一个指向int而且该指针指向不能由程序员而q被改变的指针int而且该指针指向可由不是程序员以外的其他人进行更改,以便编译器对该指针不做任何假设。

所以:

int *const p = (int*)malloc(sizeof(int)); 
int *volatile q = (int*)malloc(sizeof(int)); 
*p = 17; // legal; 
p = (int*)malloc(sizoef(int)); // not legal 
*q = 17; // legal; 
q = (int*)malloc(sizeof(int)); // legal 

在后者的情况:p是一个指向int和什么p指向不能由程序员而q改变是一个指向int和什么q是指向可以被程序员以外的其他人改变,所以编译器不会对该数据做任何假设。

int i = 17; 
int j = 34; 
const int *p = &i; 
volatile int *q = &i; 
*p = 51; // not legal 
p = &j; // legal 
*q = 51; // legal 
q = &j; // legal 
+0

很好的答案! +1 – 2010-01-18 22:03:58

+0

'volatile'的另一个合法用途是访问数据的行为本身非常重要,这在内存映射I/O中是相当可能的。在标准1.9(6)中,“可观察行为”被定义为“对'易失性'数据的读取和写入以及对库I/O函数的调用序列。” – 2010-01-18 22:29:42

1

下面是那些两个概念

关键字const指定该指针初始化后不能被修改的说明;此后保护指针不受修改。

volatile关键字指定与以下名称关联的值可以通过除用户应用程序中的操作以外的操作修改。因此,volatile关键字可用于声明共享内存中的对象,这些对象可以被多个进程或用于与中断服务例程通信的全局数据区访问。

它来自here

1

一个const指针(即const char* s = ..)指向可以被修改的数据。一个易失性指针(即volatile char* s = ...)暗示编译器不会缓存指针指向CPU寄存器或其他地方的数据。相反,他们每次需要时都会从原始存储位置重新读取。如果数据内容可能在编译器范围之外改变,例如通过修改它的第二个线程,则这是必需的。

要小心,const char*char* const是不同的东西,volatile限定符相同。如果您不确定,请查看它们。

2

通常,constvolatile适用于指针,而不是指针本身。

const表示您不允许通过该指针修改指针。

volatile意味着某人/别的东西可能会修改指针,即使您的代码没有。这也意味着写入变量可能会做更多的事情,而不仅仅是存储下次使用该变量时要检索的值。因此,无论您的代码何时读取或写入易失性值,编译器都必须生成读取(或写入)实际内存的代码,而不仅仅是(例如)为临时使用分配寄存器以及读取/写入寄存器。

编辑:请注意,即使您不允许通过const指针修改数据,数据仍可能通过其他方式进行修改。事实上,有时候你可以有一个指针,它既是const也是volatile,这意味着你不能改变它,但其他人可能会改变它。

+0

它取决于它是'const char * p'还是'char * const p'。你可以合理地使用const char * const p'。 – 2010-01-19 05:02:45

相关问题