核心錯誤
[cpp]
void matrix_mult(float **p); // 錯誤:參數是二級指針
float a[3][3];
matrix_mult(a); // 編譯錯誤:cannot convert 'float [3][3]' to 'float **'
根本原因
float a[3][3] 是連續內存塊(9 個 float),類型為 float [3][3],退化為 float (*)[3](指向含 3 個 float 數組的指針)。
float **p 是指向指針的指針,期望一個指針數組(每個指針指向一行),內存不連續。
- 二者內存佈局完全不同,不可互換。
正確傳參方式
方法一:數組指針(推薦)
[cpp]
void matrix_mult(float (*a)[3], float (*b)[3], float (*c)[3]); // 第二維必須固定
// 調用
matrix_mult(a, b, c);
方法二:一維數組扁平化
[cpp]
void matrix_mult(float *a, float *b, float *c, int n); // 手動計算下標 a[i*n+j]
方法三:指針數組(需額外構建行指針)
[cpp]
float *rows[3];
for (int i=0;i<3;i++) rows[i]=a[i];
matrix_mult(rows, ...); // 參數 float **
關鍵類型辨析
| 聲明 | 含義 | sizeof |
int a[10][20] | 真二維數組,連續 200 int | 800 字節 |
int *b[10] | 10 個 int* 組成的指針數組 | 40/80 字節 |
int (*p)[3] | 指向「3個int數組」的指針 | 4/8 字節 |
int (*p)() | 指向函數的指針 | 4/8 字節 |
int *p() | 返回 int* 的函數 | — |
完整可運行示例(矩陣乘法)
[cpp]
#include
#include
#include
void matrix_mult(float (*a)[3], float (*b)[3], float (*c)[3]);
void matrix_init(float (*a)[3]);
float a[3][3] = {1,2,3,4,5,6,7,8,9};
float b[3][3] = {2,3,4,5,6,7,8,9,1};
float c[3][3] = {0};
int main() {
matrix_init(c);
matrix_mult(a, b, c);
for(int i=0;i<3;i++){
for(int j=0;j<3;j++) printf("%f ", c[i][j]);
printf("\n");
}
return 0;
}
void matrix_mult(float (*a)[3], float (*b)[3], float (*c)[3]) {
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
for(int k=0;k<3;k++)
c[i][j] += a[i][k] * b[k][j];
}
void matrix_init(float (*a)[3]) {
for(int i=2;i>=0;i--)
for(int j=2;j>=0;j--)
a[i][j] = 0;
}
總結
- 二維數組參數必須保留第二維大小:
void f(int a[][N]) 或 void f(int (*a)[N])。
float ** 不是二維數組指針,是二級指針,僅適用於指針數組(如 malloc 的不連續行)。
- 跨文件聲明用
extern int a[][N];,不可寫成 extern int **a;。