1、什么是指針氓侧?
通俗來講——指針就是變量脊另,用來儲(chǔ)存地址的變量。
2约巷、指針數(shù)組 & 數(shù)組指針
指針數(shù)組:它是一個(gè)數(shù)組偎痛,數(shù)組里面每個(gè)元素都是指針,數(shù)組的大小由它元素的個(gè)數(shù)決定独郎。?
數(shù)組指針:它是一個(gè)指針踩麦,它指向一個(gè)數(shù)組,指針的大小永遠(yuǎn)都是4字節(jié) 氓癌。
(1)int *p1[10]?
p1是指針數(shù)組谓谦,里面有10個(gè)元素,每個(gè)元素都是地址贪婉;
(2)int (*p2)[10]?
p2是數(shù)組指針反粥,這個(gè)指針指向一個(gè)有10個(gè)整型元素的數(shù)組。
兩者區(qū)分:
①我們要知道“[ ]”的優(yōu)先級(jí)比“ * ”的優(yōu)先級(jí)高疲迂,p1先與“[ ]”先集合才顿,這就構(gòu)成了數(shù)組的結(jié)構(gòu),數(shù)組名是p1尤蒿,里面存的元素的類型是 int *
②p2先和“ * ”結(jié)合郑气,構(gòu)成指針結(jié)構(gòu),指針名為p2腰池,int和[10]共同表示指針的類型竣贪,p2指向的是具有10個(gè)整型元素的數(shù)組军洼。
3、a和&a的區(qū)別
int main()
{
? ? char a[5] = { 'a', 'b', 'c', 'd', 'e' };
? ? char(*p1)[5] = &a;
? ? char(*p2)[5] = a;
? ? return 0;
}
p1和p2哪個(gè)是數(shù)組指針演怎?
此處p1和p2都是數(shù)組指針匕争,但最好采用p1這種寫法。?因?yàn)閍是代表數(shù)組首元素的地址爷耀,而&a才是代表整個(gè)數(shù)組的地址甘桑,兩者的值是一樣的,但所代表的意義是完全不同的歹叮。
4跑杭、地址強(qiáng)轉(zhuǎn)
下面代碼輸出結(jié)果是多少?
int main()
{
? ? int a[4] = { 1, 2, 3, 4 };
? ? int *p1 = (int *)(&a + 1);
? ? int *p2 = (int *)((int)a + 1);
? ? printf("%x, %x", p1[-1], *p2);
? ? return 0;
}
p1:把 &a+1的值強(qiáng)制轉(zhuǎn)換成 int * 再賦值給p1咆耿,此時(shí)p1指向數(shù)組a尾元素的下一個(gè)int型元素德谅。p1[-1]可以理解成 *(p1 - 1)。表示p1往前移動(dòng)sizeof(int)個(gè)字節(jié)萨螺,所以輸出0x4窄做。
p2:(int)a + 1表示把a(bǔ)強(qiáng)轉(zhuǎn)成整型數(shù)據(jù),再加1則(int)a + 1就是元素a[0]的第二個(gè)字節(jié)的地址慰技,然后再把這個(gè)地址強(qiáng)轉(zhuǎn)為int * 類型賦值給p2椭盏,那*p2的值就是從元素a[0]的第二個(gè)字節(jié)開始的連續(xù)4字節(jié)的內(nèi)容。
那么這連續(xù)4個(gè)字節(jié)內(nèi)容是什么呢吻商?這里就要區(qū)分大小端了掏颊,小端模式返回0x2000000;大端模式返回0x100艾帐。
注:
所謂的大端模式乌叶,就是高位字節(jié)排放在內(nèi)存的低地址端,低位字節(jié)排放在內(nèi)存的高地址端柒爸。
所謂的小端模式枉昏,就是低位字節(jié)排放在內(nèi)存的低地址端,高位字節(jié)排放在內(nèi)存的高地址端揍鸟。
5兄裂、函數(shù)指針
函數(shù)指針還是一個(gè)指針,它指向的是一個(gè)函數(shù)阳藻,這個(gè)指針變量里存的是一個(gè)函數(shù)的地址晰奖。
char * ( *fun)(char *p1, char *p2);
這里定義了一個(gè)函數(shù)指針,指針名為fun腥泥,指向函數(shù)fun匾南,這個(gè)函數(shù)的返回值類型是 char *,參數(shù)是char *p1, char *p2蛔外。
函數(shù)指針數(shù)組:
char * ( *pf)(char *p)這里定義了一個(gè)函數(shù)指針 pf蛆楞,既然如此那把這個(gè)指針放到數(shù)組里溯乒,這就形成了一個(gè)函數(shù)指針數(shù)組:
char * ( * pf[10])(char *p)
①數(shù)組名:pf
②數(shù)組元素:10個(gè)指向函數(shù)的指針。
③每個(gè)指針指向一個(gè)函數(shù)
④函數(shù)的返回類型為指向字符的指針豹爹,參數(shù)為一個(gè)指向字符的指針裆悄。
函數(shù)指針數(shù)組的用途:轉(zhuǎn)移表
函數(shù)指針數(shù)組指針:
函數(shù)指針數(shù)組指針就是一個(gè)指針, 這個(gè)指針指向一個(gè)數(shù)組臂聋,這個(gè)數(shù)組里存的是指向函數(shù)的指針光稼。
char * ( * (*pf)[10]) (char * p)
①這里定義了一個(gè)函數(shù)指針數(shù)組指針,指針變量名是pf孩等。
②指針指向一個(gè)有10個(gè)元素的數(shù)組艾君。
③數(shù)組里存的都是指向函數(shù)的指針。
④ 這些指針每個(gè)都指向一些函數(shù)肄方。
⑤指向的函數(shù)的返回值類型為指向字符的指針冰垄,參數(shù)為一個(gè)指向字符的指針肪虎。
記憶方法:
函數(shù)指針數(shù)組指針數(shù)組指針泛烙。
我們從右往左分析:
①指針:*pf
②數(shù)組指針:(* pf)[5]
③指針數(shù)組指針:(* (* pf) )[5]
④數(shù)組指針數(shù)組指針:( (* (* pf) )[5])[3]
⑤指針數(shù)組指針數(shù)組指針:( * ( (* (* pf) )[5]) )[3]
⑥函數(shù)指針數(shù)組指針數(shù)組指針:void * ( ( * ( (* (* pf) )[5]) )[3] ) ( )
分析(*(void(*)())0)()
①void(*)() 是一個(gè)函數(shù)指針類型愿汰,這個(gè)函數(shù)無參數(shù)蔚鸥,無返回值。
②(void(*)())0 把0強(qiáng)轉(zhuǎn)成函數(shù)指針類型碉渡,0是一個(gè)函數(shù)的首地址。
③(*(void(*)())0) 把地址為0的函數(shù)取出來。
④(*(void(*)())0)()拾徙,函數(shù)調(diào)用。