这个问题可能很幼稚,但是:
const
个关键字?const
之间是否存在语义和/或语法差异? 答案 0 :(得分:53)
关于const
关键字,C和C ++之间没有语法差异,除了一个相当模糊的关键词:在C语言中(从C99开始),你可以将函数参数声明为
void foo(int a[const]);
相当于
void foo(int *const a);
声明。 C ++不支持这种语法。
也存在语义差异。正如@Ben Voigt已经指出的那样,在C const
声明中不会产生常量表达式,即在C中你不能使用const int
标签中的case
对象作为位字段非VLA数组声明中的宽度或数组大小(所有这些在C ++中都是可能的)。此外,const
对象默认在C中具有外部链接(C ++中的内部链接)。
至少还有一个语义差异,Ben没有提及。 C ++语言的Const-correctness规则支持以下标准转换
int **pp = 0;
const int *const *cpp = pp; // OK in C++
int ***ppp = 0;
int *const *const *cppp = ppp; // OK in C++
这些初始化在C中是非法的。
int **pp = 0;
const int *const *cpp = pp; /* ERROR in C */
int ***ppp = 0;
int *const *const *cppp = ppp; /* ERROR in C */
通常,在处理多级指针时,C ++表示你可以在任何间接深度添加const-qualification,只要你还将const-qualification一直添加到顶层。
在C中,您只能将const-qualification添加到顶级指针指向的类型,但不能更深。
int **pp = 0;
int *const *cpp = pp; /* OK in C */
int ***ppp = 0;
int **const *cppp = ppp; /* OK in C */
相同的基本一般原则的另一个表现形式是const-correctness规则在C和C ++中使用数组的方式。在C ++中你可以做到
int a[10];
const int (*p)[10] = &a; // OK in C++
尝试在C中执行相同操作将导致错误
int a[10];
const int (*p)[10] = &a; /* ERROR in C */
答案 1 :(得分:13)
前两个问题在这里得到解答:Const in C
是的,C和C ++中const
的语义差异很大。
在C ++中,适当类型的const
变量是整型常量表达式(如果它们的初始化程序是编译时常量表达式),并且可以在需要的上下文中使用,例如数组边界和枚举定义。在C中,它们不是也不可能。
在C ++中,const
个全局变量自动具有static
链接,因此您可以将它们放在头文件中。在C中,此类变量具有外部链接,并且会在链接时生成重复的定义错误。
答案 2 :(得分:8)
是的,有const
个关键字。它是1989年标准的一部分。
就兼容性而言,这是Harbison& amp;斯蒂尔,第5版:
具有类型限定符const
但没有显式存储类的顶级声明在C ++中被视为static
但在C中被视为extern
。要保持兼容,请检查顶级{{ 1}}声明并提供显式存储类。 在C ++中,字符串常量是隐式的const
;他们不在C.
答案 3 :(得分:5)
是的,至少自ANSI C(又名C89)以来const
一直存在。
它肯定出现在我"The C Programming Language (2nd Edition)", Kernighan & Ritchie的副本中(1988年出版)。
相关提取物:
const
和volatile
属性是ANSI标准的新属性。const
的目的是 宣布可能被放置在只读存储器中的对象,并可能增加机会 优化
答案 4 :(得分:5)
另外两个不同之处:
const arraytype
(即typedef int A[1]; const A a = { 0 };
)在C ++中指定常量数组类型(http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#112和http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1059)(并且其元素也是如此限定),但是non-constant array type的元素在C中是合格的。
const const
在C99中有效(在C89中无效),在任何版本的C ++中无效(您只能在语义上重复const
,而不能在语法上重复)。它在C99中与const
签订合同。
答案 5 :(得分:2)
是。来自C89的C中有const
。
以下是关于behaviour of const keyword in C的好读物。
答案 6 :(得分:2)
C中的语义与C ++中的语义不同,例如
unsigned const a = 10;
unsigned A[a];
文件范围中的在C ++中有效,但在C中无效。
答案 7 :(得分:1)
是的,C中有const
个关键字。自C90以来一直存在。
从语法上讲,它可以出现在与C ++相同的地方。在语义上,它有点松懈,IIRC。
答案 8 :(得分:1)
根据ESR,{C}草案提案标准中添加了const
。 1987年的Eric Giguere's summary of ANSI C证实了这一点。
编辑:This looks like the draft itself - 搜索“3.5.3类型限定符”。
答案 9 :(得分:1)
C中有一个“const”关键字,并且持续时间很长。如果变量被指定为“const”,则禁止写入。此外,在某些环境中,声明为“const”的变量可能位于与其他变量不同的数据段中。这个数据段可以提供硬件写保护,对于嵌入式系统,可以存储在ROM或闪存中,而不是存储在RAM中(在一些处理器上有一个非常重要的区别,这些处理器比RAM有更多的ROM或闪存 - 例如128K闪存和3.5K RAM,或2K ROM和96字节RAM)。
请注意,编译器通常不对“const”值或涉及它们的表达式进行任何推断。如果我说“const char foo [] =”Hello“;”然后引用foo [1],编译器将从存储foo []的地方加载值(很可能是'e')并使用加载的值。有时,这有用地允许在已编译的代码映像中修补值,但有时它只会浪费代码。
如果要将数字定义为编译时“可替代”常量,最好的方法,至少对于整数常量,可能是使用“枚举”。例如,“enum {woozle = 19;}”将导致19代替整个代码中的“woozle”。请注意,与文本替换不同;枚举声明遵守适当的范围规则。