C中的"常量表达式"是什么,不是什么?

Dav*_*her 10 c constant-expression

即使在经过多次Google搜索之后,我对C语言中的常量表达式有什么不同感到困惑.你能提供一个C的常量表达式的例子吗?

Car*_*rum 15

可以在编译时评估常量表达式.这意味着它没有变量.例如:

5 + 7 / 3
Run Code Online (Sandbox Code Playgroud)

是一个不变的表达.就像是:

5 + someNumber / 3
Run Code Online (Sandbox Code Playgroud)

不是,假设someNumber是一个变量(即,它本身不是编译时常量).

  • 但是,某些变量的*地址*允许使用常量表达式(具有静态存储持续时间的那些). (2认同)

RBe*_*eig 15

常量表达还有另一个微妙之处.编译器有一些已知的东西,但预处理器无法知道.

例如,(24*60*60)可以由两者计算,但sizeof struct foo仅为编译器所知.如果您要验证a struct是否已定义为满足外部规定的大小,或者其成员是否在外部指定的偏移处映射,则此区别可能很重要.(这种用例通常在编码设备驱动程序时出现,其中struct描述设备在内存空间中注册为布局.)

在那种情况下,您不能简单地说,#if (sizeof(struct UART) == 12)因为预处理器在编译之前的传递中操作,并且根本无法知道任何类型的大小.但是,它是一个常量表达式,可以作为全局变量的初始值设定项(例如int UARTwords = sizeof(struct UART) / sizeof(short);),或者声明数组的大小(例如unsigned char UARTmirror[sizeof(struct UART)];)


caf*_*caf 5

似乎没有人提到另一种常量表达式:地址常量。具有静态存储期的对象的地址是一个地址常量,因此您可以在文件范围内执行此类操作:

char x;
char *p = &x;
Run Code Online (Sandbox Code Playgroud)

字符串文字定义具有静态存储持续时间的数组,因此此规则也是您可以在文件范围内执行此操作的原因:

char *s = "foobar";
Run Code Online (Sandbox Code Playgroud)