?
Dieses Dokument verwendet PHP-Handbuch für chinesische Websites Freigeben
指針是一種引用另一種類型的函數(shù)或?qū)ο蟮膶ο箢愋停赡軙砑酉薅ǚ?。指針也可能指什么都沒有,它由特殊的空指針值表示。
在指針聲明的聲明語法中,類型說明符序列指定指向類型(可能是函數(shù)或?qū)ο箢愋?,可能不完整)?em style="font-style: italic;">聲明符的形式如下:
* qualifiers(optional) declarator | (1) |
---|
其中聲明符可以是標(biāo)識正在聲明的指針的標(biāo)識符,包括另一個指針聲明符(它將指示指向指針的指針):
float *p, **pp; // p is a pointer to float // pp is a pointer to a pointer to floatint (*fp)(int); // fp is a pointer to function with type int(int)
出現(xiàn)在*
和標(biāo)識符(或其他嵌套聲明符)之間的限定符限定了正在聲明的指針的類型:
int n;const int * pc = &n; // pc is a non-const pointer to a const int// *pc = 2; // Error: n cannot be changed through p without a castpc = NULL; // OK: pc itself can be changed int * const cp = &n; // cp is a const pointer to a non-const int*cp = 2; // OK to change n through cp// cp = NULL; // Error: cp itself cannot be changed int * const * pcp = &cp; // non-const pointer to const pointer to non-const int
指針用于間接尋址,這是一種無處不在的編程技術(shù); 它們可用于實現(xiàn)傳遞引用語義,訪問具有動態(tài)存儲持續(xù)時間的對象,以實現(xiàn)“可選”類型(使用空指針值),結(jié)構(gòu)之間的聚合關(guān)系,回調(diào)(使用指向函數(shù)的指針),通用接口(使用指針void)等等。
指向?qū)ο蟮闹羔樋梢杂脩?yīng)用于對象類型表達(dá)式(可能不完整)的地址 - 運算符的結(jié)果初始化:
int n;int *np = &n; // pointer to intint *const *npp = &np; // non-const pointer to const pointer to non-const int int a[2];int (*ap)[2] = &a; // pointer to array of int struct S { int n; } s = {1}int* sp = &s.n; // pointer to the int that is a member of s
指針可能作為操作數(shù)出現(xiàn)在間接操作符(一元*
)上,后者返回標(biāo)識指向?qū)ο蟮淖笾担?/p>
int n;int* p = &n; // pointer p is pointing to n*p = 7; // stores 7 in nprintf("%d\n", *p); // lvalue-to-rvalue conversion reads the value from n
指向結(jié)構(gòu)和聯(lián)合類型對象的指針也可以作為通過指針運算符訪問成員的左側(cè)操作數(shù)->
。
由于數(shù)組到指針的隱式轉(zhuǎn)換,可以使用數(shù)組類型的表達(dá)式初始化指向數(shù)組第一個元素的指針:
int a[2];int *p = a; // pointer to a[0] int b[3][3];int (*row)[3] = b; // pointer to b[0]
某些加法,減法,復(fù)合賦值,增量和減量運算符是為指向數(shù)組元素的指針定義的。
在某些情況下,為指向?qū)ο蟮闹羔樁x比較運算符:表示相同地址的兩個指針比較相等,兩個空指針值相等,指向同一數(shù)組元素的指針與這些元素的數(shù)組索引相同,以及指向struct成員按照這些成員的聲明順序進行比較。
許多實現(xiàn)還提供了隨機起源指針的嚴(yán)格總排序,例如,如果它們被實現(xiàn)為連續(xù)(“平坦”)虛擬地址空間內(nèi)的地址。
指向函數(shù)的指針可以用函數(shù)的地址初始化。由于功能到指針的轉(zhuǎn)換,操作符的地址是可選的:
void f(int);void (*pf1)(int) = &f;void (*pf2)(int) = f; // same as &f
與函數(shù)不同,指向函數(shù)的指針是對象,因此可以存儲在數(shù)組中,復(fù)制,分配,作為參數(shù)傳遞給其他函數(shù)等。
指向函數(shù)的指針可以在函數(shù)調(diào)用操作符的左側(cè)使用; 這會調(diào)用指向函數(shù):
#include <stdio.h>int f(int n){ printf("%d\n", n); return n*n;}int main(void){ int (*p)(int) = f; int x = p(7);}
解引用函數(shù)指針會得到指向函數(shù)的函數(shù)指示符:
int f();int (*p)() = f; // pointer p is pointing to f(*p)(); // function f invoked through the function designatorp(); // function f invoked directly through the pointer
平等比較運算符定義為指向函數(shù)的指針(如果指向相同的函數(shù),則它們相等)。
指向任何類型的對象的指針都可以隱式轉(zhuǎn)換為指針void
(可以是const或volatile限定的),反之亦然:
int n=1, *p=&n;void* pv = p; // int* to void*int* p2 = pv; // void* to int*printf("%d\n", *p2); // prints 1
void指針用于傳遞未知類型的對象,這在通用接口中很常見:malloc
返回值void*
,qsort
期望用戶提供的回調(diào)接受兩個const void*
參數(shù)。pthread_create需要用戶提供的接受和返回的回調(diào)void*
。在所有情況下,調(diào)用者有責(zé)任在使用前將指針轉(zhuǎn)換為正確的類型。
每種類型的指針都有一個特殊的值,稱為該類型的空指針值。值為空的指針不指向?qū)ο蠡蚝瘮?shù)(取消引用空指針是未定義的行為),并將相同類型的所有指針值相等,其值也為空。
要將指針初始化為空值或?qū)⒖罩蒂x予現(xiàn)有指針,可以使用空指針常量(NULL
或任何其他具有零值的整數(shù)常量)。靜態(tài)初始化還會初始化指向其空值的指針。
空指針可以指示沒有對象或可以用來指示其他類型的錯誤條件。通常,接收指針參數(shù)的函數(shù)幾乎總是需要檢查值是否為空,并以不同的方式處理該情況(例如,free
在傳遞空指針時什么也不做)。
盡管任何指向?qū)ο蟮闹羔樁伎梢赞D(zhuǎn)換為指向不同類型對象的指針,但是取消引用指向與對象的聲明類型不同的類型的指針幾乎總是未定義的行為。細(xì)節(jié)請參見嚴(yán)格的別名。
可以通過指針訪問對象的函數(shù),這些指針不是別名。詳情請參閱限制。 | (自C99以來) |
---|
數(shù)組類型的左值表達(dá)式在大多數(shù)上下文中使用時,會經(jīng)歷到指向數(shù)組第一個元素的指針的隱式轉(zhuǎn)換。詳情請看陣列。
char *str = "abc"; // "abc" is a char[4] array, str is a pointer to 'a'
指向char的指針通常用于表示字符串。為了表示一個有效的字節(jié)串,一個指針必須指向一個字符,它是一個char數(shù)組的元素,并且在某個索引處必須有一個char值為零的char大于或等于指針。