C中的某些示例,也不是C中的“恒定表达”?
-
04-10-2019 - |
题
即使经过大量的谷歌,我也不是在C中的不变表达式感到困惑。您能提供一个示例,说明C中的某些内容,而不是C中的恒定表达式?
解决方案
可以在编译时评估恒定表达式。这意味着它没有变量。例如:
5 + 7 / 3
是恒定的表达。就像是:
5 + someNumber / 3
不是,假设 someNumber
是一个变量(即,不是编译时常数)。
其他提示
恒定表达式还有另一个微妙的。编译器已知有些事情,但预处理器不知道。
例如 (24*60*60)
可以通过两者计算,但是 sizeof struct foo
仅对编译器知道。如果您试图验证一个 struct
被定义为满足外部强制性的规模,或者其成员在外部指定的偏移量上映射。 (在编码设备驱动程序的情况下,通常会出现此用例 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(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中,“枚举”的价值是一个常数,但只有在“枚举”声明完成后才可以使用。例如,在标准C中不可接受以下内容,尽管C ++可以接受:
enum {foo=19, bar, boz=bar+5;};
它可以重写:
enum {foo=19, bar}; enum {boz=bar+5;};
尽管这最终将定义多个不同的枚举类型,而不是一种持有所有值的枚举类型。
还 integral character constants
作为 'a'
或者 '\n'
是编译器认可的常数。他们有类型 int
.