許多 C 語言書籍對陣列與指標的關係「含糊其辭,一帶而過」。本章重點闡述:**陣列與指標在定義、記憶體佈局、運行行為上本質不同**,僅在特定上下文 (表達式求值) 中陣列名「退化」為指標。
extern int a;),不分配記憶體。int a;),也是聲明。x = y; 中,x 代表地址 (左值),y 代表地址內容 (右值)。#include <stdio.h>
int main()
{
char *p = "012345"; // 指向字串常量 (唯讀區)
char a[19] = "01234"; // 字元陣列 (棧上,可修改)
printf("%c", p[1]); // 輸出 '1'
// p[1] = 'a'; // 錯誤!嘗試修改唯讀記憶體 -> 段錯誤
printf("%c", a[1]); // 輸出 '1'
a[1] = 'a'; // 合法!修改陣列內容
printf("%c", a[1]); // 輸出 'a'
return 0;
}
char *p = "..."; 合法,float *pi = 3.14; 非法。char * 指向字串常量為唯讀:編譯器將字面量放入 .rodata 段,寫入導致未定義行為 (通常崩潰)。char a[] 定義的陣列可修改:內容複製到棧上陣列,擁有所有權,可讀寫。| 特性 | char *p = "abc" | char a[] = "abc" |
|---|---|---|
| 存儲位置 | 指標變量在棧,字串在唯讀區 | 整個陣列在棧 (或數據段靜態存儲) |
| 內容可修改性 | 不可修改 (硬體/OS 保護) | 完全可修改 |
sizeof 結果 | 指標大小 (4/8 Bytes) | 陣列總大小 (含結束符 \0) |
| 賦值操作 | p = "def" 合法 (改指向) | a = "def" 非法 (陣列名非可修改左值) |
**「陣列不是指標,指標不是陣列。」** 陣列名在表達式中 (除 sizeof, &, 字串字面量初始化外) 會隱式轉換為指向首元素的指標,**這是一種隱式類型轉換,而非身份等同**。混淆二者是導致段錯誤、邏輯錯誤的常見根源。