5

C中的文字和常量是同一个概念吗?它们在使用上有什么区别吗?

4

3 回答 3

11

字面量和常量在 C 中是显着不同的东西。可以说,C 中的字面量一词代表占用内存的未命名对象(字面量通常是左值),而术语常量代表(可能命名的)不一定占用内存的值内存(常量是右值)。

“经典”C (C89/90) 只有一种文字:字符串文字。C 中没有其他类型的文字。C99 还引入了所谓的复合文字

同时,术语常量指的是显式值,例如12.5f和。此外,枚举成员也被识别为C中的常量。0xA's'

同样,由于 C 中的文字是左值,因此您可以获取并使用它们的地址

const char *s = "Hello";
char (*p)[6] = &"World";
int (*a)[4] = &(int []) { 1, 2, 3, 4 };

由于常量是右值,因此您不能获取它们的地址。

用关键字声明的对象在 C 术语const中不被视为常量。它们不能用于需要常量值的地方(例如大小写标签、位域宽度或全局、静态变量初始化)。

PS 请注意,C 中的相关术语与 C++ 中的术语有很大不同。在 C++ 中,字面量一词实际上涵盖了 C 中称为常量的大部分内容。而在 C++ 中,const对象可以形成常量表达式。人们有时试图将 C++ 术语强加到 C 上,这通常会导致混淆。

(另请参阅我更喜欢常量而不是定义吗?

于 2012-07-31T04:07:16.367 回答
5

The C standard (specifically ISO/IEC 9899, Second edition, 1999-12-01) does not define “literal” by itself, so this is not a specific concept for C. I find three uses of “literal”, described below.

First, a string literal (or “string-literal” in the formal grammar) is a sequence of characters inside quotation marks, optionally prefixed with an “L” (which makes it a wide string literal). This is undoubtedly called a literal because each character in the string stands for itself: A ”b” in the source text results in a “b” in the string. (In contrast the characters “34” in the source text as a number, not a string, result in the value 34 in the program, not in the characters “3” and “4”.) The semantics of these literals are defined in paragraphs 4 and 5 of 6.4.5. Essentially, adjacent literals are concatened ("abc" "def" is made into "abcdef"), a zero byte is appended, and the result is used to initialize an array of static storage duration. So a string literal results in an object.

Second, a compound literal is a more complicated construct used to create values for structures. “Compound literal” is an unfortunate name, because it is not a literal at all. That is, the characters in the source text of the literal do not necessarily stand for exactly themselves. In fact, a compound literal is not even a constant. A compound literal can contain expressions that are evaluated at run-time, including function calls!

Third, in 6.1 paragraph 1, the standard indicates that “literal words and character set members” are indicated by bold type. This use of “literal” is describing the standard itself rather than describing things within the C language; it means that “<strong>goto” in the standard means the string “goto” in the C language.

Aside from string literals, I do not think “literal” is a particular concept in C.

”Constant”, however, is a significant concept.

First, there are simple constants, such as “34”, “4.5f”, and “'b'”. The latter is a character constant; although written with a character, it has an integer value. Constants include integer constants (in decimal, octal, and hexadecimal), floating constants (in decimal and hexadecimal), character constants, and enumeration constants. Enumeration constants are names specified in “enum” constructs.

Second, there are constant expressions, defined in 6.6. A constant expression can be evaluated during translation (compile time) rather than run time and may be used any place that a constant may be. 6.6 sets certain rules for constant expressions. As an example, if x is a static array, as declared by static int x[8];, then &x[(int) (6.8 * .5)] is a constant expression: It is the address of element 3 of x. (You would rarely using floating-point to index arrays, but I include it in the example to show it is allowed as part of a constant expression.)

Regarding “const”: The standard does not appear to specifically define a const-qualified object as constant. Rather, it says that attempting to modify an object defined with a const-qualified type through an lvalue (such as a dereferenced pointer) with non-const-qualified type, the behavior is undefined. This implies a C implementation is not required to enforce the constantness of const objects. (Also, note that having a pointer-to-const does not imply the pointed-to object is const, just that the dereferenced pointer is not a modifiable lvalue. There could be a separate pointer to the same object that is not const-qualified. For example, in int i; int *p = &i; const int *q = p;, q is a pointer-to-const-int, but i is not a const object, and p is a pointer to the same int although it is pointer-to-int, without const.)

于 2012-07-31T09:13:53.027 回答
1

不完全的。常量变量(与宏中定义的常量相反)是具有专用存储空间的实际变量,因此您可以获取它们的地址。您不能获取文字的地址。

编辑:对不起大家,看来我错了。

于 2012-07-31T03:58:52.080 回答