第九章 指針
第八節 函數指針和返回指針值的函數
1. 用函數指針變量調用函數
-
一個函數在編譯的時候,系統會被這個函數分配一個入口地址,這個入口地址被稱爲函數的指針.
我們可以定義一個指針指向該函數,然後,我們通過該指針變量調用該函數 -
每個函數在可執行文件執行時都會佔用一段內存單元,它們有一個起始地址,就可以用一個指針變量來指向這個函數,
從而通過指針變量來調用對應的函數
#include <iostream>
#include <cstring>
int max(int x, int y) {
if (x > y) {
return x;
}
return y;
}
int main() {
int c;
//常規的函數調用
// c = max(15, 19);
int (*p)(int x, int y);//定義一個函數指針變量
//p不能指向函數中間的語句
p = max;//將函數max的入口地址賦給指針變量p,函數名代表函數的入口地址
// p = &max;
// 不可以寫成*p(5, 1),一定要注意括號的問題,int *表示這個函數的返回值是指向整型變量的指針
c = (*p)(5, 1);//調用*p就是調用函數max的入口,p指向max的入口,等價於c=max(5, 1)
printf("c: %d\n", c);
c = p(5, 7);//(*p)(5, 7) ==> p(5, 7)
printf("c: %d\n", c);
return 0;
}
- 總結
-
函數指針變量定義的一般形式: 數據類型標誌符 (*指針變量名)(形參列表)
其中,數據類型標誌符就是指函數的返回值類型,形參列表可以只有類型說明符,多個類型說明符用","分隔,
所以我們可以通過函數指針指向不同的函數,來調用不同函數的目的 -
函數的調用:可以通過函數名調用,也可以通過函數指針調用
-
對指向函數的指針變量p,不能做p++,p–等運算
2. 把指向函數的指針變量作爲函數參數
- 指向函數的指針變量也可以作爲另外一個函數Func的參數,從而實現函數地址的傳遞,在FuncB中調用該
函數指針變量的目的
#include <iostream>
#include <cstring>
int max(int x, int y) {
if (x > y) {
return x;
}
return y;
}
int wmax(int x, int y, int (*p)(int x, int y)) {
int res = p(x, y);
return res;
}
int main() {
int c;
c = wmax(1, 5, max);
printf("c: %d\n", c);
int (*p)(int x, int y);
p = max;
c = wmax(8, 5, p);
printf("c: %d\n", c);
return 0;
}
3. 返回指針值的函數
-
函數也可以返回指針型數據,也就是返回一個地址,使用的不是很多
-
返回指針值的函數的一般定義形式: 數據類型 *函數名(參數列表),
例如int *a(int x, int y);//–> a函數名,()優先級高於*,因此a先和()結合,這是函數形式,返回值是指針 -
問題代碼
#include <iostream>
#include <cstring>
// 返回指針值的函數
int *add(int x, int y) {
int sum = x + y;
//隱藏一個致命問題, add的函數被調用完畢後,sum的內存會被系統回收
//不能把sum的內存地址返回到被調用函數中並加以使用
return ∑
}
int main() {
int *pres;
// 執行add後,pres指向的內存已經被釋放了,所以無法從該地址中取值
pres = add(4, 5);
printf("sum : %d\n", *pres);
return 0;
}
- 修改方法
#include <iostream>
#include <cstring>
// 把sum定義成全局變量
int sum;
// 返回指針值的函數
int *add(int x, int y) {
sum = x + y;
return ∑
}
int main() {
int *pres;
pres = add(4, 5);
printf("sum : %d\n", *pres);
return 0;
}