通过C ++ Primer Plus。我正在为第5章的练习做准备。让我先介绍一下我正在进行的第二次练习:
重做清单5.4使用类型数组对象而不是内置数组 并输入long double而不是long long。找到100的值! (阶乘)
有问题的列表:
// formore -- more looping with for
#include <iostream>
int main()
{
const int aSize = 100;
long long factorials[aSize];
factorials[1] = factorials[0] = 1LL;
for (int i = 2; i < aSize; ++i)
factorials[i] = i * factorials[i-1];
for (int i = 0; i < aSize; ++i)
std::cout << i << "! = " << factorials[i] << std::endl;
return 0;
}
我按照练习说明重写了代码,并提供了以下内容:
// redo listing 5.4 using long double and arrays instead - find value of 100!
#include <iostream>
#include <array>
int main()
{
int const ArSize = 100;
std::array<long double, ArSize> factorials = {1.0L, 1.0L};
for (int i = 2; i <= ArSize; ++i)
factorials[i] = i * factorials[i-1];
for (int i = 0; i <= ArSize; ++i)
std::cout << i << "! = " << factorials[i] << std::endl;
return 0;
}
当我尝试运行此代码时,我得到了未定义的行为。我很确定它与我正在使用的long double类型有关,因为当我将factorial切换为double类型时,程序运行正常。究竟是什么造成了这个?
我很抱歉,如果我问一个明显的问题,它试图谷歌练习,但大多数人似乎跳过它,只是做练习三而不是......
修改
将ArSize更改为:
const int ArSize = 101;
For循环:
for (int i = 2; i < ArSize; ++i)
factorials[i] = i * factorials[i-1];
for (int i = 0; i < ArSize; ++i)
std::cout << i << "! = " << factorials[i] << std::endl;
我还在接受UB;阶乘[0]到阶乘[3]显示为neg。 0
见这里:
我觉得这里有些东西正好在我的头上。
答案 0 :(得分:7)
你在这里分配越界:
for (int i = 2; i <= ArSize; ++i)
factorials[i] = i * factorials[i-1];
在这里:
for (int i = 0; i <= ArSize; ++i)
std::cout << i << "! = " << factorials[i] << std::endl;
那就是UB。 解决方案:不要超出界限访问数组。
注意:它与double或std::array
无关。你改变了循环条件,引入了一个bug。