即使经过多次谷歌搜索,我对什么是 C 中的常量表达式和不是 C 中的常量表达式有点困惑。您能否提供一个示例,说明哪些是 C 中的常量表达式,哪些不是?
6 回答
可以在编译时计算常量表达式。这意味着它没有变量。例如:
5 + 7 / 3
是一个常数表达式。就像是:
5 + someNumber / 3
不是,假设someNumber
是一个变量(即,它本身不是编译时常量)。
常量表达式还有另一个微妙之处。有些东西编译器知道,但预处理器不知道。
例如(24*60*60)
,两者都可以计算,但sizeof struct foo
只有编译器知道。如果您尝试验证 astruct
是否定义为满足外部要求的大小,或者其成员是否映射到外部指定的偏移量,则此区别可能很重要。(这种用例经常出现在编写设备驱动程序时,其中struct
描述的设备寄存器布置在内存空间中。)
在那种情况下,您不能简单地说#if (sizeof(struct UART) == 12)
因为预处理器在编译之前运行,并且根本无法知道任何类型的大小。然而,它是一个常量表达式,可以作为全局变量的初始值设定项(例如int UARTwords = sizeof(struct UART) / sizeof(short);
),或声明数组的大小(例如unsigned char UARTmirror[sizeof(struct UART)];
)
似乎没有人提到另一种常量表达式:地址常量。具有静态存储持续时间的对象的地址是一个地址常量,因此您可以在文件范围内执行此类操作:
char x;
char *p = &x;
字符串字面量定义具有静态存储持续时间的数组,因此这条规则也是您可以在文件范围内执行此操作的原因:
char *s = "foobar";
任何单值文字都是常量表达式。
3 0.0f '\n'
(字符串文字很奇怪,因为它们实际上是数组。似乎"hello"
并不是一个真正的常量,因为它最终必须被链接等等,并且地址和内容可以在运行时改变。)
大多数应用于常量或类型的运算符(sizeof、casts 等)都是常量表达式。
sizeof(char)
(byte) 15
任何只涉及常量表达式的表达式本身也是一个常量表达式。
15 + 3
0.0f + 0.0f
sizeof(char)
任何涉及函数调用或非常量表达式的表达式通常都不是常量表达式。
strlen("hello")
fifteen + x
任何宏作为常量表达式的状态取决于它扩展为什么。
/* Always a constant */
#define FIFTEEN 15
/* Only constant if (x) is
#define htons(x) (( ((x) >> 8) | ((x) << 8) ) & 0xffff)
/* Never constant */
#define X_LENGTH strlen(x)
我最初在这里有一些关于const
标识符的东西,但我对此进行了测试,显然它不适用于 C. const
,奇怪的是,它没有声明常量(至少,不是那些足以在switch
语句中使用的“常量”)。然而,在 C++ 中,它确实如此。
另一个有趣的小问题:在 C 中,“enum”的值是一个常量,但只能在“enum”声明完成后使用。例如,以下内容在标准 C 中是不可接受的,但在 C++ 中是可以接受的:
枚举 {foo=19, bar, boz=bar+5;};
可以重写:
枚举 {foo=19, bar}; 枚举 {boz=bar+5;};
尽管这最终会定义多种不同的枚举类型,而不是包含所有值的枚举类型。
也integral character constants
作为'a'
或'\n'
是编译器识别的常量。他们有类型int
。