首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

《C 專家編程》筆記第 4 章:陣列與指標並不相同

     編輯:關於C

核心觀點

許多 C 語言書籍對陣列與指標的關係「含糊其辭,一帶而過」。本章重點闡述:**陣列與指標在定義、記憶體佈局、運行行為上本質不同**,僅在特定上下文 (表達式求值) 中陣列名「退化」為指標。

關鍵概念辨析

  • 聲明:描述其他地方建立的對象 (如 extern int a;),不分配記憶體。
  • 定義:為對象分配記憶體 (如 int a;),也是聲明。
  • 賦值語境:x = y; 中,x 代表地址 (左值),y 代表地址內容 (右值)。
  • 陣列名:是左值,但**不可修改**的左值 (non-modifiable lvalue),不能出現在賦值號左邊。

代碼驗證:字串常量 vs 字元陣列

#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;
}

驗證結論

  1. 只有字串常量可在定義時初始化指標:char *p = "..."; 合法,float *pi = 3.14; 非法。
  2. char * 指向字串常量為唯讀:編譯器將字面量放入 .rodata 段,寫入導致未定義行為 (通常崩潰)。
  3. char a[] 定義的陣列可修改:內容複製到棧上陣列,擁有所有權,可讀寫。

深層原因:編譯器符號表與記憶體佈局

特性char *p = "abc"char a[] = "abc"
存儲位置指標變量在棧,字串在唯讀區整個陣列在棧 (或數據段靜態存儲)
內容可修改性不可修改 (硬體/OS 保護)完全可修改
sizeof 結果指標大小 (4/8 Bytes)陣列總大小 (含結束符 \0)
賦值操作p = "def" 合法 (改指向)a = "def" 非法 (陣列名非可修改左值)

總結

**「陣列不是指標,指標不是陣列。」** 陣列名在表達式中 (除 sizeof, &, 字串字面量初始化外) 會隱式轉換為指向首元素的指標,**這是一種隱式類型轉換,而非身份等同**。混淆二者是導致段錯誤、邏輯錯誤的常見根源。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved