这个问题可能很幼稚,但是:
- C 语言中有
const
关键字吗? - 从哪个版本开始存在?
- C 语言和 C++ 中的
const
在语义和/或语法上有什么不同吗?
这个问题可能很幼稚,但是:
const
关键字吗?const
在语义和/或语法上有什么不同吗?在涉及到const
关键字的情况下,C语言和C++语言之间没有语法差异,除了一个相当晦涩难懂的区别:在C语言中(从C99开始),你可以将函数参数声明为
void foo(int a[const]);
这相当于
void foo(int *const a);
声明。C ++不支持这种语法。
也存在语义差异。正如@Ben Voigt已经指出的,C中const
声明不会产生常量表达式,即在C中,您不能在case
标签中使用const int
对象,也不能作为非VLA数组声明中的位域宽度或数组大小(在C++中均可实现)。此外,在C中,默认情况下,const
对象具有外部链接(在C ++中具有内部链接)。
至少还有一个语义差异,Ben没有提到。 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修饰符,而不能更深层次。
int **pp = 0;
int *const *cpp = pp; /* OK in C */
int ***ppp = 0;
int **const *cppp = ppp; /* OK in C */
同一基本原则的另一个表现形式是C和C++中数组的const-correctness规则。在C++中,您可以执行以下操作:
int a[10];
const int (*p)[10] = &a; // OK in C++
int a[10];
const int (*p)[10] = &a; /* ERROR in C */
这里回答了前两个问题:C语言中的const
在C和C++中,const
的语义存在相当大的差异。
在C++中,适当类型的const
变量是整型常量表达式(如果它们的初始值是编译时常量表达式),可以在需要的上下文中使用,例如数组边界和枚举定义。在C中,它们不是并且不能成为。
在C++中,const
全局变量自动具有static
链接性,因此可以将它们放在头文件中。在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 };
)在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),其元素也被限定为常量,但在C中它是一个元素被限定为常量的非常量数组类型。
const const
在C99中是有效的(在C89中无效),但在任何版本的C++中都无效(您只能在语义上重复一个const
,而不是在语法上)。它在C99中缩小为const
。
unsigned const a = 10;
unsigned A[a];
C++中,文件作用域是有效的,但在C中不是。
是的,在C语言中,从C89开始就有const
关键字。
这里有一篇很好的文章,讲述了C语言中const
关键字的行为:behaviour of const keyword in C。
是的,C语言中有一个const
关键字。它从C90版本开始就存在了。
从语法上讲,它可以出现在与C++相同的位置。从语义上讲,它可能会更加宽松,如果我没记错的话。