C中有const吗?

发布于 2024-10-20 19:46:36 字数 132 浏览 2 评论 0原文

这个问题可能很幼稚,但是:

  • C 中有 const 关键字吗?
  • 从哪个版本开始?
  • C 和 C++ 中的 const 之间有语义和/或语法差异吗?

This question may be naive, but:

  • is there const keyword in C?
  • since which version?
  • are there any semantic and/or syntactic differences between const in C and C++?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

幽梦紫曦~ 2024-10-27 19:46:36

关于 const 关键字,C 和 C++ 之间没有语法差异,除了一个相当晦涩的差异:在 C 中(自 C99 起),您可以声明函数参数,

void foo(int a[const]);

这相当于

void foo(int *const a);

声明。 C++ 不支持这样的语法。

语义差异也存在。正如 @Ben Voigt 已经指出的,在 C const 声明中不会产生常量表达式,即在 C 中,你不能在 case< 中使用 const int 对象。 /code> 标签,作为位字段宽度或作为非 VLA 数组声明中的数组大小(所有这些在 C++ 中都是可能的)。另外,const 对象在 C 中默认具有外部链接(在 C++ 中具有内部链接)。

至少还有一个语义差异,本没有提及。 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限定,只要您还添加const-qualification 一直到顶层。

在 C 中,只能将 const 限定添加到顶级指针指向的类型,但不能添加更深的类型。

int **pp = 0;
int *const *cpp = pp; /* OK in C */

int ***ppp = 0;
int **const *cppp = ppp; /* OK in C */

同一基本一般原则的另一个体现是常量正确性规则在 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 */

There are no syntactic differences between C and C++ with regard to const keyword, besides a rather obscure one: in C (since C99) you can declare function parameters as

void foo(int a[const]);

which is equivalent to

void foo(int *const a);

declaration. C++ does not support such syntax.

Semantic differences exist as well. As @Ben Voigt already noted, in C const declarations do not produce constant expressions, i.e. in C you can't use a const int object in a case label, as a bit-field width or as array size in a non-VLA array declaration (all this is possible in C++). Also, const objects have external linkage by default in C (internal linkage in C++).

There's at least one more semantic difference, which Ben did not mention. Const-correctness rules of C++ language support the following standard conversion

int **pp = 0;
const int *const *cpp = pp; // OK in C++

int ***ppp = 0;
int *const *const *cppp = ppp; // OK in C++

These initializations are illegal in C.

int **pp = 0;
const int *const *cpp = pp; /* ERROR in C */

int ***ppp = 0;
int *const *const *cppp = ppp; /* ERROR in C */

Generally, when dealing with multi-level pointers, C++ says that you can add const-qualification at any depth of indirection, as long as you also add const-qualification all the way to the top level.

In C you can only add const-qualification to the type pointed by the top-level pointer, but no deeper.

int **pp = 0;
int *const *cpp = pp; /* OK in C */

int ***ppp = 0;
int **const *cppp = ppp; /* OK in C */

Another manifestation of the same underlying general principle is the way const-correctness rules work with arrays in C and C++. In C++ you can do

int a[10];
const int (*p)[10] = &a; // OK in C++

Trying to do the same in C will result in an error

int a[10];
const int (*p)[10] = &a; /* ERROR in C */
素染倾城色 2024-10-27 19:46:36

前两个问题在这里得到解答: C 中的 Const

是的,< 之间的语义有相当多的差异。 C 和 C++ 中的 code>const。

  • 在 C++ 中,适当类型的 const 变量是积分常量表达式(如果它们的初始化器是编译时常量表达式),并且可以在需要的上下文中使用,例如数组边界和枚举定义。在 C 中,它们不是也不可能。

  • 在 C++ 中,const 全局变量自动具有 static 链接,因此您可以将它们放入头文件中。在 C 中,此类变量具有外部链接,这会在链接时生成重复定义错误。

The first two questions are answered here: Const in C

Yes there are quite a few differences in semantics between const in C and C++.

  • In C++, const variables of appropriate type are integral constant expressions (if their initializers are compile-time constant expressions) and can be used in context which requires that, such as array bounds, and in enum definitions. In C, they are not and cannot be.

  • In C++, const global variables automatically have static linkage, so you can put them in header files. In C, such variables have external linkage and that would generate duplicate definition errors at link time.

囍笑 2024-10-27 19:46:36

是的,有一个 const 关键字。它是作为 1989 年标准的一部分添加的。

至于兼容性,这是 Harbison & 的一段话。斯蒂尔,第五版:

具有类型限定符 const 但没有显式存储类的顶级声明在 C++ 中被视为 static,但在 C 中被视为 extern。保持兼容,检查顶级 const 声明并提供显式存储类。

在 C++ 中,字符串常量是隐式 const 的;他们不在C中。

Yes, there is a const keyword. It was added as part of the 1989 standard.

As far as compatibility, here's a paragraph from Harbison & Steele, 5th edition:

A top-level declaration that has the type qualifier const but no explicit storage class is considered to be static in C++ but extern in C. To remain compatible, examine top-level const declarations and provide an explicit storage class.

In C++, string constants are implicitly const; they are not in C.

绝對不後悔。 2024-10-27 19:46:36

是的,const 至少从 ANSI C(又名 C89)开始就已经存在了。

它肯定出现在我的“C 编程语言(第二版)”,Kernighan &里奇(1988 年出版)。

相关摘录:

constvolatile 属性是 ANSI 标准中的新属性。 const 的目的是
宣布可能被放置在只读内存中的对象,并且可能增加
优化。

Yes, const has been there since at least since ANSI C (aka C89).

It certainly appears in my copy of "The C Programming Language (2nd Edition)", Kernighan & Ritchie (published in 1988).

Relevant extract:

The const and volatile properties are new with the ANSI standard. The purpose of const is to
announce objects that may be placed in read-only memory, and perhaps to increase opportunities for
optimization.

深海夜未眠 2024-10-27 19:46:36

另外两个区别:

Two other differences:

铁憨憨 2024-10-27 19:46:36

是的。 const 存在于 C 中,从 C89 开始。

这是关于C 中 const 关键字的行为的好读物。

Yes. const is there in C, from C89.

Here is a good read is about behaviour of const keyword in C.

陪你搞怪i 2024-10-27 19:46:36

C 中的语义与 C++ 中的语义不同。例如,

unsigned const a = 10;
unsigned A[a];

in file 作用域在 C++ 中有效,但在 C 中无效。

The semantic in C is different than in C++. For example,

unsigned const a = 10;
unsigned A[a];

in file scope would be valid in C++, but not in C.

你げ笑在眉眼 2024-10-27 19:46:36

是的,C 中有一个 const 关键字。它从 C90 起就存在了。

从语法上讲,它可以出现在与 C++ 中相同的位置。从语义上讲,它有点宽松,IIRC。

Yes, there's a const keyword in C. It's been there since C90.

Syntactically, it can occur in the same places as in C++. Semantically, it's a bit more lax, IIRC.

瑕疵 2024-10-27 19:46:36

根据 ESR,在ANSI C 拟议标准草案。 Eric Giguere 1987 年对 ANSI C 的总结证实了这一点。

这看起来像草案本身 - 搜索“3.5.3 类型限定符” ”。

According to ESR, const was added in the ANSI C Draft Proposed Standard. Eric Giguere's summary of ANSI C, dated 1987, confirms it.

This looks like the draft itself -- search for "3.5.3 Type qualifiers".

云淡风轻 2024-10-27 19:46:36

C 中有一个“const”关键字,并且它已经存在了很长时间了。如果变量被指定为“const”,则禁止对其进行写入。

另外,在某些环境中,声明为“const”的变量可能位于与其他变量不同的数据段中。该数据段可以提供硬件写保护,对于嵌入式系统,可以存储在 ROM 或闪存中,而不是 RAM 中(对于某些具有比 RAM 更多 ROM 或闪存的处理器来说,这是一个非常重要的区别,例如 128 KB 闪存)和 3.5 KB RAM,或 2 KB ROM 和 96 字节 RAM)。

请注意,编译器通常不会对“const”值或涉及它们的表达式进行任何推断。如果我说“const char foo[] =“Hello”;”然后稍后引用 foo[1],编译器将从存储 foo[] 的位置加载该值(很可能是“e”)并使用加载的值。有时,这允许在编译的代码映像中修补值,但有时它只是浪费代码。

如果要将数字定义为编译时“可替代”常量,最好的方法(至少对于整数常量)可能是使用“enum”。例如,“enum {woozle=19;}”将导致整个代码中的“woozle”被 19 替换。请注意,与文本替换不同;枚举声明遵循适当的范围规则。

There is a "const" keyword in C, and it has been for a long time. If a variable is designated "const", writes to it are forbidden.

Additionally, in some environments, variables declared "const" may be located in a different data segment from other variables. This data segment may offer hardware write protection, and for embedded systems, may be stored in ROM or flash memory rather than in RAM (a very important distinction on some processors which have a lot more ROM or flash than RAM--e.g. 128 KB flash and 3.5 KB RAM, or 2 KB ROM and 96 bytes RAM).

Note that the compiler will generally not make any inferences about "const" values or expressions involving them. If I say "const char foo[] = "Hello";" and then later make reference to foo[1], the compiler will load the value (which will most likely be 'e') from wherever foo[] is stored and use the loaded value. Sometimes this usefully allows values to be patched in a compiled code image, but sometimes it just wastes code.

If you want to define a number to to be a compile-time "substitutable" constant, the best way, at least for integer constants, may be to use "enum". For example, "enum {woozle=19;}" will cause 19 to be substituted for "woozle" throughout the code. Note that unlike textual substitutions; enum declarations obey proper rules of scope.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文