標籤:
簡單來說,指標包含的就是記憶體位址。理解指標關鍵在於理解C的記憶體管理員模式。C裡面有三種記憶體:
①、靜態全域記憶體(生命週期從程式開始到程式結束,全域變數範圍是全域,靜態變數範圍在定義它們的函數內部);
②、自動記憶體(在函數內部聲明的變數,在函數被調用時建立,範圍和生命週期都在函數內部);
③、動態記憶體(記憶體配置在堆上,根據需要釋放,通過指標引用,範圍局限於引用的指標);
下面先來生命一個指標並列印其地址和值,這裡p%指的是以十六進位的形式返回資料:
#include <stdio.h>main()
{int num=5;int* pi=#printf("Address of pi is : %p\n Value: %p\n", &pi, pi);
//Address of pi is : 0xbfa98298
//Value: 0xbfa98294}
間接引用操作符(*)返回指標變數指向的值,一般稱為解引指標。我們可以把接引操作符的結果用作左值,“左值”指賦值操作符左邊的運算元,所有左值都必須可以修改,因為它們會被賦值。
*pi = 10;printf("%d\n", num);
null有幾種不同的應用情況,這可能使它被誤解。null被賦值給指標就說明該指標不指向任何東西。當然他還是有自己的地址,但是他的value將是空的。NULL宏是強制轉換為void指標的整數常量0。很多標頭檔都包含這個定義,如stddef.h,stdblib.h,stdio.h。通過NULL宏來擷取null指標。ASCII字元NUL定義為全0的位元組。null語句就是只有一個分號的語句。null字串就是Null 字元串。注意為初始化的指標可能包含任何值,但是null指標不會引用記憶體中 任何地址。當指標為null時,if(指標)表示false,反之表示true。
NULL宏:
#define NULL ((void*) 0)
int* pi1 = 0;//1
int* pi2 = NULL//2
1和2是等價的。在這裡,根據不同上下文,數字0被重載了,表示null指標。
void指標是通用類型指標,用來存放任何資料類型的引用。任何指標都可以被賦值給void指標,也可以轉換成原來的指標類型,因此我們應該小心不能胡亂轉換,因為不同類型的指標長度不一定相同。使用sizeof()函數列印指標的長度:
printf("size of *pi is : %d\n", sizeof(*pi));
當指標被聲明全域或靜態,就會在程式啟動時被初始化為NULL。指標的實際長度取決於使用的機器和編譯器。不同的電腦給C的資料類型分配空間採用不同的資料模型。一種作業系統可能支援多種模型,具體採用哪種通常由編譯器決定。
使用指標時可能遇到一下預定義類型:
①、size_t :用於安全的表示長度;
②、ptrdiff_t:用於處理指標算術運算;
③、intptr_t和uintptr_t:用於儲存指標地址;
size_t類型表示C中任何對象能達到的最大長度。它是不帶正負號的整數。size_t作為sizeof操作符的傳回值類型,同時也是很多函數如malloc和strlen的參數類型。列印size_t可以用 %zu 或 %u格式說明符。
intptr_t和uintptr_t類型用來存放指標地址。它們提供了一種可移植且安全的方法聲明指標,而且和系統中使用的指標長度相同。
指標有如下幾種操作符:
* 聲明指標
* 解引指標
-> 指向操作符
+ 加法
- 減法
== != 相等、不等
> >= < <= 大於大於等於小於小於等於
資料指標可以執行以下算數運算:
加上整數;實際加的數是整數與指標資料類型對應位元組的乘積。
減去整數;原理同上。
兩個指標相減;一個指標減去另一個指標得到兩個指標間的差值。同樣這個差值是"單位"數,是實際地址差除以資料對應位元組數的值。ptrdiff_t類型用於表示兩個指標差值的可移植方式。
比較指標;差值和比較指標通常在數組方面比較有用,可以用來判斷元素順序。
指標支援多層間接引用。指向指標的指標叫做“雙重指標”。
未完待續。
深入理解C指標之一:初識指標