C中常量和volatile指针的区别是什么?

C中常量和volatile指针的区别是什么?,c,C,C中常量和volatile指针的区别是什么?下面是对这两个概念的解释 const关键字指定初始化后不能修改指针;此后,指针将受到保护,不会被修改 volatile关键字指定与后面的名称关联的值可以由用户应用程序中的操作以外的其他操作修改。因此,volatile关键字可用于声明共享内存中的对象,这些对象可由多个进程或用于与中断服务例程通信的全局数据区域访问 它来自于指向无法修改的数据的常量指针(即const char*s=…)。易失性指针(即,volatile char*s=…)提示编译器不要将指

C中常量和volatile指针的区别是什么?

下面是对这两个概念的解释

const关键字指定初始化后不能修改指针;此后,指针将受到保护,不会被修改

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

它来自于指向无法修改的数据的常量指针(即
const char*s=…
)。易失性指针(即,
volatile char*s=…
)提示编译器不要将指针引用的数据缓存在CPU寄存器或其他地方。相反,每次需要它们时,都会从原始内存位置重新读取它们。如果数据的内容可能在编译器的作用域之外发生更改,例如通过第二个线程对其进行修改,则需要这样做


小心,
const char*
char*const
是不同的东西,对于
volatile
限定符也是一样的。如果不确定,请查找它们。

通常,
const
volatile
应用于指针对象,而不是指针本身

const
表示不允许通过该指针修改指针对象

volatile
意味着其他人/事物可能会修改指针对象,即使您的代码没有修改。这还意味着写入变量可能不仅仅是存储一个值,以便下次使用该变量时检索。因此,每当代码读取或写入易失性值时,编译器都必须生成从实际内存读取(或写入)的代码,而不仅仅是(例如)分配寄存器供临时使用,以及读取/写入寄存器


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

区别实际上在于
const
volatile
之间的区别。这两个概念唯一的共同点是语法
const
是编译器强制执行的,并表示“程序员无法更改此数据”。
volatile
表示“此数据可能被其他人更改”,因此编译器不会对该数据做出任何假设。如果没有
volatile
,编译器可能会说“我将这些数据从内存中放入寄存器,因为我没有对这些数据做过任何操作,我确信它们是相同的,我不需要再次将其读入寄存器。”当数据标记为
volatile
时,编译器不会做出这样的假设(因为其他人可能已经更改了数据),因此它会将数据重新读取到寄存器中

现在,你是在问他们之间的区别吗

int *const p;
const int* p;

或者两者之间的区别

int *const p;
const int* p;

在前一种情况下:
p
是指向
int
的指针,其中该指针点不能由程序员更改,而
q
是指向
int
的指针,该指针点可以由程序员以外的人更改,因此编译器对该指针不作任何假设

因此:

在后一种情况下:
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

它们完全不同。你看过文档了吗?@Anon:但是它们有相反的上下文。这个问题对于新手来说是合法的。+1来平衡。@the_-drow:它们看起来相反,但是
const volatile
是一个完全合法的cv限定符,意思是“程序没有改变它,但是其他的东西可能会改变它,或者执行访问本身也可能会改变它“是的,但这对新手来说太过分了。记忆障碍和其他低级噩梦是经验丰富的开发人员的习惯用语。对新手来说,它们似乎是相反的。必须立即鼓励新手不要认为它们是相反的,即使他们没有处理“低级噩梦”。否则,他们可能会认为
const
意味着你(和编译器)可以假设值不能更改,这在涉及指针时显然不是这样。例如,
const char
不能更改值,但是
const char*
指向的字符可以在您的背部转动时有效地更改值(例如,由于别名)
volatile
的另一个合法用途是当访问数据的行为本身很重要时,这在内存映射的I/O中相当可能。在标准的1.9(6)中,“可观察行为”定义为“对
volatile
数据的读写顺序以及对库I/O函数的调用。”这取决于它是
const char*p
还是
char*const p
。您可以合理地使用
const char*const p
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