这个问题可能很幼稚,但是:
- C中有
const
关键字吗? - 从哪个版本开始?
const
C 和 C++ 之间是否存在语义和/或句法差异?
这个问题可能很幼稚,但是:
const
关键字吗?const
C 和 C++ 之间是否存在语义和/或句法差异?C 和 C++ 之间在关键字方面没有语法差异const
,除了一个相当模糊的差异:在 C(C99 起)中,您可以将函数参数声明为
void foo(int a[const]);
这相当于
void foo(int *const a);
宣言。C++ 不支持这样的语法。
语义差异也存在。正如@Ben Voigt 已经指出的那样,在Cconst
声明中不会产生常量表达式,即在C 中,您不能const int
在标签中使用对象case
,作为位域宽度或作为非VLA 数组声明中的数组大小(所有这些在 C++ 中是可能的)。此外,const
默认情况下,对象在 C 中具有外部链接(在 C++ 中为内部链接)。
至少还有一个语义差异,Ben 没有提到。C++语言的const-正确性规则支持以下标准转换
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 限定添加到顶级指针指向的类型,但不能更深。
int **pp = 0;
int *const *cpp = pp; /* OK in C */
int ***ppp = 0;
int **const *cppp = ppp; /* OK in C */
相同基本一般原则的另一种表现形式是 const 正确性规则在 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 */
前两个问题在这里得到解答:Const in C
const
是的,C 和 C++之间的语义有很多差异。
在 C++ 中,const
适当类型的变量是整型常量表达式(如果它们的初始值设定项是编译时常量表达式),并且可以在需要它的上下文中使用,例如数组边界和枚举定义。在 C 中,它们不是也不能是。
在 C++ 中,const
全局变量自动具有static
链接,因此您可以将它们放在头文件中。在 C 中,此类变量具有外部链接,并且会在链接时产生重复的定义错误。
是的,有一个const
关键字。它被添加为 1989 年标准的一部分。
至于兼容性,这里有一段来自 Harbison & Steele,第 5 版:
具有类型限定符但没有显式存储类的顶级声明const
被认为是static
在 C++ 中但extern
在 C 中。为了保持兼容,请检查顶级const
声明并提供显式存储类。在 C++ 中,字符串常量是隐式的const
;它们不在 C 中。
是的,const
至少从 ANSI C(又名 C89)开始就一直存在。
它肯定出现在我的“The C Programming Language (2nd Edition)”副本中,Kernighan & Ritchie(1988 年出版)。
相关摘录:
const
和volatile
属性是 ANSI 标准的新属性。的目的const
是宣布可能放置在只读内存中的对象,并可能增加优化的机会。
另外两个区别:
const arraytype
(即typedef int A[1]; const A a = { 0 };
)指定一个常量数组类型(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)在 C++ 中(并且其元素也是如此限定的),但它的元素在 C 中是如此限定的非常量数组类型。
const const
在 C99 中有效(在 C89 中无效),在任何版本的 C++ 中均无效(您只能在语义上重复 a const
,而不能在语法上重复)。const
它在 C99 中收缩。
是的。const
在 C 中,从 C89 开始。
这是一篇关于C 中 const 关键字行为的好读物。
C 中的语义与 C++ 中的不同。例如,
unsigned const a = 10;
unsigned A[a];
在文件范围内将在 C++ 中有效,但在 C 中无效。
是的,const
C 中有一个关键字。自 C90 以来就一直存在。
从语法上讲,它可以出现在与 C++ 相同的位置。从语义上讲,IIRC 有点松懈。
根据ESR,const
被添加到 ANSI C Draft Proposed Standard 中。 Eric Giguere在 1987 年对 ANSI C 的总结证实了这一点。
这看起来像草稿本身——搜索“3.5.3 Type qualifiers”。
C中有一个“const”关键字,已经很久了。如果变量被指定为“const”,则禁止对其进行写入。
此外,在某些环境中,声明为“const”的变量可能位于与其他变量不同的数据段中。该数据段可以提供硬件写保护,对于嵌入式系统,可以存储在 ROM 或闪存中而不是 RAM 中(对于某些 ROM 或闪存比 RAM 多得多的处理器来说,这是一个非常重要的区别,例如 128 KB 闪存和 3.5 KB RAM,或 2 KB ROM 和 96 字节 RAM)。
请注意,编译器通常不会对“const”值或涉及它们的表达式进行任何推断。如果我说 "const char foo[] = "Hello";" 然后稍后引用 foo[1],编译器将从存储 foo[] 的任何位置加载值(很可能是“e”)并使用加载的值。有时这有助于在编译的代码映像中修补值,但有时它只是浪费代码。
如果要将数字定义为编译时“可替换”常量,最好的方法,至少对于整数常量,可能是使用“枚举”。例如,“enum {woozle=19;}”将导致在整个代码中将 19 替换为“woozle”。请注意,与文本替换不同;枚举声明遵守适当的范围规则。