输入a=2时C++幂运算程序输出全为16,求技术原因
为什么输入2时,这段C++代码输出三个16?
我写了一段简单的C++程序,用来输出输入数字的2次、3次和4次幂:
int a = 0; cin >> a; int a2 = a * a; cout << "\n" << a2 << "\n" << (a2 *= a) << "\n" << (a2 *= a) << "\n"; return 0;
当输入a=2时,程序的输出结果是:
16 16 16
有人能解释这个现象吗?
这问题出在C++中cout的<<操作符的表达式求值顺序是未定义行为上。
你写的这条输出语句:
cout << "\n" << a2 << "\n" << (a2 *= a) << "\n" << (a2 *= a) << "\n";
C++标准并没有规定这些<<操作数的求值顺序——编译器可以选择从左到右、从右到左,或者其他任意顺序来计算每个操作数的值。
在你的情况里,编译器是先从右往左计算所有操作数:
- 最右边的
(a2 *= a):此时a2初始是4(2*2),乘2后变成8; - 接着是中间的
(a2 *= a):a2现在是8,再乘2变成16; - 最后才计算最左边的
a2,此时a2已经是16了。
所以三个输出的都是最终修改后的a2值16,这就导致了看起来不符合预期的结果。
怎么修复?
要避免这种未定义行为,别在同一条输出语句里既修改变量又读取它。分开写或者提前计算好各个幂值就行:
方法一:提前计算所有值
int a = 0; cin >> a; int a2 = a * a; int a3 = a2 * a; int a4 = a3 * a; cout << "\n" << a2 << "\n" << a3 << "\n" << a4 << "\n"; return 0;
方法二:拆分输出语句
int a = 0; cin >> a; int a2 = a * a; cout << "\n" << a2 << "\n"; a2 *= a; cout << a2 << "\n"; a2 *= a; cout << a2 << "\n"; return 0;
这样无论编译器怎么处理求值顺序,结果都是正确的:输入2时会输出4、8、16。
内容的提问来源于stack exchange,提问作者Ali Kamel Ali
相关产品推荐
相关产品推荐

