C中的“常量表达式”是什么,而不是什么?
即使在经过多次Google搜索之后,我对C语言中的常量表达式与之间的混淆感有点混淆。 你能提供一个C的常量表达式的例子吗?
可以在编译时评估常量表达式。 这意味着它没有变量。 例如:
5 + 7 / 3
是一个不变的表达。 就像是:
5 + someNumber / 3
假设someNumber
是一个变量(即,它本身不是编译时常量)。
常量表达还有另一个微妙之处。 编译器有一些已知的东西,但预处理器无法知道。
例如, (24*60*60)
可以由两者计算,但sizeof struct foo
仅为编译器所知。 如果您尝试validationstruct
是否已定义为满足外部强制大小,或者其成员是否在外部指定的偏移处映射,则此区别可能很重要。 (这种用例通常在编码设备驱动程序时出现,其中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 ++中是可以接受的:
enum {foo = 19,bar,boz = bar + 5;};
它可以被重写:
enum {foo = 19,bar}; enum {boz = bar + 5;};
虽然这最终会定义多个不同的枚举类型,而不是一个包含所有值的枚举类型。
另外,作为'a'
或'\n'
integral character constants
是编译器识别的常量。 他们有int
类型。