C語言指標筆記

LanceEst發表於2024-07-18

該筆記整理自 阮一峰老師的《C語言教程》和部分網上資料

什麼是指標

指標就是一個代表某個記憶體地址的值

宣告和初始化指標變數

int a = 10;
// 宣告一個指標變數p,並將a的地址賦給p
int* p = &a;

// 輸出p的值(地址值)
printf("%p", p);
// 輸出p所指向的值
printf("%d", *p);

這個*可以放在資料型別和變數名之間的任意位置,比如int * p;int *p;等等,不過為了體現p是一個指標變數,建議int* p;
%p佔位符表示一個指標變數

野指標

野指標通常指的是那些指向了一個已釋放的記憶體區域、未分配的記憶體區域、或者指向了不可訪問的記憶體區域的指標

野指標如何產生的?
指標變數未經初始化,則該指標會隨機指向一個記憶體地址,因此應該儘量給指標變數初始化,如果不知道該賦啥值,就賦NULL
指標所指向的空間被釋放掉了,如果某個指標指向的空間被釋放了,應該立即將該指標指向NULL
陣列越界訪問

指標與數字加減

一般用於陣列指標或者字串指標

int* p = (int*) 0x100;
p += 2; // 此時p的值為0x108,因為指標偏移量和其資料型別一致,int型別的指標偏移量為4

使用指標遍歷列印陣列裡的元素

int arr[] = {1, 2, 3, 4, 5};
int* p = arr; // 此時p指向arr的第一個元素1
for (int i = 0; i < sizeof(arr) / sizeof(int); i ++) {
  printf("%d\n", *p);
  p ++;
}

指標之間的加減

指標之間的加法是違法的,會報錯

但是相同型別的指標之間的減法是合法的

int* p1 = (int*) 0x1009;
int* p2 = (int*) 0x1000;

int dist = p1 - p2; // dist的值為3
// 分析:因為 0x1009 - 0x1000 = 9
// int佔4位元組,所以 9 / 4 = 2 ... 1,多出來1位,這個多出來的1位被包含在第三個int元素裡,所以dist值為3

但是dist可能會超過int的範圍,所以為了程式的健壯性,建議這麼寫

#include <stddef.h>

int main() {
  int* p1 = (int*) 0x1009;
  int* p2 = (int*) 0x1000;

  ptrdiff_t dist = p1 - p2;

  return 0;
}

ptrdiff_t型別專門被設計用來表示兩個指標之間的距離的,使用這種型別之前,需要引入stddef.h

踩雷日誌

交換兩個變數的值,錯誤程式碼:

int change(int x, int y) {
  int* xp = &x;
  int* yp = &y;

  *xp = *xp ^ *yp;
  *yp = *xp ^ *yp;
  *xp = *xp ^ *yp;
}

錯誤點:忘記基本資料型別的傳參方式為值傳遞,即 新開一個空間,將值賦值進去,再讓引數指向新的空間
正確程式碼:

int change(int* x, int* y) {
  *x = *x ^ *y;
  *y = *x ^ *y;
  *x = *x ^ *y;
}

相關文章