关于面试题中C程序输出结果为30的原因咨询
解析这段C程序的输出:为什么最终会得到30?
首先,咱们先把你给出的代码贴出来,方便对照:
#include<stdio.h> #define x 9+2/4*3-2*4+(5-4)*3 void main() { int i,y,p; y=6+3*3/5; printf("%d",x); i=x*x+y; printf("%d",i); }
你提到的输出结果30,其实是程序第二个printf的输出——第一个printf会输出4,问题的核心在于宏定义的文本替换规则,这也是很多C初学者容易踩的坑。咱们一步一步拆解计算过程:
1. 先计算变量y的值
y=6+3*3/5,C语言中运算符优先级是先乘除后加减,而且整数除法会直接舍去小数部分:
- 先算
3*3=9 - 再算
9/5=1(整数除法只保留整数部分) - 最后
6+1=7,所以y=7
2. 计算第一个printf的输出(即单独x的值)
宏定义#define x 9+2/4*3-2*4+(5-4)*3是纯文本替换,不是先计算好x的值再代入,但单独计算x的表达式时,按照优先级来:
- 先处理括号:
(5-4)=1 - 再处理乘除:
2/4=0(整数除法),然后0*3=02*4=81*3=3
- 最后处理加减:
9 + 0 -8 +3 = 4
所以第一个printf会输出4。
3. 计算i=x*x+y的值(重点!这里是坑)
很多人会误以为x*x是4*4=16,但宏是文本替换,不是预计算值!所以x*x会被直接替换成:
9+2/4*3-2*4+(5-4)*3*9+2/4*3-2*4+(5-4)*3
注意:这里没有括号包裹x的表达式,导致(5-4)*3后面直接跟了*9,乘法优先级高于加减,所以这部分会先计算!
现在分步计算这个展开后的表达式:
- 先处理所有括号和乘除:
(5-4)=12/4*3=0*3=0(两处都是这个结果)2*4=8(两处都是这个结果)1*3*9=27(这是最关键的部分:因为乘法优先级高,(5-4)*3*9会从左到右计算,得到27)
- 把这些值代入后,表达式变成:
9 + 0 -8 +27 +0 -8 +3 - 计算加减:
9-8=1→1+27=28→28-8=20→20+3=23 - 最后加上
y=7:23+7=30
所以第二个printf会输出30,这就是你看到的结果。
总结一下
这个问题的核心是宏定义的文本替换特性:如果你希望x作为一个整体参与运算,一定要给宏的表达式加上括号,比如改成#define x (9+2/4*3-2*4+(5-4)*3),这样x*x就会被替换成(x表达式)*(x表达式),计算结果就是4*4+7=23,避免了优先级导致的错误。
内容的提问来源于stack exchange,提问作者Shahed al mamun




