C语言中int a = a = 1;多重赋值编译通过的原因及标准问询
为啥
int a = a = 1;能编译还输出1? 哈哈,这个写法看起来有点反直觉,但完全符合C标准的规则,咱们一步步说清楚:
首先,a在初始化器里是合法可见的
你可能觉得“变量得先声明再用”,但C标准对自动存储期(就是没加static的局部变量)的变量有个特殊规定:这类变量的作用域包含它自己的初始化器。也就是说,当你写int a = ...;的时候,等号后面的初始化代码里,a已经是“可用”的标识符了——它的声明在初始化器之前就已经完成了作用域的生效,所以这里引用a并不违反“先声明后使用”的要求。
然后看赋值表达式的执行逻辑
赋值运算符=是右结合的,简单说就是括号会加在右边,所以a = a = 1等价于:
a = (a = 1);
咱们拆解这个过程:
- 先算括号里的
a = 1:把1赋值给a,这个赋值表达式的结果就是赋值后a的值(也就是1)。 - 再把这个结果(1)赋值给
a——这一步其实没改变a的值,但语法完全合规。
这里要区分开和int a = a;的区别:后者是直接拿未初始化的a的值来初始化自己,属于未定义行为(结果随机);但你的代码里,a在被用作右值之前,已经通过a = 1完成了赋值,相当于提前给a塞了个确定的值,所以整个过程的行为是明确的。
对应的C标准条款支撑
- 作用域相关:C标准明确,自动存储期的变量,其作用域覆盖自身的初始化器(C17 §6.2.1/7 和 §6.7.9/10)——简单说就是初始化器里能合法用这个变量的名字。
- 赋值运算相关:赋值运算符是右结合的,且赋值表达式的结果是左操作数赋值后的值(C17 §6.5.16/3),这保证了
a = a =1会按从右到左的顺序执行赋值。
所以这段代码能正常编译,运行后输出1就完全合理啦。
内容的提问来源于stack exchange,提问作者akjlab
相关产品推荐
相关产品推荐

