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

C 語言 & 取址運算符深度解析:從基礎到進階

     編輯:關於C語言

三種函數參數傳遞模式對比

1. 指標傳遞(C 風格)

int find(int *a);
int b = 1;
int test = find(&b);  // 實際執行:int *a = &b

創建新指標變數 a,指向 b。函數內修改 *a 影響外部 b。

2. 參考傳遞(C++ 風格)

int find(int &a);
int b = 1;
int n = find(b);  // 實際執行:int &a = b

a 成為 b 的別名,無新變數創建,直接操作原變數。

3. 值傳遞

int find(int a);
int b = 1;
int n = find(b);  // 實際執行:int a = b

創建副本 a,函數內修改不影響外部 b。

& 與 * 運算符核心語義

  • &(取址):作用於變數/函數標識符,獲取其記憶體地址。編譯期確定。
  • *(解引用):作用於指標,獲取指向地址的值。運行期確定。
int a = 0;
int *p = &a;   // p 存儲 a 的地址
int val = *p;  // val 獲取 a 的值(0)

進階案例:& 與 * 的複合運算

案例一:硬編碼地址的合法轉換

int a = 0;  // 假設地址 0x0012ff60
int *p = &*(int*)0x0012ff60;

解析:

  1. (int*)0x0012ff60:將整數轉為 int 指標
  2. *...:解引用,獲取該地址的值(即 a 的值)
  3. &...:再次取址,此處 & 非取址運算,而是「脫去解引用」,還原為 (int*)&a

關鍵結論:& 作為取址運算,操作數必須是變數/函數標識符。表達式結果(如 *ptr)無地址,此時 & 表示類型轉換中的「去引用」。

案例二:多重 & * 抵消

int *p = &*&*&a;  // 等價於 int *p = &a;

每對 &* 相互抵消,最終回歸取址本質。

常見錯誤與避坑指南

錯誤代碼原因正確寫法
int *p = &0x01000;字面常數無地址int *p = (int*)0x01000;
int *p = &(*ptr);*ptr 非標識符,& 非取址直接用 ptr
scanf("%d", a);缺少 &,傳值而非傳址scanf("%d", &a);

C++ 擴展:引用聲明

int a = 0;
int &r = a;  // r 是 a 的別名
cout << r;   // 輸出 0

引用必須初始化,綁定後不可改變指向,本質是編譯器層面的別名機制,無額外記憶體開銷。

總結:& 的雙重身份

  • 單目運算符:取變數/函數地址(編譯期綁定)
  • 按位與:a & b 位運算(運行期計算)
  • C++ 引用聲明:int &r = a 類型修飾符

區分上下文,精準理解,是寫出正確 C/C++ 代碼的基石。

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