【问题标题】:What is the difference between these declarations in C?C中的这些声明有什么区别?
【发布时间】:2010-09-18 22:46:55
【问题描述】:

在 C 和 C++ 中,以下声明的作用是什么?

const int * i;
int * const i;
const volatile int ip;
const int *i;

以上声明有错吗?

如果不是,它们之间的含义和区别是什么?

上述声明有什么用处(我的意思是在 C/C++/嵌入式 C 中我们必须在什么情况下使用它们)?

【问题讨论】:

  • 如果您要编辑语法和拼写,为什么不用“I”而不是“!”输入“If”?

标签: c++ c pointers declaration


【解决方案1】:

const int * i;

i 是一个指向常量整数的指针。 i 可以更改为指向不同的值,但i 指向的值不能更改。

int * const i;

i 是一个指向非常量整数的常量指针。 i 指向的值可以更改,但i 不能更改为指向不同的值。

const volatile int ip;

这个有点棘手。 ipconst 的事实意味着编译器不会让您更改 ip 的值。但是,它仍然可以在理论上进行修改,例如通过获取其地址并使用const_cast 运算符。这是非常危险的,不是一个好主意,但这是允许的。 volatile 限定符表示任何时候访问ip,它都应该总是从内存中重新加载,即它不应该被缓存在寄存器中。这可以防止编译器进行某些优化。当您有一个可能被另一个线程修改的变量,或者如果您正在使用内存映射 I/O 或其他可能导致编译器可能不期望的行为的类似情况时,您希望使用 volatile 限定符。在同一个变量上使用constvolatile 是相当不寻常的(但合法)——你通常会看到一个但看不到另一个。

const int *i;

这与第一个声明相同。

【讨论】:

  • 您确定 volatile 可以保证使只读值反映在另一个线程中所做的更改吗?在什么实现上?具有非一致缓存的多核架构呢?
  • 如果一个变量被声明constip在这里),那么用const_cast删除const是未定义的行为,以便修改值。此外,不保证 volatile 会使更改对另一个线程可见。特定的编译器可能会做出这样的保证。
  • 安东尼完全正确。 volatile 不会使您的变量具有线程意识。此外,从声明为 const 的变量中丢弃 const 是未定义的行为。
  • volatile 保证以下 AFAIK,存储和读取不会被重新排序或优化掉,编译器不会假设在对 var 的引用之间不会修改值
  • 来自微控制器世界的一句话:寄存器(例如,A/D 寄存器)是一个 volatile const 并不少见。如果您有 CodeWarrior 的副本,请查看 HC11 和 PIC 芯片的默认头文件。
【解决方案2】:

您可以从右到左阅读 C/C++ 中的变量声明。

const int *i;  // pointer to a constant int (the integer value doesn't change)

int *const i;  // constant pointer to an int (what i points to doesn't change)

const volatile int ip;  // a constant integer whose value will never be cached by the system

他们每个人都有自己的目的。任何 C++ 教科书或半体面的资源都会有各自的解释。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-07
    相关资源
    最近更新 更多