void nzp(int v) { // 形參為標量
if (v > 0) printf("%d ", v);
else printf("%d ", 0);
}
int main() {
int a[5];
for (int i = 0; i < 5; i++) {
scanf("%d", &a[i]);
nzp(a[i]); // 傳遞 a[i] 的值
}
}
int 值,函數內修改不影響原陣列。實參陣列 a:位址 2000 起,佔 10 bytes (5 int) 形參陣列 b:無獨立記憶體,b 即為指標指向 2000 a[i] 與 b[i] 物理上為同一記憶體單元
float aver(float a[5]) { ... } // 帶長度(僅文檔用,編譯器忽略)
float aver(float a[]) { ... } // 空括號
float aver(float *a) { ... } // 指標形式(本質相同)
編譯器均視為 float *a,不檢查長度,長度資訊丟失,需額外參數傳遞。
float aver(float a[5]) {
float s = 0;
for (int i = 0; i < 5; i++) s += a[i];
return s / 5;
}
int main() {
float sco[5];
for (int i = 0; i < 5; i++) scanf("%f", &sco[i]);
printf("%.2f", aver(sco)); // sco 退化為指標傳遞
}
void nzp(int a[5]) {
for (int i = 0; i < 5; i++)
if (a[i] < 0) a[i] = 0; // 修改形參陣列
}
int main() {
int b[5] = {10, -2, 5, -1, 8};
nzp(b); // 實參 b 被修改!
// b 現在為 {10, 0, 5, 0, 8}
}
const:void nzp(const int a[5])。
// 二維陣列:必須指定第二維長度
void print(int a[][4], int rows) { ... }
void print(int (*a)[4], int rows) { ... } // 指向含 4 int 陣列的指標
int main() {
int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
print(a, 3);
}
int (*)[4]),非 int **。a[0][0], a[0][1]... a[1][0]...| 錯誤代碼 | 問題 | 修正 |
|---|---|---|
void f(int a[10]) { sizeof(a); } | sizeof(a) 為指標大小 (4/8),非陣列大小 | 額外傳長度參數 |
int a[10]; f(&a); | 類型不匹配:&a 為 int (*)[10] | 直接傳 a |
void f(int **a) { ... } 接收二維陣列 | 二維陣列非指標陣列 | 用 int (*a)[N] 或扁平化一維陣列 |
| 形參未加 const 導致誤改實參 | 副作用難追蹤 | 唯讀陣列加 const |
void process(int *arr, size_t len)。void print(const int *arr, size_t len)。int *arr 語意更清晰。void f(int n, int a[n]) 保留長度資訊(但棧分配風險大,慎用)。struct Vec { int *data; size_t len; } 實現帶長度的陣列物件。