首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C++ 指針操作二維數組的正確姿勢

     編輯:程式設計疑難解答

問題代碼

int *s;
for (i=0; i<5; i++)
    for (j=0; j<5; j++)
        cout << s[i][j];  // 編譯錯誤:s 是一級指針,不支持 [i][j]

錯誤原因

int *s 是一級指針,只能進行一維解引用 s[i]。二維數組需要指向數組的指針或二級指針。

三種正確方案

方案一:指向固定列數數組的指針 (推薦、類型安全)

// 定義:指向「包含 5 個 int 的數組」的指針
int (*s)[5];  

// 分配 5 行 (動態)
s = new int[5][5];  // 或 malloc(5 * sizeof(int[5]))

// 訪問
s[i][j] = 10;  // 正確:編譯器知曉列數為 5,計算偏移 i*5+j

// 釋放
delete[] s;  // s 是指向數組的指針,delete[] 正確釋放整塊內存
  • 優勢:保持二維語法 s[i][j],編譯器自動計算偏移,類型安全。
  • 要求:列數 (第二維) 必須在編譯期已知。

方案二:二級指針 (動態行列、兼容 C)

int **s;

// 分配行指針數組
s = new int*[5];
// 分配每行數據
for (int i = 0; i < 5; i++) {
    s[i] = new int[5];
}

// 訪問
s[i][j] = 10;  // 正確:先解引用行指針,再解引用列

// 釋放 (逆序)
for (int i = 0; i < 5; i++) delete[] s[i];
delete[] s;
  • 優勢:行數、列數均可動態決定,兼容 C 風格 malloc。
  • 缺點:內存不連續(每行獨立分配),釋放繁瑣,緩存局部性差。

方案三:一維數組模擬二維 (高性能、內存連續)

int *s = new int[5 * 5];  // 連續塊

// 訪問:手動計算索引
s[i * 5 + j] = 10;  // 第 i 行第 j 列 (行優先)

// 封裝宏/函數簡化
#define AT(s, i, j, COLS) ((s)[(i) * (COLS) + (j)])
AT(s, i, j, 5) = 10;

// 釋放
delete[] s;
  • 優勢:單次分配、內存連續、緩存友好、易於傳遞給 C API/GPU/OpenCL。
  • 現代 C++ 建議:使用 std::vector<int> s(25) 或 std::unique_ptr<int[]> 管理生命週期。

現代 C++ 最佳實踐

1. std::vector 二維 (動態、安全、RAII)

std::vector<std::vector<int>> matrix(5, std::vector<int>(5));
matrix[i][j] = 10;  // 直接使用
// 自動內存管理,無需手動 delete

2. std::array 固定大小 (棧上、零開銷)

std::array<std::array<int, 5>, 5> matrix;
matrix[i][j] = 10;

3. 單維 vector + 封裝類 (高性能、連續內存)


class Matrix {
    std::vector<int> data;
    int rows, cols;
public:
    Matrix(int r, int c) : rows(r), cols(c), data(r * c) {}
    int& at(int r, int c) { return data[r * cols + c]; }
    const int& at(int r, int c) const { return data[r * cols + c]; }
    int* rowPtr(int r) { return &data[r * cols]; } // 兼容 C API
};

Matrix m(5, 5);
m.at(i, j) = 10;

方案選擇指南

場景推薦方案關鍵點
列數固定、需二維語法、C++98/11int (*s)[COLS]類型安全、連續內存
行列均動態、兼容 C 庫int **s 或 std::vector<vector>靈活但非連續
高性能計算、GPU 互操作、大矩陣std::vector<T> 一維 + 索引計算連續內存、緩存友好
現代 C++ 專案 (C++11+)std::vector / std::array / 封裝類RAII、異常安全、可讀

總結

原代碼 int *s 無法直接支持 s[i][j]。列數固定用 int (*s)[COLS],全動態用 std::vector 封裝,極致性能用一維連續內存手動索引。現代 C++ 強烈建議棄用裸指針,擁抱標準庫容器與 RAII。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved