C中的文字和常量是相同的概念吗?

时间:2012-07-31 03:48:49

标签: c

C中的文字和常量是相同的概念吗? 使用它们之间有什么区别吗?

3 个答案:

答案 0 :(得分:11)

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

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

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

同样,由于C中的文字是左值,你可以使用和使用它们的地址

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

由于常量是右值,因此无法获取其地址。

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

P.S。请注意,C中的相关术语与C ++的术语完全不同。在C ++中,术语 literal 实际上涵盖了C中已知的大多数常量。在C ++ const对象中可以形成常量表达式。人们有时会试图将C ++术语强加给C,这通常会导致混淆。

(另见Shall I prefer constants over defines?

答案 1 :(得分:5)

C标准(特别是ISO / IEC 9899,第二版,1999-12-01)本身并没有定义“文字”,所以这不是C的特定概念。我发现“文字”的三种用法,如下所述。

首先,字符串文字(或形式语法中的“字符串 - 字面”)是引号内的字符序列,可选地以“L”为前缀(使其成为宽字符串文字)。毫无疑问,这称为文字,因为字符串中的每个字符都代表自己:源文本中的“b”在字符串中产生“b”。 (相反,源文本中的字符“34”作为数字而不是字符串,导致程序中的值34,而不是字符“3”和“4”。)这些文字的语义在6.4.5的第4和第5段。本质上,相邻的文字被连接("abc" "def"被制成"abcdef"),附加零字节,结果用于初始化静态存储持续时间的数组。所以字符串文字会产生一个对象。

其次,复合文字是用于为结构创建值的更复杂的构造。 “复合文字”是一个不幸的名字,因为它根本不是文字。也就是说,文字源文本中的字符不一定代表它们自己。实际上,复合文字甚至不是常数。复合文字可以包含在运行时计算的表达式,包括函数调用!

第三,在6.1第1段中,标准表示“字面词和字符集成员”用粗体表示。这种“文字”的使用是描述标准本身而不是用C语言描述事物;这意味着标准中的“ goto ”表示C语言中的字符串“goto”。

除了字符串文字,我不认为“文字”是C中的特定概念。

然而,“常数”是一个重要的概念。

首先,有一些简单的常量,例如“34”,“4.5f”和“'b'”。后者是一个字符常数;虽然用字符书写,但它有一个整数值。常量包括整数常量(十进制,八进制和十六进制),浮点常量(十进制和十六进制),字符常量和枚举常量。枚举常量是“enum”构造中指定的名称。

其次,有一些常量表达式,在6.6中定义。可以在转换(编译时)而不是运行时评估常量表达式,并且可以在常量可以使用的任何位置使用。 6.6为常量表达式设置了某些规则。例如,如果x是静态数组,由static int x[8];声明,则&x[(int) (6.8 * .5)]是常量表达式:它是x的元素3的地址。 (您很少使用浮点索引数组,但我在示例中包含它以显示它是允许作为常量表达式的一部分。)

关于“const”:标准似乎没有将const限定对象专门定义为常量。相反,它表示尝试通过具有非const限定类型的左值(例如解除引用的指针)修改使用const限定类型定义的对象,行为是未定义的。这意味着不需要C实现来强制const对象的常量。 (另外,请注意,指向const的指针并不意味着指向对象是const,只是解除引用的指针不是可修改的左值。可能有一个指向同一对象的单独指针,它不是const限定的例如,在int i; int *p = &i; const int *q = p;中,q是指向const-int的指针,但我不是const对象,而p是指向同一个int的指针,尽管它是指向int的指针,没有const 。)

答案 2 :(得分:1)

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

编辑:对不起大家,似乎我错了。