C語言的羅盤指針——深入理解C語言指針及其應(yīng)用
??前面的話??
前面已經(jīng)簡(jiǎn)要介紹了數(shù)組指針,字符串庫函數(shù)和指針等內(nèi)容,在這篇文章我們將繼續(xù)深入了解有關(guān)字符串庫函數(shù)和指針的探索。
1.字符指針與字符串
字符指針即指向字符類型的指針。
char* pch = NULL; char ch = 's'; pch = &ch;//字符指針
1.1字符指針與字符串的關(guān)系
在C語言中,并沒有字符串這種數(shù)據(jù)類型,但是在編程中又常常遇到字符串,那在C語言中然后去表達(dá)字符串呢?
有兩種方式,一是使用字符數(shù)組表示字符串,本質(zhì)上就是定義一個(gè)char類型的數(shù)組變量去儲(chǔ)存字符串,使用字符數(shù)組表示字符串得到的是一個(gè)字符串變量,它是能夠被修改的;二是使用字符指針的方式去表達(dá)字符串,本質(zhì)上就是使用一個(gè)char指針指向字符串的第一個(gè)字符,因?yàn)樵谳敵鲎址臅r(shí)候計(jì)算機(jī)是以
有兩種方式,一是使用字符數(shù)組表示字符串,本質(zhì)上就是定義一個(gè)char類型的數(shù)組變量去儲(chǔ)存字符串,使用字符數(shù)組表示字符串得到的是一個(gè)字符串變量,它是能夠被修改的;二是使用字符指針的方式去表達(dá)字符串,本質(zhì)上就是使用一個(gè)char指針指向字符串的第一個(gè)字符,因?yàn)樵谳敵鲎址臅r(shí)候計(jì)算機(jī)是以\0為標(biāo)志來打印字符串的。但是要注意的是,它和使用字符數(shù)組不同,字符數(shù)組定義的是一個(gè)字符串變量,而字符指針定義的是一個(gè)字符串常量,是不能進(jìn)行修改的。
為標(biāo)志來打印字符串的。但是要注意的是,它和使用字符數(shù)組不同,字符數(shù)組定義的是一個(gè)字符串變量,而字符指針定義的是一個(gè)字符串常量,是不能進(jìn)行修改的。#include
:bulb:運(yùn)行結(jié)果:
str1:Come on, China Olympic Games! str2:Come on, China Olympic Games! D:\gtee\C-learning-code-and-project\test_813\Debug\test_813.exe (進(jìn)程 6960)已退出,代碼為 0。 按任意鍵關(guān)閉此窗口. . .
如果不小心對(duì)字符串常量修改,會(huì)引發(fā)讀寫訪問沖突的異常,對(duì)于VS這個(gè)異常只有在調(diào)試的時(shí)候才能看得見而在編譯的時(shí)候是不會(huì)報(bào)警告或者報(bào)錯(cuò)的,萬一是在一個(gè)很大的工程中出現(xiàn)了這種問題,是很難察覺的,所以一般定義一個(gè)不能被修改的變量或常量的時(shí)候,一般在定義的數(shù)據(jù)類型前面加上一個(gè)const,這樣如果不小心修改了這個(gè)const修飾的變量或常量,編譯器在編譯的時(shí)候就會(huì)報(bào)錯(cuò),這樣就能更容易地發(fā)現(xiàn)讀寫沖突異常的情況。
:bulb:面試題:
#include
使用字符數(shù)組表達(dá)的是字符串變量,本質(zhì)就是數(shù)組,每個(gè)數(shù)組是獨(dú)立儲(chǔ)存的,所以就算兩個(gè)數(shù)組儲(chǔ)存相同的內(nèi)容,但是兩者地址一定是不相同的。
而使用字符指針表達(dá)的是字符串常量,所以內(nèi)容相同,字符指針指向的就是同一個(gè)地址。
知道了這個(gè)區(qū)別,那這道面試題也能迎刃而解了。
:bulb:運(yùn)行結(jié)果:
str1 and str2 are not same str3 and str4 are same D:\gtee\C-learning-code-and-project\test_813\Debug\test_813.exe (進(jìn)程 16488)已退出,代碼為 0。 按任意鍵關(guān)閉此窗口. . .
1.2常用的幾個(gè)字符串庫函數(shù)
在前面介紹字符數(shù)組的時(shí)候簡(jiǎn)要提到了這幾個(gè)與字符串相關(guān)的庫函數(shù),現(xiàn)在我將詳細(xì)介紹這些常用的庫函數(shù)。
1.2.1輸出輸入字符串的函數(shù)
puts(字符數(shù)組);//輸出 int puts(const char* string); gets(字符數(shù)組);//輸入 char* gets(char* buffer);
:mag_right:puts:函數(shù)所在庫為stdio.h;函數(shù)參數(shù)為const修飾的char*類型(使用const修飾是為了防止字符串被修改);函數(shù)返回值為int,如果函數(shù)執(zhí)行失敗則會(huì)返回EOF。
:mag_right:gets:函數(shù)所在庫為stdio.h;函數(shù)參數(shù)為char*類型(從緩沖區(qū)讀取一行字符串,buffer是緩沖區(qū)的意思);函數(shù)返回值為char*(字符串的第一個(gè)元素地址),函數(shù)不能傳入空指針,如果函數(shù)執(zhí)行失敗會(huì)返回EOF。
用puts和gets函數(shù)只能輸出或輸入一個(gè)字符串。
puts作用:將一個(gè)字符串(以′
puts作用:將一個(gè)字符串(以′\0′結(jié)束的字符序列)輸出到終端。
′結(jié)束的字符序列)輸出到終端。用puts函數(shù)輸出的字符串中可以包含轉(zhuǎn)義字符。
在用puts輸出時(shí)將字符串結(jié)束標(biāo)志′
在用puts輸出時(shí)將字符串結(jié)束標(biāo)志′\0′轉(zhuǎn)換成′\n′,即輸出完字符串后換行。
′轉(zhuǎn)換成′\n′,即輸出完字符串后換行。gets作用:從終端輸入一個(gè)字符串到字符數(shù)組,并且得到一個(gè)函數(shù)值。該函數(shù)值是字符數(shù)組的起始地址。
1.2.2字符串連接函數(shù)
strcat(字符串1, 字符串2); char *strcat( char *strDestination, const char *strSource );
:mag_right:strcat:函數(shù)所在庫為string.h;函數(shù)參數(shù)有兩個(gè),第一個(gè)為char*類型(目的字符串地址)第二個(gè)參數(shù)為const char*類型(被連接字符串的地址);函數(shù)返回值為char*(返回strDestination的元素地址)。
strcat函數(shù)將strSource追加到strDestination后面。
strcat作用:把兩個(gè)字符數(shù)組中的字符串連接起來,把字符串2接到字符串1的后面,結(jié)果放在字符數(shù)組1中,函數(shù)調(diào)用后得到一個(gè)函數(shù)值——字符數(shù)組1的地址。
字符數(shù)組1必須足夠大,以便容納連接后的新字符串。
連接前兩個(gè)字符串的后面都有′
連接前兩個(gè)字符串的后面都有′\0′,連接時(shí)將字符串1后面的′\0′取消,只在新串最后保留′\0′。
′,連接時(shí)將字符串1后面的′連接前兩個(gè)字符串的后面都有′\0′,連接時(shí)將字符串1后面的′\0′取消,只在新串最后保留′\0′。
′取消,只在新串最后保留′連接前兩個(gè)字符串的后面都有′\0′,連接時(shí)將字符串1后面的′\0′取消,只在新串最后保留′\0′。
′。1.2.3字符串復(fù)制函數(shù)
strcpy(字符串1, 字符串2); char *strcpy( char *strDestination, const char *strSource );
:mag_right:strcpy:函數(shù)所在庫為string.h;函數(shù)參數(shù)有兩個(gè),第一個(gè)為char*類型(目的字符串地址)第二個(gè)參數(shù)為const char*類型(被復(fù)制字符串的地址);函數(shù)返回值為char*(返回strDestination的元素地址)。
strcpy函數(shù)將strSource復(fù)制給strDestination。
strcpy作用:將字符串2復(fù)制到字符數(shù)組1中去。
字符數(shù)組1必須定義得足夠大,以便容納被復(fù)制的字符串2。字符數(shù)組1的長(zhǎng)度不應(yīng)小于字符串2的長(zhǎng)度。
“字符數(shù)組1”必須寫成數(shù)組名形式,“字符串2”可以是字符數(shù)組名,也可以是一個(gè)字符串常量。
若在復(fù)制前未對(duì)字符數(shù)組1初始化或賦值,則其各字節(jié)中的內(nèi)容無法預(yù)知,復(fù)制時(shí)將字符串2和其后的′
若在復(fù)制前未對(duì)字符數(shù)組1初始化或賦值,則其各字節(jié)中的內(nèi)容無法預(yù)知,復(fù)制時(shí)將字符串2和其后的′\0′一起復(fù)制到字符數(shù)組1中,取代字符數(shù)組1中前面的字符,未被取代的字符保持原有內(nèi)容。
′一起復(fù)制到字符數(shù)組1中,取代字符數(shù)組1中前面的字符,未被取代的字符保持原有內(nèi)容。不能用賦值語句將一個(gè)字符串常量或字符數(shù)組直接給一個(gè)字符數(shù)組。字符數(shù)組名是一個(gè)地址常量,它不能改變值,正如數(shù)值型數(shù)組名不能被賦值一樣。
可以用strncpy函數(shù)將字符串2中前面n個(gè)字符復(fù)制到字符數(shù)組1中去。
將str2中最前面2個(gè)字符復(fù)制到str1中,取代str1中原有的最前面2個(gè)字符。但復(fù)制的字符個(gè)數(shù)n不應(yīng)多于str1中原有的字符(不包括′
將str2中最前面2個(gè)字符復(fù)制到str1中,取代str1中原有的最前面2個(gè)字符。但復(fù)制的字符個(gè)數(shù)n不應(yīng)多于str1中原有的字符(不包括′\0′)。
′)。1.2.4字符串比較函數(shù)
strcmp(字符串1, 字符串2); int strcmp( const char *string1, const char *string2 );
:mag_right:strcmp:函數(shù)所在庫為string.h;函數(shù)參數(shù)有兩個(gè),第一個(gè)為constchar*類型(第一個(gè)字符串地址)第二個(gè)參數(shù)為const char*類型(第二個(gè)字符串的地址);函數(shù)返回值為int(相同則返回0,字符串1>字符串2則返回一個(gè)正整數(shù),字符串1<字符串2則返回一個(gè)負(fù)整數(shù))。
:bulb:對(duì)兩個(gè)字符串比較不能直接用str1>str2進(jìn)行比較,因?yàn)閟tr1和str2代表地址而不代表數(shù)組中全部元素,而只能用 (strcmp(str1,str2)>0)實(shí)現(xiàn),系統(tǒng)分別找到兩個(gè)字符數(shù)組的第一個(gè)元素,然后順序比較數(shù)組中各個(gè)元素的值。
strcmp作用:比較字符串1和字符串2。
字符串比較的規(guī)則是: 將兩個(gè)字符串自左至右逐個(gè)字符相比(按ASCII碼值大小比較),直到出現(xiàn)不同的字符或遇到′
字符串比較的規(guī)則是: 將兩個(gè)字符串自左至右逐個(gè)字符相比(按ASCII碼值大小比較),直到出現(xiàn)不同的字符或遇到′\0′為止。
′為止。(1) 如全部字符相同,則認(rèn)為兩個(gè)字符串相等;
(2) 若出現(xiàn)不相同的字符,則以第1對(duì)不相同的字符的比較結(jié)果為準(zhǔn)。
比較的結(jié)果由函數(shù)值帶回。
(1) 如果字符串1與字符串2相同,則函數(shù)值為0。
(2) 如果字符串1>字符串2,則函數(shù)值為一個(gè)正整數(shù)。
(3) 如果字符串1<字符串2,則函數(shù)值為一個(gè)負(fù)整數(shù)。
1.2.5測(cè)字符串長(zhǎng)度的函數(shù)
strlen(字符串); size_t strlen( const char *string );//size_t本質(zhì)上是unsigned int 類型
:mag_right:strlen:函數(shù)所在庫為string.h;函數(shù)參數(shù)為const char*類型(需要被計(jì)算字符串長(zhǎng)度的字符串地址);函數(shù)返回值為unsigned int(size_t)(返回傳入字符串長(zhǎng)度大?。?。
strlen作用:測(cè)試字符串長(zhǎng)度的函數(shù)。函數(shù)的值為字符串中的實(shí)際長(zhǎng)度(不包括′
strlen作用:測(cè)試字符串長(zhǎng)度的函數(shù)。函數(shù)的值為字符串中的實(shí)際長(zhǎng)度(不包括′\0′在內(nèi))。
′在內(nèi))。1.2.6轉(zhuǎn)換為大小寫的函數(shù)
strlwr(字符串);//大寫字母轉(zhuǎn)小寫字母 char *_strlwr( char *string ); strupr(字符串)//小寫字母轉(zhuǎn)大寫字母
:mag_right:strlwr:函數(shù)所在庫為string.h;函數(shù)參數(shù)為char*類型(需要被轉(zhuǎn)換成小寫的字符串地址);函數(shù)返回值為char*(返回傳入字符串地址)。
:mag_right:strupr:函數(shù)所在庫為string.h;函數(shù)參數(shù)為char*類型(需要被轉(zhuǎn)換成大寫的字符串地址);函數(shù)返回值為char*(返回傳入字符串地址)。
作用:
srtlwr將字符串中大寫字母換成小寫字母。
strupr將字符串中小寫字母換成大寫字母。
2.指針數(shù)組與數(shù)組指針
2.1指針數(shù)組
指針數(shù)組就是數(shù)組元素類型為指針的數(shù)組。
int* arr1[10]; //整形指針的數(shù)組 char* arr2[40]; //一級(jí)字符指針的數(shù)組 char** arr3[50];//二級(jí)字符指針的數(shù)組
2.2數(shù)組指針
數(shù)組指針就是指向一個(gè)數(shù)組的指針。要弄清楚數(shù)組指針是什么,首先必須知道數(shù)組指針是指針還是數(shù)組。我們從概念名字上進(jìn)行分析,就能知道它是指針而不是數(shù)組。
我們以類比的方式來搞清楚數(shù)組指針究竟是什么?
我們已經(jīng)學(xué)習(xí)過整型指針int*,浮點(diǎn)數(shù)指針float* double*,我們以類型名+變量名的方式定義一個(gè)相應(yīng)類型的指針。
a = 8; b = 2.2; int* pa = &a;//整型指針 double* pb = &b;//雙精度浮點(diǎn)型指針
同理數(shù)組指針也是如此,不過需要與指針數(shù)組區(qū)分開來
int* arr[10];//整型指針數(shù)組,是一個(gè)數(shù)組,存放了10個(gè)整型指針類型元素 int (*parr)[10];//這就是一個(gè)數(shù)組指針,是不是和指針數(shù)組有點(diǎn)像呢? //因?yàn)閇]優(yōu)先級(jí)高于*,如果不加括號(hào),變量名首先會(huì)與[]結(jié)合表示成一個(gè)數(shù)組 //如果(*變量名),那變量名首先會(huì)與*結(jié)合就表示一個(gè)指針
int (*parr)[10]表示一個(gè)指針,指向一個(gè)數(shù)據(jù)類型為int元素個(gè)數(shù)為10的一個(gè)數(shù)組,所以parr是一個(gè)數(shù)組指針變量。
2.3數(shù)組名與&數(shù)組名
數(shù)組名一般情況下指的是數(shù)組首元素地址,與數(shù)組名[0]等價(jià)。但是有二般情況,使用sizeof(數(shù)組名),這里的數(shù)組名指的是全數(shù)組整體;&arr并不是指數(shù)組名存放的地址的地址,而是指一個(gè)數(shù)組整體的首地址。數(shù)組名+1加的是該數(shù)組存放元素的數(shù)據(jù)類型的大小,如果為int類型的數(shù)組,那就是加4,而&arr+1加的是數(shù)組整體的大小,如果一個(gè)int類型的數(shù)組有10個(gè)元素,那就是加40。
3.數(shù)組傳參與指針傳參
3.1數(shù)組傳參
3.1.1一維數(shù)組傳參
對(duì)于test1 test2函數(shù)形參可以這么寫呢?
#include
//test1 void test1(int arr[]);//方式1 void test1(int arr[10]);//方式2 void test1(int* arr);//方式3 //test2 void test2(int* arr[]);//方式1 void test2(int* arr[10]);//方式2 void test2(int** arr);//方式3
3.1.2二維數(shù)組傳參
對(duì)于test函數(shù)形參可以這么寫呢?
#include
void test(int arr[4][3]);//方式1 void test(int arr[][3]);//方式2 void test(int arr[][]);//不能省略列數(shù),錯(cuò)誤 //對(duì)于二維數(shù)組來說,每個(gè)元素指的是每一行,首元素指的是第一行數(shù)組,所以可以使用數(shù)組指針傳參 void test(int (*arr)[3]);//方式3
3.2指針傳參
3.2.1一級(jí)指針傳參
一個(gè)函數(shù)test(int* p)能接受什么參數(shù)?
int arr[10] = {0}; test(arr);//1.數(shù)組名 int a = 10; int* pa = &a; test(pa);//或 test(&a);//2.一級(jí)指針
3.2.2二級(jí)指針傳參
一個(gè)函數(shù)test(int** p)能接受什么參數(shù)?
int n = 10; int* p = &n; int** pp = &p; int* arr[10] = {0}; test(arr);//1.整型指針數(shù)組 test(pp); test(&p);//2.二級(jí)指針
4.函數(shù)指針與函數(shù)指針數(shù)組
4.1函數(shù)指針
如果在程序中定義了一個(gè)函數(shù),在編譯時(shí)會(huì)把函數(shù)的源代碼轉(zhuǎn)換為可執(zhí)行代碼并分配一段存儲(chǔ)空間。這段內(nèi)存空間有一個(gè)起始地址,也稱為函數(shù)的入口地址。每次調(diào)用函數(shù)時(shí)都從該地址入口開始執(zhí)行此段函數(shù)代碼。
函數(shù)名就是函數(shù)的指針,它代表函數(shù)的起始地址。
函數(shù)名與數(shù)組名有點(diǎn)相似,對(duì)函數(shù)名取地址得到的還是函數(shù)的地址。
#include
:bulb:運(yùn)行結(jié)果:
004713B1 004713B1 D:\gtee\C-learning-code-and-project\test_813\Debug\test_813.exe (進(jìn)程 20032)已退出,代碼為 0。 按任意鍵關(guān)閉此窗口. . .
可以定義一個(gè)指向函數(shù)的指針變量,用來存放某一函數(shù)的起始地址,這就意味著此指針變量指向該函數(shù)。例如:
int (*p)(int,int);
定義p是一個(gè)指向函數(shù)的指針變量,它可以指向函數(shù)類型為整型且有兩個(gè)整型參數(shù)的函數(shù)。此時(shí),指針變量p的類型用int (*)(int,int)表示。
:star:函數(shù)指針定義通式:類型名 (*指針變量名)(函數(shù)參數(shù)表列)
:star:對(duì)于函數(shù)指針你要注意以下幾點(diǎn):
:lemon::定義指向函數(shù)的指針變量,并不意味著這個(gè)指針變量可以指向任何函數(shù),它只能指向在定義時(shí)指定的類型的函數(shù)。
:lemon::如果要用指針調(diào)用函數(shù),必須先使指針變量指向該函數(shù)。
:lemon::在給函數(shù)指針變量賦值時(shí),只須給出函數(shù)名而不必給出參數(shù)。
:lemon::用函數(shù)指針變量調(diào)用函數(shù)時(shí),只須將(*p)代替函數(shù)名即可(p為指針變量名),在(*p)之后的括號(hào)中根據(jù)需要寫上實(shí)參。
:lemon::對(duì)指向函數(shù)的指針變量不能進(jìn)行算術(shù)運(yùn)算,如p+n,p++,p–等運(yùn)算是無意義的。
:lemon::用函數(shù)名調(diào)用函數(shù),只能調(diào)用所指定的一個(gè)函數(shù),而通過指針變量調(diào)用函數(shù)比較靈活,可以根據(jù)不同情況先后調(diào)用不同的函數(shù)。
小栗子:
#include
:bulb:運(yùn)行結(jié)果:
8 8 D:\gtee\C-learning-code-and-project\test_813\Debug\test_813.exe (進(jìn)程 21292)已退出,代碼為 0。 按任意鍵關(guān)閉此窗口. . .
:bulb:分析兩個(gè)有趣的代碼
#include
:key:代碼1:
void (*)()是一個(gè)參數(shù)為空返回值為空的函數(shù)指針類型,(void (*)())0意思是將0強(qiáng)制轉(zhuǎn)換成這種指針類型,(* (void (*)())0)()解引用被轉(zhuǎn)換過的0執(zhí)行在該地址的函數(shù)。
:key:代碼2:
定義了一個(gè)名為signal的函數(shù),其中參數(shù)為整型int和參數(shù)為int 返回值為空的函數(shù)指針void(*)(int),返回值為void (*)(int)類型的函數(shù)指針。
可以使用typedef將這個(gè)代碼簡(jiǎn)化:
typedef void (*pf)(int) void (*signal(int, void(*)(int)))(int); //相當(dāng)于 pf signal(int, pf);
4.2函數(shù)指針數(shù)組及其在計(jì)算器的應(yīng)用
//函數(shù)指針 int (*func)(int, int); //指針數(shù)組 int* arr[10]; //函數(shù)指針數(shù)組 int (*funcarr[10])(int, int); //函數(shù)指針數(shù)組的指針 int (*(*pfuncarr)[10])(int, int);
函數(shù)指針數(shù)組用途:轉(zhuǎn)移表
:corn:栗子:整型加減乘除計(jì)算器
菜單及其加減乘除函數(shù)
#include
1.使用函數(shù)指針傳參實(shí)現(xiàn)
int main() { int input = 0; do { menu(); printf("請(qǐng)選擇:>"); scanf("%d", &input); switch (input) { case 1: Calc(Add); break; case 2: Calc(Sub); break; case 3: Calc(Mul); break; case 4: Calc(Div); break; case 0: printf("退出計(jì)算器\n"); break; default: printf("選擇錯(cuò)誤\n"); break; } } while (input); return 0; }
:bulb:運(yùn)行結(jié)果:
********************************** ********************************** ******* 1.add ******* ******* 2.sub ******* ******* 3.mul ******* ******* 4.div ******* ******* 0.exit ******* ********************************** ********************************** 請(qǐng)選擇:>1 請(qǐng)輸入2個(gè)操作數(shù):>2 3 ret = 5 ********************************** ********************************** ******* 1.add ******* ******* 2.sub ******* ******* 3.mul ******* ******* 4.div ******* ******* 0.exit ******* ********************************** ********************************** 請(qǐng)選擇:>3 請(qǐng)輸入2個(gè)操作數(shù):>2 3 ret = 6 ********************************** ********************************** ******* 1.add ******* ******* 2.sub ******* ******* 3.mul ******* ******* 4.div ******* ******* 0.exit ******* ********************************** ********************************** 請(qǐng)選擇:>0 退出計(jì)算器 D:\gtee\C-learning-code-and-project\test_813\Debug\test_813.exe (進(jìn)程 7012)已退出,代碼為 0。 按任意鍵關(guān)閉此窗口. . .
2.使用函數(shù)指針數(shù)組實(shí)現(xiàn)
int main() { int input = 0; do { int x = 0; int y = 0; int ret = 0; menu(); printf("請(qǐng)選擇:>");//1 scanf("%d", &input); int (*pfArr[5])(int, int) = {0, Add, Sub, Mul, Div}; //0 1 2 3 4 if (input == 0) { printf("退出計(jì)算器\n"); } else if(input>=1 && input<=4) { printf("請(qǐng)輸入2個(gè)操作數(shù):>"); scanf("%d %d", &x, &y); ret = pfArr[input](x, y); printf("%d\n", ret); } else { printf("選擇錯(cuò)誤\n"); } } while (input); return 0; }
:bulb:運(yùn)行結(jié)果:
********************************** ********************************** ******* 1.add ******* ******* 2.sub ******* ******* 3.mul ******* ******* 4.div ******* ******* 0.exit ******* ********************************** ********************************** 請(qǐng)選擇:>1 請(qǐng)輸入2個(gè)操作數(shù):>2 3 5 ********************************** ********************************** ******* 1.add ******* ******* 2.sub ******* ******* 3.mul ******* ******* 4.div ******* ******* 0.exit ******* ********************************** ********************************** 請(qǐng)選擇:>3 請(qǐng)輸入2個(gè)操作數(shù):>2 3 6 ********************************** ********************************** ******* 1.add ******* ******* 2.sub ******* ******* 3.mul ******* ******* 4.div ******* ******* 0.exit ******* ********************************** ********************************** 請(qǐng)選擇:>0 退出計(jì)算器 D:\gtee\C-learning-code-and-project\test_813\Debug\test_813.exe (進(jìn)程 16872)已退出,代碼為 0。 按任意鍵關(guān)閉此窗口. . .
5.回調(diào)函數(shù)
回調(diào)函數(shù)就是一個(gè)通過函數(shù)指針調(diào)用的函數(shù)。如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個(gè)函數(shù),當(dāng)這個(gè)指針被用來調(diào)用其所指向的函數(shù)時(shí),我們就說這是回調(diào)函數(shù)?;卣{(diào)函數(shù)不是由該函數(shù)的實(shí)現(xiàn)方直接調(diào)用,而是在特定的事件或條件發(fā)生時(shí)由另外的一方調(diào)用的,用于對(duì)該事件或條件進(jìn)行響應(yīng)。
比如上述計(jì)算器中的Calc函數(shù),這個(gè)函數(shù)通過傳入的函數(shù)指針,去找到Add Sub Mul Div中的一個(gè)函數(shù)并調(diào)用它。
int Add(int x, int y)//int (*)(int, int) { return x + y; } int Sub(int x, int y)//int (*)(int, int) { return x - y; } int Mul(int x, int y)//int (*)(int, int) { return x * y; } int Div(int x, int y)//int (*)(int, int) { return x / y; } void Calc(int(*pf)(int, int)) { int x = 0; int y = 0; int ret = 0; printf("請(qǐng)輸入2個(gè)操作數(shù):>"); scanf("%d %d", &x, &y); ret = pf(x, y);//通過函數(shù)指針返回調(diào)用調(diào)用加減乘除函數(shù) printf("ret = %d\n", ret); }
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。