Linux 核心設計實作摘要

C語言

指標理解

C Traps and Pitfalls 的 “Understanding Declarations”小節提到如何解讀指標。每一個C的變數宣告可以拆成兩個部分。

  1. 型態
  2. 一串將會回傳這個型態的表達式

float f, g;代表f, g將會回傳float
float ff();代表ff()將會回傳float,因此ff是一個function並且會回傳float
float *pf;代表*pf江會回傳float,因此pf是一個pointer
float *g(), (*h)();首先()的優先度大於*因此*g() 可以改寫成*(g()),由此可知g是function並且會回傳一個pointer to a float的指標。而(*h)()代表h是一個pointer to a function指標,而且這個function會回傳float。


知道如何宣告變數後就可以寫出,就可以知道如何寫出這個類型強制轉型的寫法,只需要把變數名稱和分號移除,最後再加上括號
float *g();在這裡的g是一個回傳pointer的function,這個pointer指向float。而g強制轉型的寫法即為(float *())

Byte和Bit

1 Byte = 8 Bits

指標運算符號

  1. Address-of operator
    &稱為 Address-of operator

  2. Dereference operator
    *稱為 Dereference operator
    將pointer所指向的值給另一個變數(This is called a “load” operation.)

    1
    int bar = *foo_ptr;

    將值儲存到pointer所指的位置(This is called a “store” operation.)

    1
    *foo_ptr = 42; Sets foo to 42

->操作符

定義一個struct foo和一個foo的指針foo_ptr

1
2
3
4
5
6
struct foo {
size_t size;
char name[64];
int answer_to_ultimate_question;
unsigned shoe_size;
};

如果要查看foo_ptr所指向的內容,可以用

1
(*foo_ptr).size = new_size;

或者是用->操作符

1
foo_ptr->size = new_size;

陣列Array

宣告陣列

1
int array[] = { 45, 67, 89 };

在C語言,你宣告了一個陣列array之後,當你使用的時候,array這個變數其實是一個指向這個陣列第一個元素的指針,我們把這個行為稱為decaying,因為陣列被decays成指針了。不過他還是和針的指針有一點不同,其中就是如果用sizeof(array)來看陣列的話,回傳的將會是陣列的總長度(在這個範例就是(sizeof(int) = 4) × 3 = 12)而不是單一個指針的長度。
下面這三種狀況對陣列來說都是一樣的

1
array == &array == &array[0]

他們分別代表“array”, “pointer to array”, 和 “pointer to the first element of array”,但在C這三個東西是一樣的

陣列++

對於一般變數來說variable += 1代表對變數+1,但是對於指標來說代表對目前指標的位置加上資料型態的大小。以我們上一個例子來說我們的陣列儲存的是int,而array被decays成pointer了,所以array + 1就是加上sizeof(int),等同於我們把指針移動到下一個元素。

Indexing

首先看一下以下例子

1
2
3
int array[] = { 45, 67, 89 };
int *array_ptr = &array[1];
printf("%i\n", array_ptr[1]);

這段程式宣告的一個三個元素的陣列array,還有一個int指針array_ptr,可以用下面這張圖可以看到array[1]array_ptr[0]指向同一個記憶體。
image info{: w=”700” h=”200” }
我們可以看到其實[]是指針的操作符,array[1]等同於*(array + 1)

參考:
Everything you need to know about pointers in C
https://boredzo.org/pointers/

Author

Steven

Posted on

2022-12-02

Updated on

2025-01-14

Licensed under

Comments