在c++中创建mxn 2D数组,而不使用任何外部库



我是c++语法的初学者。现在,我需要在c++中创建一个mxn 2D数组,以便在另一个项目中使用它。我看过其他的答案,包括使用vector等工具。许多工具不能在我的Visual Studio 15上工作,即对于vector,我不能在没有vector is not in std这样的消息的情况下定义std::vector。因此,我编写了以下代码:

#include "stdafx.h"
#include <iostream>
using namespace std;

int main()
{
    int i; int j; int row[5][10] = {};
    for (int j = 0; j < 10;)
        for (int i = 0; i < 5;)
        {
            row[i][j] = 500;
            int printf(row[i][j]);
            i++;
            j++;
            cout << "Array:" << row[i][j] << endl;
        }
    return 0;
}

显然,这不是正确的语法。所以输出超出了我的预期。我想创建一个m*n数组所有元素都是相同的整数;这里是500。也就是说,如果m=3 n=2,我应该得到

500 500 500
500 500 500

您当前的代码有一些问题。

  1. 第一个for循环缺少大括号
  2. 在for循环中重新定义了int i和int j。不是一个复杂的问题,但仍然是一个问题。
  3. 您使用printf错误。printf用于向控制台输出字符串。正确的行应该是printf("%d", row[i][j]);

如果你想使用vector,你必须包含它使用#include <vector>。您可以使用非常类似于数组的vector,但您不必担心大小。

你好像在学习。所以,我做了最小的修改,使它工作。我建议你根据你的需要修改。

#include <iostream>
using namespace std;
int main()
{
    int row[5][10] = {};
    for (int j = 0; j < 10; j++) {
        for (int i = 0; i < 5; i++) {
            row[i][j] = 500;
            cout << row[i][j]  << " ";
        }
        cout << endl;
    }
    return 0;
}

以OP程序为例对std::vector的护理与喂养。

#include <iostream>
#include <vector> // needed to get the code that makes the vector work
int main()
{
    int m, n; // declare m and n to hold the dimensions of the vector
    if (std::cin >> m >> n) // get m and n from user
    { // m and n are good we can continue. Well sort of good. The user could
      // type insane numbers that will explode the vector, but at least they
      // are numbers.
      // Always test ALL user input before you use it. Users are malicious
      // and incompetent <expletive delteted>s, so never trust them.
      // That said, input validation is a long topic and out of scope for this
      // answer, so I'm going to let trapping bad numbers pass in the interests
      // of keeping it simple
        // declare row as a vector of vectors
        std::vector<std::vector<int>> row(m, std::vector<int> (n, 500));
        // breaking this down:
        // std::vector<std::vector<int>> row
        //      row is a vector of vectors of ints
        // row(m, std::vector<int> (n, 500));
        //      row's outer vector is m std::vector<int>s constructed with
        //      n ints all set to 500
        for (int j = 0; j < n; j++) // note: j++ has been moved here. This is
                                     // exactly what the third part of a for
                                     // statement is for. Less surprises for
                                     // everyone this way
        // note to purists. I'm ignoring the possible advantages of ++j because
        // explaining them would muddy the answer.
        // Another note: This will output the transverse of row because of the
        // ordering of i and j; 
        {
            for (int i = 0; i < m; i++) // ditto I++ here
            {
                // there is no need to assign anything here. The vector did 
                // it for us
                std::cout << " " << row[i][j]; // moved the line ending so that
                                               // the line isn't ended with
                                               // every column
            }
            std::cout << 'n'; // end the line on the end of a row
            // Note: I also changed the type of line ending. endl ends the line
            // AND writes the contents of the output stream to whatever media
            // the stream represents (in this case the console) rather than
            // buffering the stream and writing at a more opportune time. Too
            // much endl can be a performance killer, so use it sparingly and
            // almost certainly not in a loop
        }
        std::cout << std::endl; // ending the line again to demonstrate a better
                                // placement of endl. The stream is only forced
                                // to flush once, right at the end of the
                                // program
                                // even this may be redundant as the stream will
                                // flush when the program exits, assuming the
                                // program does not crash on exit.
    }
    else
    { // let the use know the input was not accepted. Prompt feedback is good
      // otherwise the user may assume everything worked, or in the case of a
      // long program, assume that it crashed or is misbehaving and terminate
      // the program.
        std::cout << "Bad input. Program exiting" << std::endl;
    }
    return 0;
}

一个性能注意事项:向量的向量不能提供一个长内存块。它提供了M+1块内存,可以在存储中的任何位置。通常,当现代CPU从内存中读取一个值时,它也会根据这样的假设读取它周围的值:如果您希望项目位于位置X,那么您可能很快就会希望该值位于位置X+1。这允许CPU一次加载,"缓存"许多值。如果你必须在记忆中跳来跳去,这就行不通了。这意味着CPU可能会发现自己花费更多的时间来检索向量的向量的部分,而不是处理向量的向量。典型的解决方案是用1D结构代替2D数据结构,然后自己执行2D到1D的映射。

:

std::vector<int> row(m*n, 500); 

好看多了,是吗?访问看起来有点难看,不过

std::cout << " " << row[i * n + j];
有趣的是,将row[j][i]转换为内存地址的幕后工作几乎与row[j*n+i]相同,因此即使您显示更多的工作,它也不会占用更长时间。再加上您从CPU成功预测和提前读取中获得的好处,您的程序通常会快得多。

相关内容

最新更新