char *a[2]; // 宣告兩個 char* 指標,但**未初始化** (野指標)
char *d;
scanf("%s%s", a[0], a[1]); // 將輸入寫入野指標指向的隨機記憶體 → 崩潰/資料損壞
if (strcmp(a[0], a[1]) > 0) { d=a[0]; a[0]=a[1]; a[1]=d; }
printf("%s\n", a); // %s 期望 char*,傳入 char** → 格式錯誤
#include
#include
int main() {
char str1[80], str2[80]; // 1. 分配實際字串儲存空間 (各 80 bytes)
char *a[2]; // 2. 指標陣列
char *d;
a[0] = str1; // 3. 指標指向有效緩衝區
a[1] = str2;
printf("請輸入兩個字串:");
scanf("%79s %79s", a[0], a[1]); // 限制寬度防溢位
if (strcmp(a[0], a[1]) > 0) {
d = a[0]; a[0] = a[1]; a[1] = d;
}
printf("較小: %s\n", a[0]); // 正確:傳入 char*
printf("較大: %s\n", a[1]);
return 0;
}
#include
#include
#include
int main() {
char *a[2];
char input[100];
char *d;
for (int i = 0; i < 2; i++) {
printf("字串 %d: ", i+1);
scanf("%99s", input);
a[i] = malloc(strlen(input) + 1); // 精確分配
if (!a[i]) { perror("malloc"); return 1; }
strcpy(a[i], input);
}
if (strcmp(a[0], a[1]) > 0) { d=a[0]; a[0]=a[1]; a[1]=d; }
printf("排序後: %s, %s\n", a[0], a[1]);
free(a[0]); free(a[1]); // 釋放記憶體
return 0;
}
int len1, len2;
scanf("%d %d", &len1, &len2); // 先讀長度 (教學示範)
char str1[len1+1], str2[len2+1]; // VLA
scanf("%s %s", str1, str2);
// ...後續同方法 1
| 宣告 | 記憶體配置 | 可直接存字串? | 適用場景 |
|---|---|---|---|
| `char str[80];` | 堆疊 80 bytes | ✅ | 固定最大長度、生命週期跟隨區塊 |
| `char *p;` | 堆疊 1 個指標 (8 bytes) | ❌ 需指向有效空間 | 指向現有字串、動態分配 |
| `char *a[2];` | 堆疊 2 個指標 | ❌ | 字串指標陣列、參數傳遞 |
| `char **p;` | 指向指標的指標 | ❌ | 動態二維字串、主函數 argv |
**字串指標陣列必須指向有效記憶體空間** (靜態陣列、動態分配、VLA)。`char *a[2]` 僅建立指標,**不配置字串儲存空間**。教學首選**靜態陣列緩衝區 + 指標指向**,簡單安全;實務長度不定用 **`malloc`/`free`**。