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

C語言指標運算深度解析:從基礎到進階

     編輯:關於C

前言:兩個看似無關的小知識

在正式探討指標運算之前,我們先透過兩個簡單的例子來熱身,這也能幫助我們更好地理解後續的核心概念。

例子一:printf 的特殊用法

#include <stdio.h>

int main(void) {
    char *s = "Hello world.";
    printf(s);
    return 0;
}

這段代碼會報錯嗎?不會。printf 的常規用法是 printf("Please input a data:"),此時傳遞給函數的是字符串常量的首地址。上述代碼中,字符指針 s 同樣存儲了字符串首地址,因此運行完全正常,甚至編譯時連警告都不會出現。

例子二:多餘參數的處理

#include <stdio.h>

int main(void) {
    char *s = "Hello world.";
    printf(s, 1, 2, 3);
    return 0;
}

這段代碼正確嗎?同樣是正確的。printf 是變長參數函數,它根據格式字符串中的佔位符(如 %d)數量來解析後續參數。若格式字符串中無佔位符,後續傳入的參數會被忽略,因此編譯運行均無問題。


核心主題:指標的加減運算規則

理解指標運算的關鍵在於:**指標運算依賴於指標指向的數據類型**,而非簡單的地址數值增減。

經典面試題

#include <stdio.h>

int main(void) {
    int a[10];
    printf("%p %p ", &a[0] + 1, &a[1]);
    return 0;
}

問題:輸出的兩個地址值一樣嗎?不一樣的話相差多少?

常見誤區:許多人認為 &a[0] 是第 0 個元素地址,&a[1] 是第 1 個元素地址,兩者應相差 sizeof(int) 個字節(通常為 4)。

正確分析:&a[0] 的類型是 int (*)[10](指向含 10 個 int 的數組指針),但此處發生了隱式轉換為 int*。&a[0] + 1 並非地址值加 1,而是加上 1 * sizeof(int),即指向下一個 int 元素。因此 &a[0] + 1 與 &a[1] 完全等價,輸出地址相同。

極端驗證例子

#include <stdio.h>

int main(void) {
    printf("%d ", (int *)0x04 - (int *)0x00);
    return 0;
}

在 32 位機上運行,輸出為 1。這有力證明了指標減法的結果是「元素個數差」,而非字節差。兩個 int* 指標相減,結果為 1,表示相差 1 個 int 大小(4 字節)。

類型安全體現

若嘗試將 char* 賦值給 int*,編譯器會報錯或警告:

char s;
int *p = &s; // 警告:不能將 char* 賦值給 int*

這說明取地址操作 &s 的結果類型是 char*,嚴格區分了指標類型,進而決定了指標運算的步長。


總結

  • 指標加減運算的步長由指標指向的**數據類型大小**決定(ptr + n 相當於 ptr + n * sizeof(type))。
  • 指標相減結果為**元素個數差**,單位是指向類型的大小。
  • 指標類型嚴格綁定其指向的數據類型,這是 C 語言類型系統的重要體現。

掌握這些規則,是寫出正確、高效 C 代碼(尤其是涉及數組、動態內存、底層硬件操作)的基石。

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