日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

【c++】23.【函数指针】定义? 为什么不直接调用函数而要使用函数指针?

發(fā)布時(shí)間:2025/3/21 c/c++ 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【c++】23.【函数指针】定义? 为什么不直接调用函数而要使用函数指针? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1. 函數(shù)指針及其定義和用法,C語言函數(shù)指針詳解

原文鏈接:http://c.biancheng.net/view/228.html

什么是函數(shù)指針

如果在程序中定義了一個(gè)函數(shù),那么在編譯時(shí)系統(tǒng)就會(huì)為這個(gè)函數(shù)代碼分配一段存儲(chǔ)空間, 這段存儲(chǔ)空間的首地址稱為這個(gè)函數(shù)的地址。而且函數(shù)名表示的就是這個(gè)地址。既然是地址我們就可以定義一個(gè)指針變量來存放,這個(gè)指針變量就叫作 函數(shù)指針變量,簡稱 函數(shù)指針。

那么這個(gè)指針變量怎么定義呢?

雖然同樣是指向一個(gè)地址,但指向函數(shù)的指針變量同我們之前講的指向變量的指針變量的定義方式是不同的。例如:

int(*p)(int, int);

這個(gè)語句就定義了一個(gè)指向函數(shù)的指針變量p。

  • 首先,它是一個(gè)指針變量,所以要有一個(gè)*,即(*p);
  • 其次,前面的int 表示這個(gè)指針變量可以指向返回值類型為 int 型的函數(shù);后面括號(hào)中的兩個(gè) int 表示這個(gè)指針變量可以指向有兩個(gè)參數(shù)且都是 int 型的函數(shù)。
  • 所以合起來這個(gè)語句的意思就是:定義了一個(gè)指針變量p,p可以指向返回值類型為int型,且有兩個(gè)int型參數(shù)的函數(shù)。p 的類型為int(*)(int,int)。

所以函數(shù)指針的定義方式為:

函數(shù)返回值類型 (* 指針變量名) (函數(shù)參數(shù)列表);

函數(shù)返回值類型表示該指針變量可以指向具有什么返回值類型的函數(shù);
函數(shù)參數(shù)列表表示該指針變量可以指向具有什么參數(shù)列表的函數(shù)。這個(gè)參數(shù)列表中只需要寫函數(shù)的參數(shù)類型即可。

我們看到,函數(shù)指針的定義就是將函數(shù)聲明中的函數(shù)名改成(*指針變量名)。

但是這里需要注意的是:(*指針變量名)兩端的括號(hào)()不能省略,括號(hào)改變了運(yùn)算符的優(yōu)先級(jí)。如果省略了括號(hào),就不是定義函數(shù)指針而是一個(gè)函數(shù)聲明了,即聲明了一個(gè)返回值類型為指針型的函數(shù)。

那么怎么判斷一個(gè)指針變量是指向變量的指針變量還是指向函數(shù)的指針變量呢?

  • 首先看變量名前面有沒有*,如果有*說明是指針變量;
  • 其次看變量名的后面有沒有帶有形參類型的圓括號(hào)(),如果有就是指向函數(shù)的指針變量,即函數(shù)指針,如果沒有就是指向變量的指針變量。

最后需要注意的是,指向函數(shù)的指針變量沒有++ 和--運(yùn)算。


如何用函數(shù)指針調(diào)用函數(shù)

給大家舉一個(gè)例子:
int Func(int x); /*聲明一個(gè)函數(shù)*/ int (*p) (int x); /*定義一個(gè)函數(shù)指針*/ p = Func; /*將Func函數(shù)的首地址賦給指針變量p*/

賦值時(shí)函數(shù) Func 不帶括號(hào),也不帶參數(shù)。由于函數(shù)名 Func 代表函數(shù)的首地址,因此經(jīng)過賦值以后,指針變量 p 就指向函數(shù) Func() 代碼的首地址了。


下面來寫一個(gè)程序,看了這個(gè)程序你們就明白函數(shù)指針怎么使用了:

# include <stdio.h> int Max(int, int); //函數(shù)聲明 int main(void) {int(*p)(int, int); //定義一個(gè)函數(shù)指針int a, b, c;p = Max; //把函數(shù)Max賦給指針變量p, 使p指向Max函數(shù)printf("please enter a and b:");scanf("%d%d", &a, &b);c = (*p)(a, b); //通過函數(shù)指針調(diào)用Max函數(shù)printf("a = %d\nb = %d\nmax = %d\n", a, b, c);return 0; }int Max(int x, int y) //定義Max函數(shù) {int z;if (x > y){z = x;} else{z = y;}return z; }

輸出結(jié)果是:

please enter a and b:3 4<br> a = 3<br> b = 4<br> max = 4<br>


2. 知乎問題:C++中函數(shù)指針有什么作用? 為什么不直接調(diào)用函數(shù)而要使用函數(shù)指針?

原文鏈接:https://www.zhihu.com/question/349498301

貓之公爵公之貓12 人贊同了該回答

我覺得這個(gè)問題。。。可以去好好看看B站上有個(gè)講設(shè)計(jì)模式的視頻,講的非常好。。。。

簡單來講,函數(shù)指針,和虛函數(shù)有著一樣的用處(其實(shí)他們本質(zhì)上也是一樣的),都是為了一個(gè)作用:延時(shí)綁定(晚綁定)。

這也是一個(gè)語言中,框架和庫的區(qū)別。。。

以前的C程序想用別人的東西,大部分都是庫,是一堆代碼的集合,所以你要用庫,就是調(diào)用它的功能,然后返回。。。框架的出現(xiàn)改變了這種情況,比如MFC框架(或者windows sdk),它要修改一個(gè)窗口的顏色,但是框架并不知道你的窗口是什么類型,它只關(guān)心它要修改的數(shù)據(jù)。。。這個(gè)時(shí)候就需要函數(shù)指針的幫助了。(注意,這個(gè)重點(diǎn)就在于,框架是不知道類型的,因?yàn)樗鼘懣蚣艽a的時(shí)候,你還沒有寫窗口代碼),我給一個(gè)例子,這個(gè)例子多少有點(diǎn)不合適,因?yàn)镃++通用做法肯定是虛函數(shù)了。。。但是這個(gè)方法本質(zhì)上就是用函數(shù)指針模擬虛函數(shù),只不過虛函數(shù)機(jī)制是編譯器生成的。

框架代碼:

#include <iostream>// 框架代碼 typedef void(ChangeColorFun)(Window* pWindow, int color);struct Window {ChangeColorFun* ChangeFun; };struct FrameWord {void SetWindow(Window* pWindow) {m_pWindow = pWindow;}void Run() {m_pWindow->ChangeFun(m_pWindow, 1000);}Window* m_pWindow = nullptr; };

用戶代碼:

// 用戶代碼struct LinuxWindow : public Window {int m_LinuxColor = 0; };struct MacWindow : public Window {int m_MacColor = 0; };void ChangeLinuxColor(Window* pWindow, int color) {LinuxWindow* pLinuxWindow = (LinuxWindow*)pWindow;pLinuxWindow->m_LinuxColor = color; }void ChangeMaxColor(Window* pWindow, int color) {MacWindow* pLinuxWindow = (MacWindow*)pWindow;pLinuxWindow->m_MacColor = color; }int main() {FrameWord Frame; // 框架代碼Window* pWindow = new LinuxWindow; // 用戶代碼pWindow->ChangeFun = ChangeLinuxColor; // 用戶代碼Frame.SetWindow(pWindow); // 框架代碼Frame.Run(); // 框架代碼 delete pWindow; }

注意看,框架代碼是寫框架的人之前就確定的,特別是在這個(gè)函數(shù)

void Run(){m_pWindow->ChangeFun(m_pWindow, 1000); }

中,框架是完全不知道它拿到的是什么東西的,但是通過函數(shù)指針,框架并不需要確定這個(gè)對(duì)象是什么,這樣就做到了晚綁定機(jī)制,函數(shù)指針在這里就是提供了一個(gè)接口,這個(gè)接口規(guī)定了框架作者要做什么,用戶代碼要做什么。

現(xiàn)代C++框架機(jī)制錯(cuò)綜復(fù)雜,大部分人寫代碼的時(shí)候是既要寫服務(wù)代碼,又要寫用戶代碼,這個(gè)時(shí)候區(qū)分出來他們的區(qū)別是非常重要的,按照用戶代碼的思路寫框架代碼,你的代碼會(huì)很難復(fù)用;反之按照框架代碼的思路去寫用戶代碼,你的代碼實(shí)現(xiàn)會(huì)過因?yàn)檫^于靈活復(fù)雜難用且功能可能很多用不到。


題主估計(jì)寫框架代碼少,所以才問這個(gè)問題的



補(bǔ)上b的設(shè)計(jì)模式的鏈接。。。

b23.tv/wrqjt5

總結(jié)

以上是生活随笔為你收集整理的【c++】23.【函数指针】定义? 为什么不直接调用函数而要使用函数指针?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。