C++计算三个数LCM时添加std::cout<<""才可正常运行的原因是什么?
问题根因
你的程序异常和输出缓冲没有任何关系,核心问题是未初始化局部变量触发的未定义行为,所谓加输出语句就正常完全是巧合。
具体问题出在计算最大公约数的NWD函数上:
- 函数内定义了局部变量
int r但没有初始化,C++中栈上的局部变量不会被自动置0,初始值是对应内存地址的随机垃圾值。 - 你直接用未初始化的
r做while (r != 0)的循环判断:如果r的初始垃圾值刚好为0,循环不会执行,直接返回a的值,刚好符合最大公约数的逻辑;如果初始垃圾值不为0,就会进入完全错误的循环逻辑,最终得到错误结果甚至程序崩溃。 - 加上
std::cout << "";时,调用标准库输出函数会修改栈内存的临时数据,刚好把NWD函数中r对应的内存位置的值改写为0,刚好凑出了正确的执行结果,这是完全不可靠的偶发现象。去掉输出语句后r的初始垃圾值不为0,自然就会出现异常。
修复方案
首先修正NWD函数的逻辑,你用的更相减损术求最大公约数的写法存在逻辑漏洞,正确写法参考如下:
#include <iostream> // 更相减损术实现最大公约数 int NWD(int a, int b){ while (a != b){ if (a > b) a -= b; else b -= a; } return a; } int NWW(int a, int b){ // 调整计算顺序避免a*b溢出 return a / NWD(a,b) * b; } int NWW3(int a, int b, int c){ return NWW(c, NWW(a,b)); } int main() { std::cout << NWW3(1,7,9); return 0; }
额外说明:你原有main函数中的cout没有加std::命名空间前缀,也是不符合语法规范的问题,如果你不想每次写std::可以在头文件后加using namespace std;。
内容的提问来源于stack exchange,提问作者Arkadiusz Kuboszek
相关产品推荐
相关产品推荐

