程序仅适用于包含(无副作用)cout语句的情况吗?

时间:2018-08-04 03:12:03

标签: c++ cout pascals-triangle

因此,我一直在研究problem 15 from the Project Euler's website,直到我决定在编写代码时删除我正在使用的cout语句之前,我的解决方案一直有效。我的解决方案通过在1D数组中生成Pascal三角形并找到与用户指定的NxN晶格中的路径数相对应的元素来工作。这是我的程序:

#include <iostream>
using namespace std;

//Returns sum of first n natural numbers
int sumOfNaturals(const int n)
{
    int sum = 0;
    for (int i = 0; i <= n; i++)
    {
        sum += i;
    }
    return sum;
}

void latticePascal(const int x, const int y, int &size)
{
    int numRows = 0;
    int sum = sumOfNaturals(x + y + 1);
    numRows = x + y + 1;

    //Create array of size (sum of first x + y + 1 natural numbers) to hold all elements in P's T
    unsigned long long *pascalsTriangle = new unsigned long long[sum];
    size = sum;

    //Initialize all elements to 0
    for (int i = 0; i < sum; i++)
    {
        pascalsTriangle[i] = 0;
    }
    //Initialize top of P's T to 1
    pascalsTriangle[0] = 1;
    cout << "row 1:\n" << "pascalsTriangle[0] = " << 1 << "\n\n";  // <--------------------------------------------------------------------------------

    //Iterate once for each row of P's T that is going to be generated
    for (int i = 1; i <= numRows; i++)
    {
        int counter = 0;
        //Initialize end of current row of P's T to 1
        pascalsTriangle[sumOfNaturals(i + 1) - 1] = 1;
        cout << "row " << i + 1 << endl;   // <--------------------------------------------------------------------------------------------------------

        //Iterate once for each element of current row of P's T
        for (int j = sumOfNaturals(i); j < sumOfNaturals(i + 1); j++)
        {
            //Current element of P's T is not one of the row's ending 1s
            if (j != sumOfNaturals(i) && j != (sumOfNaturals(i + 1)) - 1)
            {
                pascalsTriangle[j] = pascalsTriangle[sumOfNaturals(i - 1) + counter] + pascalsTriangle[sumOfNaturals(i - 1) + counter + 1];
                cout << "pascalsTriangle[" << j << "] = " << pascalsTriangle[j] << '\n';   // <--------------------------------------------------------
                counter++;
            }
            //Current element of P's T is one of the row's ending 1s
            else
            {
                pascalsTriangle[j] = 1;
                cout << "pascalsTriangle[" << j << "] = " << pascalsTriangle[j] << '\n';  // <---------------------------------------------------------
            }
        }
        cout << endl;
    }

    cout << "Number of SE paths in a " << x << "x" << y << " lattice: " << pascalsTriangle[sumOfNaturals(x + y) + (((sumOfNaturals(x + y + 1) - 1) - sumOfNaturals(x + y)) / 2)] << endl;
    delete[] pascalsTriangle;
    return;
}

int main()
{
    int size = 0, dim1 = 0, dim2 = 0;

    cout << "Enter dimension 1 for lattice grid: ";
    cin >> dim1;
    cout << "Enter dimension 2 for lattice grid: ";
    cin >> dim2;
    latticePascal(dim1, dim2, size);

    return 0;
}

似乎正在保存程序的cout语句用带注释的箭头标记。只要包含这些行中的任何,它似乎就可以工作。 如果所有这些语句都被删除,则程序将打印:“ 中的SE路径数,然后挂起几秒钟,然后终止且不终止打印答案。我希望该程序尽可能简洁,并且只需输出答案而不必打印三角形的全部内容,因此它在当前状态下无法按预期工作。

2 个答案:

答案 0 :(得分:1)

很有可能,用于计算数组索引的表达式或用于分配的数组大小的表达式都会导致不确定的行为,例如堆栈溢出。

由于未定义此未定义行为的可见性,因此程序可以按预期工作或可以执行其他操作-可以解释为什么它只能与一个编译器一起使用,而不能与另一个编译器一起使用。

在程序在写入或刷新其所有内容之前中止的情况下,可以使用带有vector :: resize()和vector :: at()的vector代替带有new和[]的数组,以获取一些改进的信息。输出由于无效的内存访问。

如果问题是由于使用了无效索引导致,那么vector :: at()会引发一个异常,您将无法捕获它,并且许多调试器在找到这对因素时将停止,它们将为您提供帮助检查程序中发生问题的点以及关键事实,例如您尝试访问的索引以及变量的内容。

它们通常会向您显示比预期更多的“堆栈帧”,但是其中一些是系统如何处理未捕获的异常的内部细节,您应该期望调试器可以帮助您找到与问题发展相关的堆栈帧,因此您可以检查那个背景。

答案 1 :(得分:0)

您的程序在Linux上的g ++上运行良好

$ g++ -o main pascal.cpp
$ ./main
Enter dimension 1 for lattice grid: 3
Enter dimension 2 for lattice grid: 4








Number of SE paths in a 3x4 lattice: 35

还有其他事情,因为您的cout语句没有副作用。 下面是一个有关如何调试此方法的想法:打开2个Visual Studio实例,一个实例的版本为没有,而cout语句,另一个实例的版本为其中。只需进行逐步调试即可发现它们之间的第一个区别。我的猜测是,您将意识到cout语句与错误无关。