簡體   English   中英

在不使用任何外部庫的情況下用c ++創建mxn 2D數組

[英]creating mxn 2D array in c++ without using any external library

我是C ++語法的初學者。 現在,我需要在C ++中創建一個mxn 2D數組,以便在另一個項目中使用它。 我看過使用類似工具,包括其他的答案vector等許多工具都沒有關於我的Visual Studio 15的工作,即對vector我不能確定std::vector沒有消息像vector is not in std 因此,我編寫了以下代碼:

#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成功地進行預測和提前閱讀中獲得收益,並且您的程序通常要快得多。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM