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],編譯器自動計算偏移,類型安全。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;
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;
std::vector<int> s(25) 或 std::unique_ptr<int[]> 管理生命週期。std::vector<std::vector<int>> matrix(5, std::vector<int>(5));
matrix[i][j] = 10; // 直接使用
// 自動內存管理,無需手動 delete
std::array<std::array<int, 5>, 5> matrix;
matrix[i][j] = 10;
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/11 | int (*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。