欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

目錄

柚子快報(bào)激活碼778899分享:c++ 指針的進(jìn)階

柚子快報(bào)激活碼778899分享:c++ 指針的進(jìn)階

http://yzkb.51969.com/

指針的進(jìn)階

本文旨在探討指針的高階妙用,默認(rèn)大家已經(jīng)對(duì)指針的基本概念已經(jīng)熟練掌握。

一、字符指針

字符指針的賦值

先創(chuàng)建字符串,再賦值給指針創(chuàng)建字符串時(shí),就賦值給指針

代碼示例

直接跟著代碼來(lái)分析它們的區(qū)別吧:

int main()

{

/*方式1:先創(chuàng)建字符串,再賦值給指針*/

char arr[] = "abcd"; // 在內(nèi)存中創(chuàng)建了一個(gè)字符數(shù)組,并將數(shù)組的初值賦值為a,b,c,d,\0

char* p1 = arr; // 將內(nèi)存中創(chuàng)建的數(shù)組首地址賦值給了p1指針

*p1 = "W"; // 數(shù)組中的第一個(gè)元素‘a(chǎn)’,被修改為了‘w’

/*方式2:創(chuàng)建字符串時(shí),就賦值給指針*/

char* p2 = "abcd"; // 在內(nèi)存中創(chuàng)建了一個(gè)"abcd"常量字符串,并且把這個(gè)字符串的首地址賦值給了p2

*p2 = "W"; // 這句代碼雖然編譯可能不會(huì)報(bào)錯(cuò),但是運(yùn)行會(huì)崩潰,因?yàn)槌A渴遣荒鼙恍薷牡?/p>

return 0;

}

代碼解析

char* p1 = arr; 代碼解析:

將內(nèi)存中已經(jīng)創(chuàng)建并初始化完成的字符數(shù)組arr的首地址賦值給了p1指針。

char* p2 = "abcd";代碼解析:

先在內(nèi)存中創(chuàng)建一個(gè)常量字符串,然后把這個(gè)字符串的首地址賦值給了p2指針。

通過(guò)*p2 = "W";想給常量字符串賦值時(shí),程序會(huì)崩潰(因?yàn)槌A坎荒鼙恍薷模?。所以,如果確實(shí)想使用char* p2 = "abcd";的方式給指針賦值,建議在前面加上const修飾符,const char* p2 = "abcd";聲明這個(gè)指針指向的是一個(gè)常量?!?/p>

進(jìn)階思考

想想以下代碼段的輸出結(jié)果:

int main()

{

char arr1[] = "abcd";

char arr2[] = "abcd";

char* arr3 = "abcd";

char* arr4 = "abcd";

printf("%d\n", arr1 == arr2); // 輸出結(jié)果為0,arr1和arr2值不相等,因?yàn)樗麄冎赶虻氖遣徽J(rèn)同的內(nèi)存空間

printf("%d\n", arr3 == arr4); // 輸出結(jié)果為1,arr3和arr4值相等,因?yàn)樗麄冎赶虻亩际莾?nèi)存中的同一個(gè)字符串常量

return 0;

}

別忘了,在arr3和arr4的前面要加上const修飾符,養(yǎng)成良好編程規(guī)范。

二、指針數(shù)組

語(yǔ)法:類型名* 數(shù)組名[數(shù)組長(zhǎng)度]

定義:指針數(shù)組是一種特殊的數(shù)組,其中每個(gè)元素都是指針。這意味著指針數(shù)組中的每個(gè)元素都指向另一個(gè)內(nèi)存位置或?qū)ο蟆?/p>

代碼示例:例如如下代碼段,可以使用指針數(shù)組作為函數(shù)參數(shù),對(duì)一組字符串進(jìn)行排序?。

void sort_strings(char **str, int n) {

// 實(shí)現(xiàn)排序算法,如冒泡排序等

}

int main() {

char strs[] = {"lisi", "hahaha", "hehehe", "helloa", "leihoua", "lisi", "nihaoa", "wangwu", "ajax", "bureau"};

char *pstr; // 定義指針數(shù)組

for(int i = 0; i < 10; i++) {

pstr[i] = strs[i]; // 將字符串地址存入指針數(shù)組

}

sort_strings(pstr, 10); // 對(duì)字符串進(jìn)行排序

// 輸出排序后的字符串

for(int i = 0; i < 10; i++) {

printf("%s\n", pstr[i]);

}

return 0;

}

三、數(shù)組指針

數(shù)組指針是一個(gè)指向數(shù)組類型的指針

數(shù)組指針操作一維數(shù)組

先來(lái)看看以下代碼:

int main()

{

int arr[3] = {1,2,3};

int (*p1)[3] = &arr;

int* p2 = arr;

/*使用數(shù)組指針,遍歷一維數(shù)組,方式1:先解引用,再用下標(biāo)取值*/

for(int i = 0; i < 3; i++)

{

printf("%d\n", (*p1)[i]);

}

/*使用數(shù)組指針,遍歷一維數(shù)組,方式2:先解引用,再移動(dòng)指針步長(zhǎng),再解引用*/

for(int i = 0; i < 3; i++)

{

printf("%d\n", *(*p1+i));

}

/*使用整型指針遍歷一維數(shù)組:直接移動(dòng)指針,再解引用即可*/

for(int i = 0; i < 3; i++)

{

printf("%d\n", *(p2+i)); //*(p2+i)等價(jià)于p2[i]

}

}

有沒(méi)有覺(jué)得使用int (*p1)[3]遍歷一維數(shù)組生澀難用。實(shí)際上,遍歷一維數(shù)組時(shí),我們更多的是直接使用普通指針(int* p2的方式)。數(shù)組指針在訪問(wèn)二維數(shù)組時(shí),才會(huì)體現(xiàn)它的妙用。

數(shù)組指針操作二維數(shù)組

先明確一點(diǎn),數(shù)組指針指向的是數(shù)組首元素的地址。那么一個(gè)二維數(shù)組arr[i][j]的首元素是誰(shuí)?是arr[0][0]嗎?

當(dāng)然不是,arr[0]才是這個(gè)二維數(shù)組的首元素,arr[0][0]是這個(gè)二維數(shù)組中的第個(gè)元素arr[0]中的第一個(gè)元素。來(lái)看看以下代碼:

int main()

{

int arr[2][3] = {{1,2,3},{4,5,6}};

int (*p1)[3] = arr;

/* 以下幾種操作二維數(shù)組的方式都是等價(jià)的 */

printf("%d\n", arr[1][2]);

printf("%d\n", *(*(p1+1) +2));

printf("%d\n", *(p1[1]+2));

printf("%d\n", p1[1][2]);

}

arr[1][2]:直接使用數(shù)組名訪問(wèn)數(shù)組 *(*(p1+1) +2):arr這個(gè)二維數(shù)組中存儲(chǔ)了2個(gè)數(shù)組類型的元素

p1+1使指針從數(shù)組首地址偏移了一個(gè)元素的長(zhǎng)度,也就是指向了"{4,5,6}"這個(gè)數(shù)組的首地址。 *(p1+1)在上一步的基礎(chǔ)上對(duì)指針進(jìn)行解引用,拿到了"{4,5,6}"這個(gè)數(shù)組首地址的值。(是數(shù)組首地址的值,不是數(shù)組首地址里面的值) *(p1+1) +2在上一步的基礎(chǔ)上,指針偏移了一個(gè)元素的長(zhǎng)度,也就是指向了"{4,5,6}"這個(gè)數(shù)組中的元素’6’的地址。 *(*(p1+1) +2)在上一步的基礎(chǔ)上,對(duì)指針進(jìn)行解引用,拿到了真正的數(shù)據(jù),也就是6這個(gè)數(shù)。 *(p1[1]+2):在上一節(jié)數(shù)組指針操作一維數(shù)組中,我們提到了*(p1+1)與p1[1]是等價(jià)的。所以*(p1[1]+2)和*(*(p1+1) +2)也是等價(jià)的。 p1[1][2]:參考第三點(diǎn)的邏輯,*(p1[1]+2)與p1[1][2]也是等價(jià)的。

一維數(shù)組傳參

一維數(shù)組在函數(shù)間傳遞的幾種方式:

void test1(int arr[3]){}; // 正確寫(xiě)法

void test2(int arr[){}; // 正確寫(xiě)法,一維度數(shù)傳參時(shí),形參可以省略元素個(gè)數(shù)

void test3(int* p){}; // 正確寫(xiě)法,使用數(shù)組指針傳遞一維數(shù)組

void test4(int* p[3]){}; // 正確寫(xiě)法,使用數(shù)組指針傳遞一維的指針數(shù)組

void test5(int **p){}; // 正確寫(xiě)法,使用二級(jí)指針,傳遞一維的指針數(shù)組

int main()

{

int arr[3] = {1,2,3;

int arr2[3] = {0};

test1(arr);

test2(arr);

test3(arr);

test4(arr2);

test5(arr2);

test4(arr); // 語(yǔ)法正確,但是不推薦使用數(shù)組指針接收除指針數(shù)組外的其他類型一維數(shù)組

test5(arr); // 語(yǔ)法錯(cuò)誤,編譯會(huì)報(bào)錯(cuò),二級(jí)指針不能接收除指針數(shù)組外的其他類型一維數(shù)組

}

思考:

為什么形參使用int arr[m]的方式接收數(shù)組時(shí),m可以省略?

為什么形參使用int (*p)[n]的方式接收數(shù)組時(shí),n能省略?

答:當(dāng)對(duì)指向一維數(shù)組的指針進(jìn)行步數(shù)長(zhǎng)+1時(shí),不需要知道元素個(gè)數(shù),只要知道元素類型即可。

二維數(shù)組傳參

二維數(shù)組在函數(shù)間傳遞的幾種方式:

void test1(int arr[2][3]){};// 正確寫(xiě)法,行列都確定個(gè)數(shù)

void test2(int arr[][3]){}; // 正確寫(xiě)法,列確認(rèn)元素個(gè)數(shù),行省略元素個(gè)數(shù)

void test2(int arr[][3]){}; // 錯(cuò)誤寫(xiě)法,列省略元素個(gè)數(shù),行確認(rèn)元素個(gè)數(shù)

void test3(int arr[][]){}; // 錯(cuò)誤寫(xiě)法,行列都省元素個(gè)數(shù)

void test4(int *p){}; // 錯(cuò)誤寫(xiě)法,使用基本類型的指針接收二維數(shù)組后,對(duì)數(shù)組進(jìn)行操作時(shí)會(huì)發(fā)生不可預(yù)知的錯(cuò)誤

void test5(int **p){}; // 錯(cuò)誤寫(xiě)法,使用二級(jí)指針接收二維數(shù)組后,對(duì)數(shù)組進(jìn)行操作時(shí)會(huì)發(fā)生不可預(yù)知的錯(cuò)誤

void test6(int (*p)[3]){}; // 正確寫(xiě)法,使用數(shù)組指針傳遞二維數(shù)組

void test7(int *p){}; // 錯(cuò)誤寫(xiě)法,使用數(shù)組指針傳遞二維數(shù)組時(shí),需要確定數(shù)組首元素中的元素個(gè)數(shù)

int main()

{

int arr[2][3] = {{1,2,3},{4,5,6}};

test1(arr);

test2(arr);

test3(arr);

test4(arr);

test5(arr);

test6(arr);

test7(arr);

}

總結(jié):

二維數(shù)組傳參時(shí),如果形參使用int arr[m][n]的方式接收實(shí)參,形參的行個(gè)數(shù)可以省略,列個(gè)數(shù)不能省略。二維數(shù)組傳參時(shí),如果形參使用指針的方式接收實(shí)參,必須使用數(shù)組指針int (*p)[n]的方式,且n不能省略。

思考:

為什么形參使用int arr[m][n]的方式接收數(shù)組時(shí),m可以省略,n不能省略?

為什么形參使用int (*p)[n]的方式接收數(shù)組時(shí),n不能省略?

答:當(dāng)對(duì)指向二維數(shù)組的指針進(jìn)行步數(shù)長(zhǎng)+1時(shí),需要根據(jù)列的個(gè)數(shù)n來(lái)決定指針跨域多少個(gè)地址長(zhǎng)度。

指針數(shù)組傳參

void test4(int** p){}; // 正確寫(xiě)法,傳遞指針數(shù)組時(shí),需要用到二級(jí)指針。

int main()

{

int* arr[10];

test1(arr);

}

五、函數(shù)指針

函數(shù)指針的創(chuàng)建

函數(shù)指針是一個(gè)指向函數(shù)的指針

函數(shù)指針創(chuàng)建語(yǔ)法:函數(shù)返回值類型 (*變量名)(函數(shù)參數(shù)類型) = 函數(shù)名

函數(shù)指針創(chuàng)建語(yǔ)法說(shuō)明:

函數(shù)返回值類型:說(shuō)明函數(shù)指針指向函數(shù)的返回值類型(*變量名):加()是為了讓*與變量名相結(jié)合,說(shuō)明這是一個(gè)指針類型的變量(函數(shù)參數(shù)類型):根據(jù)函數(shù)指針指向函數(shù)的參數(shù)列表進(jìn)行填寫(xiě),不同的函數(shù)有不同的參數(shù),這里可以省略函數(shù)形參列表中的函數(shù)名,保留形參類型即可。

int Add(int a ,int b)

{

return a+b;

}

int main()

{

int a = 1;

int b = 2;

int (*p)(int,int) = Add;

printf("%p\n",(*p)(a,b));

printf("%p\n", Add); // 打印結(jié)果為函數(shù)Add的起始地址

printf("%p\n", &Add); // 在對(duì)函數(shù)名取地址時(shí),Add與&Add是等價(jià)的,打印結(jié)果都是函數(shù)Add的起始地址

printf("%p\n", p); // 打印結(jié)果為函數(shù)Add的起始地址,因?yàn)橹羔楶中存的是函數(shù)起始地址

}

思考:

void (*p)();與void *p();的區(qū)別是什么?

首先明確一點(diǎn),按照運(yùn)算符的優(yōu)先級(jí),()>*>數(shù)據(jù)類型。

在void (*p)();中,(*p)會(huì)先結(jié)合,表明這是一個(gè)指針。然后(*p)()相結(jié)合,表明這個(gè)指針指向的是一個(gè)無(wú)參的函數(shù),最后void (*p)()再結(jié)合,表明這個(gè)指針指向的無(wú)參函數(shù)的返回值是void類型。

在void *p();中,p()會(huì)先結(jié)合,表明這是一個(gè)無(wú)參函數(shù)。然后*p()再結(jié)合,表明這個(gè)無(wú)參函數(shù)的返回值是一個(gè)指針。最后void *p()再結(jié)合,表明這個(gè)無(wú)參函數(shù)的返回值是一個(gè)int類型的指針。

函數(shù)指針的使用

函數(shù)指針的調(diào)用推薦語(yǔ)法:(*指針名)(實(shí)參列表);

函數(shù)指針的調(diào)用推薦語(yǔ)法說(shuō)明:

(*指針名):表示對(duì)函數(shù)指針解引用,拿到指針指向的值,也就是函數(shù)起始地址。(實(shí)參列表):表示調(diào)用函數(shù)時(shí),需要傳遞的參數(shù)值。

思考:

為什么這里叫函數(shù)指針的調(diào)用推薦語(yǔ)法,來(lái)看看以下代碼段。實(shí)際上,指針P前面加不加*號(hào),加幾個(gè)*號(hào)都不影響函數(shù)指針的調(diào)用的。個(gè)人覺(jué)得(*p)(a,b)的方式更容易理解。業(yè)界也有很多人用 p(a,b)的方式,要記得這也是正確語(yǔ)法。

int Add(int a ,int b)

{

return a+b;

}

int main()

{

int a = 1;

int b = 2;

int (*p)(int,int) = Add;

printf("%p\n", p(a,b)); // 正確語(yǔ)法, 輸出結(jié)果為3

printf("%p\n",(*p)(a,b)); // 正確語(yǔ)法, 輸出結(jié)果為3

printf("%p\n",(**p)(a,b)); // 正確語(yǔ)法, 輸出結(jié)果為3

printf("%p\n",(***p)(a,b)); // 正確語(yǔ)法, 輸出結(jié)果為3

}

函數(shù)指針經(jīng)典案例

學(xué)會(huì)函數(shù)指針的創(chuàng)建與使用足以滿足大部分使用場(chǎng)景,下面列舉兩種函數(shù)指針的進(jìn)階組合,加強(qiáng)對(duì)函數(shù)指針的掌握。

請(qǐng)解讀(*(void (*)())0)();

按照從左到右的順序,找到最先被執(zhí)行的()為(*),表明這是一個(gè)指針;按照運(yùn)算符的優(yōu)先級(jí),(*)()會(huì)先結(jié)合,表明這是一個(gè)函數(shù)指針;按照運(yùn)算符的優(yōu)先級(jí),void (*)()會(huì)結(jié)合,表明這是一個(gè)指向返回值是void類型函數(shù)的函數(shù)指針;按照運(yùn)算符的優(yōu)先級(jí),(void (*)()) 0會(huì)結(jié)合。還記得C語(yǔ)言怎么類型轉(zhuǎn)換嗎(轉(zhuǎn)換類型)待轉(zhuǎn)換的數(shù)據(jù);,例如float y = (float) 10;。這里也是一樣的,指的是將0轉(zhuǎn)換稱為了void (*)()類型。也就是說(shuō)這個(gè)函數(shù)指針指向了地址為0的函數(shù)。按照運(yùn)算符的優(yōu)先級(jí),* (void (*)()) 0會(huì)結(jié)合,對(duì)函數(shù)指針*解引用,拿到了里面的值,也就是函數(shù)的起始地址0。按照運(yùn)算符的優(yōu)先級(jí),(*(void (*)()) 0)()會(huì)結(jié)合。上一節(jié)中我們提到了調(diào)用函數(shù)指針指的語(yǔ)法為(*指針名)(實(shí)參列表)。上一步中,我們已經(jīng)拿到了函數(shù)的起始地址,最后一步,實(shí)際上是調(diào)用了起始地址0的函數(shù),最后面的()是它的參數(shù)列表,因?yàn)槭且粋€(gè)空參函數(shù),所以調(diào)用時(shí)不需要傳遞參數(shù)。 請(qǐng)解讀void (*signal(int, void(*)(int)))(int);

經(jīng)過(guò)上1道題的進(jìn)階,這道題應(yīng)該很快能看出來(lái)void(*)(int)會(huì)最先組合,表示這是一個(gè)參數(shù)列表為int類型,返回值為void類型的函數(shù)指針。 其次signal(int, void(*)(int))會(huì)結(jié)合,這里我們能看出來(lái),signal函數(shù)有2個(gè)參數(shù)類型,分別為int和void(*)(int)。通過(guò)這一點(diǎn),我們能分析出當(dāng)前正在定義一個(gè)名為signal的函數(shù)。為什么是正在定義而不是調(diào)用?想一想,如果是調(diào)用的話,參數(shù)列表里填的應(yīng)該是實(shí)際的參數(shù),而不是參數(shù)類型。 經(jīng)過(guò)上一步分析,我們知道了當(dāng)前正在定義signal(類型1,類型2)函數(shù)。函數(shù)定義就要有函數(shù)返回類型,它的返回類型是什么?這里我們發(fā)(*signal(int, void(*)(int))并不能很好的結(jié)合在一起,它不能被解讀為“返回值是一個(gè)沒(méi)有類型的指針”。 現(xiàn)在我們的思路返回步驟2,我們已經(jīng)確定了signal(int, void(*)(int))這部分內(nèi)容是正在定義一個(gè)名為signal的函數(shù)。實(shí)際上,除了signal(int, void(*)(int)),這段代碼剩余的部分,也就是void (* )(int)就是這個(gè)函數(shù)的返回值類型,沒(méi)錯(cuò),signal函數(shù)的返回值類型是一個(gè)指向“參數(shù)列表為int,返回值為void類型函數(shù)"的函數(shù)指針類型。這里非常容易繞暈,但是定義一個(gè)函數(shù)的返回值類型是一個(gè)函數(shù)指針時(shí)就是這么混亂。感興趣的兄弟可以百度一下如何定義一個(gè)函數(shù)的返回值類型是一個(gè)函數(shù)指針。 // 下面列舉了聲明一個(gè)函數(shù)返回值為函數(shù)指針的2種類方式,一般編碼更推薦宏定義的方式。

// 方式1: 直接定義函數(shù),同時(shí)聲明返回值是一個(gè)而函數(shù)指針

void (*signal(int, void(*)(int)))(int);

// 方式2: 先宏定義一個(gè)函數(shù)指針類型,再定義函數(shù)

typedef void void(* pfun_t )(int);

pfun_t signal(int, pfun_t);

六、函數(shù)指針數(shù)組

初識(shí)函數(shù)指針數(shù)組

解釋:函數(shù)指針數(shù)組,指的首先是一個(gè)數(shù)組,數(shù)組中的元素都是函數(shù)指針類型

語(yǔ)法:函數(shù)返回值類型 (*數(shù)組名[數(shù)組長(zhǎng)度])(函數(shù)參數(shù)類型)

案例:int (*pa[4])(int, int),定義了一個(gè)長(zhǎng)度為4的數(shù)組,數(shù)組中的元素為int (*)(int, int)類型\

代碼:

int Add(int x,int y){return x+y};

int Sub(int x,int y){return x-y};

int Mul(int x,int y){return x*y};

int Sub(int x,int Mulreturn x-y};

int main()

{

// 定義函數(shù)指針數(shù)組

int (*parr[4])(int, int) = {Add, Sub, Mul, Div};

// 遍歷函數(shù)指針數(shù)組,調(diào)用里面指向的各函數(shù)

for(int i = 0; i<4; i++)

{

printf("%d\n",parr[i](2,3));

}

}

如何使用函數(shù)指針數(shù)組

函數(shù)指針數(shù)組是一種特殊的數(shù)據(jù)結(jié)構(gòu),它允許我們將函數(shù)的地址存儲(chǔ)在數(shù)組中,從而實(shí)現(xiàn)通過(guò)索引直接調(diào)用不同的函數(shù),這種機(jī)制被稱為轉(zhuǎn)移表。

轉(zhuǎn)移表的實(shí)現(xiàn)可以通過(guò)選擇或循環(huán)語(yǔ)句子和函數(shù)指針數(shù)組結(jié)合使用。例如,我們可以根據(jù)用戶輸入的不同選項(xiàng),通過(guò)選擇語(yǔ)句選擇調(diào)用函數(shù)指針數(shù)組中對(duì)應(yīng)的函數(shù)。這種方式在實(shí)現(xiàn)計(jì)算器程序等應(yīng)用中特別有用,其中不同的運(yùn)算(如加、減、乘、除)可以通過(guò)函數(shù)指針數(shù)組來(lái)實(shí)現(xiàn),用戶界面則通過(guò)簡(jiǎn)單的輸入選擇來(lái)決定調(diào)用哪個(gè)函數(shù)進(jìn)行計(jì)算。例如以下代碼段,就使用do/while循環(huán)+if條件判斷+函數(shù)指針數(shù)組實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的計(jì)算器功能:

int Add(int x,int y){return x+y};

int Sub(int x,int y){return x-y};

int Mul(int x,int y){return x*y};

int Sub(int x,int Mulreturn x-y};

void Manue()

{

printf("*******計(jì)算器*******\n");

printf("**1. 加法 2. 減法**\n");

printf("**3. 乘法 4. 除法**\n");

printf("**0. 退出計(jì)算器 **\n");

};

int main()

{

int (*parr[5])(int, int) = {0, Add, Sub, Mul, Div}; // 定義函數(shù)指針數(shù)組,提前封裝好加減乘除需要用到的不同函數(shù)

int input = 0;

int x = 0;

int y = 0;

do()

{

Manue();

printf("請(qǐng)輸入您想要進(jìn)行的運(yùn)算:");

scanf("%d", &input);

if(0)

{

printf("程序退出.\n");

}else if(1 < input && 4 > input)

{

printf("請(qǐng)輸入兩個(gè)操作數(shù),以逗號(hào)隔開(kāi):");

scanf("%d,%d", &x, &y);

int ret = (*parr)[i](x,y);

printf("運(yùn)算結(jié)果為:%d", ret);

}

else

{

printf("參數(shù)錯(cuò)誤,請(qǐng)重新輸入.\n");

}

}while(input); // 函數(shù)指針數(shù)組的首元素是0,當(dāng)用用戶輸入0時(shí),會(huì)跳出循環(huán),函數(shù)結(jié)束。

}

七、指向函數(shù)指針數(shù)組的指針

定義:指向函數(shù)指針數(shù)組的指針,指的首先是一個(gè)指針,這指針指向的是一個(gè)數(shù)組,且數(shù)組中的元素都是函數(shù)指針類型。

語(yǔ)法:函數(shù)返回值類型 (*(*數(shù)組名)[數(shù)組長(zhǎng)度])(函數(shù)參數(shù)類型)

代碼示例:

int Add(int a, int b)

{

reture a+b;

}

int main()

{

int (*p1)(int, int) = Add; // 將函數(shù)Add傳遞給函數(shù)指針p1

int (*p2[1])(int, int) = {p1}; // 將函數(shù)指針p1,傳遞給函數(shù)指針數(shù)組p2作為首元素

int (*(*p3)[1])(int, int) = &p2; // 將函數(shù)指針數(shù)組p2的首地址,傳遞給指向函數(shù)指針數(shù)組的指針p3

}

八、回調(diào)函數(shù)

定義:回調(diào)函數(shù)就是通過(guò)一個(gè)函數(shù)指針調(diào)用的函數(shù)。如果把函數(shù)的地址作為參數(shù)傳遞給另一個(gè)函數(shù),當(dāng)這個(gè)指針被用來(lái)調(diào)用其所指向的函數(shù)時(shí),我們就說(shuō)這是回調(diào)函數(shù)。回調(diào)函數(shù)不是由該函數(shù)的實(shí)現(xiàn)方直接調(diào)用,而是在特定的事件或條件發(fā)生時(shí),由另一方調(diào)用的,用于對(duì)該事件或條件進(jìn)行相應(yīng)。

代碼:

例如以下代碼段,為調(diào)用C語(yǔ)言庫(kù)函數(shù)qsort對(duì)不同類型數(shù)組排序的案例,marin方法只負(fù)責(zé)將資源調(diào)度給qsort函數(shù)進(jìn)行處理,并不關(guān)心它們之間的業(yè)務(wù)關(guān)系,只關(guān)注最終的處理結(jié)果:

#include

#include

struct Student

{

char name[20];

int age;

};

// arr_int數(shù)組比較大小的函數(shù)

int cmp_int(const void *e1,const void *e2)

{

return (int)(*(int*)e1 -*(int*)e2);

}

// arr_db數(shù)組比較大小的函數(shù)

int cmp_double(const void *e1,const void *e2)

{

return (int)(*(double*)e1 -*(double*)e2);

}

// arr_std數(shù)組比較大小的函數(shù)

int cmp_student(const void *e1,const void *e2)

{

return (int)((*(struct Student*)e1).age -(*(struct Student*)e2).age);

}

int main()

{

int arr_int[] = {9,8,7,6,5,4,3,2,1};

double arr_db[] = {9.9,8.8,7.7,6.6,5.5,4.4,3.3,2.2,1.1};

struct Student arr_std[] = {{"zhangsan",10},{"lisi",20},{"wangwu",8}};

/*

qsort是C語(yǔ)言庫(kù)中提供的快速排序方法,可以實(shí)現(xiàn)對(duì)任意類型的數(shù)據(jù)排序

參數(shù)1:void *類型,要求傳入待排序的數(shù)組

參數(shù)2:size_t類型,要求傳入待排序數(shù)組的元素個(gè)數(shù)

參數(shù)3:size_t類型,要求傳入待排序數(shù)組單個(gè)元素的所占空間大小

慘數(shù)4:int(*)(const void*, const void*)類型,要求傳遞入待排序數(shù)組元素比較大小的函數(shù)

*/

qsort(arr_int, sizeof (arr_int)/sizeof (arr_int[0]), sizeof(arr_int[0]), cmp_int);

qsort(arr_db, sizeof (arr_db)/sizeof (arr_db[0]), sizeof(arr_db[0]), cmp_double);

qsort(arr_std, sizeof (arr_std)/sizeof (arr_std[0]), sizeof(arr_std[0]), cmp_student);

/*

經(jīng)過(guò)以上排序arr_int、arr_db,arr_std數(shù)組都被排成了升序,感興趣的同學(xué)可以打印結(jié)果看一看。

這里要強(qiáng)調(diào)的主要是cmp_int()、cmp_double()、cmp_student()函數(shù)在這個(gè)案例中都屬于回調(diào)函數(shù)

它們都是在qsort()內(nèi)部通過(guò)函數(shù)z

*/

return 0;

}

九、void類型指針

學(xué)過(guò)指針基礎(chǔ)的同學(xué),應(yīng)該對(duì)void類型的指針已經(jīng)很熟悉了,這里我們簡(jiǎn)單的明確下void類型的指針都有哪些使用上的限制即可。

void* 類型的指針,可以接收任意類型的地址void* 類型的指針,不能進(jìn)行解引用操作void* 類型的指針,不能進(jìn)行指針移動(dòng)

柚子快報(bào)激活碼778899分享:c++ 指針的進(jìn)階

http://yzkb.51969.com/

參考閱讀

評(píng)論可見(jiàn),查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。

轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://gantiao.com.cn/post/19519613.html

發(fā)布評(píng)論

您暫未設(shè)置收款碼

請(qǐng)?jiān)谥黝}配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問(wèn)

文章目錄