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