使用long double但不是double的未定义行为

时间:2014-01-26 22:17:02

标签: c++ c++11

通过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

见这里:

enter image description here

我觉得这里有些东西正好在我的头上。

1 个答案:

答案 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。