問題程式碼
#include <stdio.h>
int erfen(int x, int v[], int n) {
int low = 0, high = n - 1, mid;
while (low <= high) {
mid = (low + high) / 2;
if (x > v[mid]) low = mid + 1;
else if (x < v[mid]) high = mid - 1;
else return mid;
}
return -1;
}
int main() {
int x, n, c, i;
int v[n]; // 錯誤:n 尚未初始化,VLA 在此處未合法配置
printf("請輸入你要找的數\n");
scanf("%d", &x);
printf("請輸入最大的範圍\n");
scanf("%d", &n);
for (i = 0; i <= n - 1; i++) {
v[i] = i;
}
c = erfen(x, v[n - 1], n); // 錯誤:傳遞 v[n-1] (int) 而非陣列指標
if (c == -1) printf("抱歉,沒有找到你需要的資訊\n");
else printf("你要找到的資訊在第%d個", c);
return 0;
}
主要錯誤
- 陣列宣告時機錯誤:
int v[n]; 置於 scanf 讀取 n 之前,此時 n 未初始化(亂數),導致陣列大小不定,且 C 標準不保證支援此寫法(VLA 需在 C99 且 n 已知)。
- 函式呼叫參數錯誤:
erfen(x, v[n - 1], n) 將陣列最後一個元素(int)傳遞給期望 int[] 的參數,導致型別不符、存取非法記憶體。
- 迴圈條件:
i <= n - 1 應改為 i < n,避免陣列越界。
修正程式碼
#include <stdio.h>
#include <stdlib.h>
int erfen(int x, int v[], int n) {
int low = 0, high = n - 1, mid;
while (low <= high) {
mid = (low + high) / 2;
if (x > v[mid]) low = mid + 1;
else if (x < v[mid]) high = mid - 1;
else return mid;
}
return -1;
}
int main() {
int x, n, c, i;
printf("請輸入你要找的數: ");
scanf("%d", &x);
printf("請輸入陣列大小: ");
scanf("%d", &n);
if (n <= 0) {
printf("陣列大小必須大於 0\n");
return 1;
}
// 動態配置記憶體
int *v = (int *)malloc(n * sizeof(int));
if (!v) {
printf("記憶體配置失敗\n");
return 1;
}
for (i = 0; i < n; i++) {
v[i] = i; // 陣列內容為 0,1,2,...,n-1 (已排序)
}
c = erfen(x, v, n); // 傳遞陣列指標
if (c == -1) printf("抱歉,沒有找到你需要的資訊\n");
else printf("找到目標值,索引為 %d (第 %d 個元素)\n", c, c + 1);
free(v);
return 0;
}
重點總結
- 先讀取
n,再配置陣列(靜態大小上限或動態 malloc)。
- 函式參數傳遞陣列名稱
v(退化為指標),而非單一元素。
- 使用動態記憶體時,記得
free 釋放。
- 二分搜尋前提:陣列**必須已排序**,本範例因
v[i]=i 滿足條件。