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

C語言指針深度解析:從基礎操作到數組與字符串的核心差異

     編輯:關於C語言

指針基礎操作回顧

在上一篇文章中,我們探討了指針的基本概念。這裡我們通過一組經典問答,進一步鞏固對指針運算的理解。假設有如下代碼片段:

char ch = 'a';
char *pch = &ch;

以下是關鍵表達式的含義解析:

  • &ch:變量 ch 的內存地址。
  • pch:一個 char* 類型的指針變量,其值為 ch 的地址。
  • &pch:指針變量 pch 本身在內存中的地址(二級指針的目標)。
  • *pch:對 pch 進行解引用,間接訪問並獲取 ch 的值(即 'a')。
  • *pch + 1:先解引用獲取值 'a',再加 1,結果為 'b'(注意優先級:* 高於 +)。
  • *(pch + 1):先對指針加 1(移動到下一個 char 大小的內存單元),再解引用訪問該地址上的內容(此處屬於越界訪問,行為未定義)。
  • ++pch:前置遞增,指針先移動到下一個位置,表達式的值為新地址。
  • *++pch:指針先遞增,再解引用訪問新地址的值。
  • *pch++:後置遞增,先解引用訪問當前地址的值,表達式結束後指針再移動到下一個位置。
  • ++*pch:等價於 ++(*pch),對指針指向的值進行遞增(ch 變為 'b')。
  • (*pch)++:先取值使用,然後將指向的值遞增。
  • ++*++pch:解析為 ++(*(++pch)),指針先移動,再解引用,最後對目標值遞增。
  • ++*pch++:解析為 ++(*(pch++)),先解引用當前值並遞增,隨後指針移動。

數組名與指針的淵源

理解數組與指針的關係是掌握 C 語言的關鍵一步。請看代碼:

int a[10];
int *pa;
pa = a;        // 等價於 pa = &a[0];

這揭示了兩個核心事實:

  1. 數組名代表數組首元素的地址。在絕大多數表達式中,a 會隱式轉換為指向首元素的指針 &a[0]。
  2. 內存佈局的連續性。數組在內存中是連續分配的,指針算術運算(如 pa+1)正是基於這種連續性跳躍到下一個元素。

數組與指針內存佈局示意圖

字符指針 vs 字符數組:一個經典的陷阱

這是面試與實際開發中極易踩坑的地方:


char amessage[] = "I Love You!";  // 字符數組
char *pmessage = "I Love You!";   // 字符指針

字符數組與字符指針內存結構對比

雖然圖示看似相似,但本質區別巨大:

  • amessage:分配在棧上(或全局區),內容可修改,大小固定為 12 字節(含 \0)。
  • pmessage:指針變量指向只讀數據段中的字符串字面量。嘗試通過 pmessage[0] = 'i'; 修改內容會導致未定義行為(通常是段錯誤)。
核心口訣:數組是“容器”,自帶存儲空間;指針是“路標”,只記錄地址。字符串字面量是常量,存放在只讀區。

指針算術運算詳解

1. 指針 ± 整數

適用於數組遍歷與動態內存操作。指針加減整數時,步長為 sizeof(指針指向的類型)。

int values[5];
int *vp;
for (vp = values; vp != &values[5]; ) {
    *vp++ = 0;  // 清零並移動到下一個
}

2. 指針 - 指針

只有指向同一數組(或同一塊動態內存)的指針相減才有意義,結果類型為 ptrdiff_t,表示兩者之間的元素個數差值。


int *vp1 = values;
int *vp2 = &values[3];
printf("%td\n", vp1 - vp2); // 輸出 -3

指針數組、數組指針與多維數組

指針數組

本質是數組,元素為指針。定義形式:類型 *數組名[長度]。

char *ptr_array[10]; // 含有 10 個 char* 的數組

指針數組內存結構

數組指針

本質是指針,指向一個數組(通常指向二維數組的一行)。定義形式:類型 (*指針名)[長度]。

二維數組 vs 指針數組


char ar[3][8] = {"we","are","chinese"};  // 二維數組:連續內存,固定行長
char *parray[3] = {"we","are","chinese"}; // 指針數組:離散內存,行長可變

二維數組與指針數組對比

  • 二維數組:編譯時分配連續塊內存(3*8=24 bytes),ar[i][j] 編譯器轉換為 *(*(ar+i)+j)。
  • 指針數組:僅分配 3 個指針的空間,各指針指向不同位置的字符串常量。

總結:數組與指針的區別與聯系

維度指針數組
訪問方式間接訪問(解引用)直接訪問(下標)
存儲內容地址數據實體
結構特性動態數據結構固定大小、同類型元素集合
內存管理malloc/free 手動管理隱式自動分配/釋放
指向對象可指向匿名數據(堆內存)自身即數據

緊密聯系

  1. 表達式中數組名退化為指向首元素的指針。
  2. 下標運算 a[i] 本質等價於指針偏移 *(a+i)。
  3. 函數參數傳遞時,數組參數退化為指針,失去長度信息。
  4. 多維數組在編譯器處理時,以多級指針形式計算地址偏移。

指針與數組是 C 語言靈活與高效的雙刃劍,深入理解其內存模型,才能寫出健壯、高性能的代碼。

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