来自C in a Nutshell:
常量表达式
编译器识别源代码中的常量表达式 并用它们的值替换它们。由此产生的常数值 必须可以在表达式的类型中表示。你可以使用常数 表达式允许使用简单常量。
运营商 常量表达式与其他表达式的规则相同 表达式。因为常量表达式是在翻译时评估的 但是,时间不能包含函数调用或操作 修改变量,例如赋值。
什么是常量表达式?它没有定义常量表达式
常量表达式和不可修改的左值之间有什么区别(例如数组名称,已用const
声明的左值)
常量表达式总是非左值吗?
不可修改的左值是否为常量表达式?
答案 0 :(得分:6)
什么是常量表达式?
§6.6-常量表达式:
可以在转换期间而不是运行时期间计算常量表达式,因此可以在常量可以使用的任何位置使用。
常量表达式的一个约束是
常量表达式不应包含赋值,递增,递减,函数调用或逗号运算符,除非它们包含在未评估的子表达式中 115)。
常量表达式和不可修改的左值之间有什么区别?
不可修改的左值不是常量表达式。 不可修改的值是不能用于修改对象的左值。
int const i = 5;
i
指的是一个const对象,但它是一个左值,一种称为不可修改的左值的特殊左值。
无论标准说什么“左值”,它实际上意味着“可修改的左值”(你不会在标准中找到它但是为了清晰起见)
现在让我再解释一下。
int x = 5;
int const *p;
x
是一个非const对象,它是一个可修改的左值。 p
是指向const int
对象的指针。
p = &x; // This will raise a warning though and hazardous to do.
以上赋值使用限定转换将类型指针的值转换为int
,将值指向const int
。<登记/>
*p
和x
是指向同一对象的两个不同表达式。可以使用x
--x;
但是这不能使用*p
来完成,因为它是一个不可修改的左值。
--(*p); // Error
常量表达式和不可修改的左值之间的另一个区别是
int const x = 5;
int *p;
/* Assigning address of a non-modifiable object */
p = &x // Correct
/* Assigning address of a constant expression */
p = &5 // Wrong
常量表达式总是非左值吗?
是的,常量表达总是非左值,即rvalues。
是不可修改的左值常量表达式吗?
否强>
答案 1 :(得分:4)
常量表达式在C11 6.6:
中定义<强>描述强>
2。可以在转换期间而不是运行时期间评估常量表达式,并且因此可以在常量可以在任何地方使用。
约束
3常量表达式不应包含赋值,递增,递减,函数调用或comma operators,除非它们包含在未评估的子表达式中.15)
4每个常量表达式应计算为其类型的可表示值范围内的常量。
在某个地方可能允许使用几种类型的常量表达式。有一些常量表达式可以评估为
左值或定位器值(可能)指定对象。您可以获取左值的地址。可修改和不可修改的左值之间的区别在于后者不能用作赋值的左侧。或者,C11 6.3.2.1p1:
可修改的左值是一个左值,它没有数组类型,没有不完整的类型,没有const限定类型,如果是结构或联合,则没有任何成员(包括,递归) ,具有常量类型的所有包含聚合或联合的任何成员或元素。
不可修改的左值是一个不可修改的左值。
常量表达式只是...值。它们不存在于内存中 - 没有数字42的地址 - &42
毫无意义。
因此,常量表达式总是非左值。他们没有指定对象。您不能使用6 * 9
。
不,但......数组类型的左值隐式衰减为指向数组的指针,而这些是地址常量。然而,当它们被转换后,它们就不再是左值。
答案 2 :(得分:2)
我认为有多个复杂的问题,让我尝试以一种简单的方式回答它(主要通过从标准中明确地复制粘贴,只需创建一个反复的连接我自己的)。
1。什么是常量表达式?
C11
,章节§6.5,Expressions
,
表达式是一系列运算符和操作数,用于指定a的计算 值,或指定对象或功能,或产生副作用,或 执行它们的组合。
第6.6章,Constant expressions
常量表达式可以在翻译期间而不是运行时进行评估 因此可以在常数可能的任何地方使用。
和,P4
每个常量表达式应计算为可表示范围内的常量 其类型的值。
和Lvalues
,章节§6.3.2,
左值是一个表达式(对象类型不是void),可能 指定一个对象
,对于 对象 ,§3.15,
<强>对象强>
执行环境中的数据存储区域,其内容可以表示 值
一些常量表达式,例如数组(数组名称),字符串文字或地址常量,是左值。否则,对于整个范围的不可修改的左值,由常量对象(或对象引用)和常量表达式组成。
答案 3 :(得分:0)
常量表达式是在编译期间已知(可以评估)值的表达式
examaples
int a = 5+5+3; //5 + 5 +3
char []= "Hello"; // string literal "hello"
不可修改的左值是常数对象&amp;不断的经历
Exmaples
const char c;
c = '3';
'3' = c;
可修改的左值必须是可寻址的(即你可以使用&amp;获得它们的地址)并且可分配,即它们可以在赋值运算符的左侧。唯一的例外是没有地址的寄存器变量。