成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C++面試題:函數(shù)類型和函數(shù)指針類型的區(qū)別

開(kāi)發(fā)
函數(shù)類型與函數(shù)指針類型的區(qū)別不僅體現(xiàn)在語(yǔ)法形式上,更關(guān)系到程序的內(nèi)存模型、類型系統(tǒng)的底層邏輯等方面。

函數(shù)類型與函數(shù)指針類型 是兩種看似相似但本質(zhì)完全不同的概念。它們的區(qū)別不僅體現(xiàn)在語(yǔ)法形式上,更關(guān)系到程序的內(nèi)存模型、類型系統(tǒng)的底層邏輯等方面。

一、定義

1. 函數(shù)類型(Function Type)

定義:描述函數(shù)的構(gòu)成,包括 返回值類型 和 參數(shù)列表。

示例:void(int, int) 表示一個(gè)接受兩個(gè) int 參數(shù)且無(wú)返回值的函數(shù)類型。

本質(zhì):

  • 函數(shù)類型是一種抽象類型,僅表示函數(shù)的調(diào)用約定(如參數(shù)和返回值)。
  • 不是對(duì)象類型,無(wú)法直接實(shí)例化變量或分配內(nèi)存(如 void(int, int) func; 是非法的)。
  • 可通過(guò)別名(using/typedef)或引用間接操作。

2. 函數(shù)指針類型(Function Pointer Type)

定義:指向函數(shù)地址的指針類型,存儲(chǔ)函數(shù)的入口地址。

示例:void(*)(int, int) 是指向 void(int, int) 函數(shù)的指針類型。

本質(zhì):

  • 是對(duì)象類型,占用內(nèi)存空間(通常與普通指針大小相同,如 4/8 字節(jié))。
  • 可直接聲明變量、賦值,并通過(guò)指針間接調(diào)用函數(shù)。

二、語(yǔ)法區(qū)別與聲明方式

1. 類型別名定義

使用 using(C++11):

// 函數(shù)類型別名
using FuncType = void(int, int);          
// 函數(shù)指針類型別名
using FuncPtrType = void(*)(int, int);

使用 typedef(兼容 C):

// 函數(shù)類型別名
typedef void FuncTypeLegacy(int, int);     // 正確,C風(fēng)格函數(shù)類型
// 函數(shù)指針類型別名
typedef void(*FuncPtrTypeLegacy)(int, int); // 正確,C風(fēng)格函數(shù)指針類型

2. 變量聲明與初始化

函數(shù)類型 不能直接聲明變量,必須通過(guò)指針或引用操作:

FuncType* ptr = &myFunction;   // 正確,聲明函數(shù)指針變量
FuncType& ref = myFunction;     // 正確,聲明函數(shù)引用
// FuncType func;               // 錯(cuò)誤!函數(shù)類型無(wú)法實(shí)例化

函數(shù)指針可直接聲明變量并賦值:

FuncPtrType ptr = myFunction;   // 正確,隱式轉(zhuǎn)換為指針
FuncPtrType ptr2 = &myFunction; // 正確,顯式取地址

三、使用規(guī)則

1. 隱式轉(zhuǎn)換規(guī)則

函數(shù)名到指針的隱式轉(zhuǎn)換:函數(shù)名(如 myFunction)在大多數(shù)上下文中會(huì)自動(dòng)退化為函數(shù)指針(如賦值、傳參)。

void myFunction(int, int);
FuncPtrType ptr = myFunction;    // 隱式轉(zhuǎn)換,等價(jià)于 ptr = &myFunction

保留函數(shù)類型的場(chǎng)景:使用 decltype(函數(shù)名) 或 sizeof(函數(shù)名) 時(shí),函數(shù)名不會(huì)退化為指針,保留原始函數(shù)類型:

decltype(myFunction) func;        // 錯(cuò)誤!decltype(myFunction) 是函數(shù)類型,無(wú)法實(shí)例化
decltype(&myFunction) ptr;        // 正確,decltype(&myFunction) 是函數(shù)指針類型

2. 賦值與調(diào)用的限制

函數(shù)類型別名:

using FuncType = void(int, int);
FuncType* ptr = myFunction;      // 必須通過(guò)指針或引用操作
ptr(1, 2);                       // 通過(guò)指針調(diào)用函數(shù)

函數(shù)指針類型別名:

using FuncPtrType = void(*)(int, int);
FuncPtrType ptr = myFunction;     // 直接存儲(chǔ)地址
ptr(3, 4);                        // 直接調(diào)用

四、使用場(chǎng)景對(duì)比

1. 作為函數(shù)參數(shù)

函數(shù)指針類型可直接作為參數(shù)傳遞:

void processData(int a, int b, FuncPtrType callback) {
    callback(a, b);  // 直接調(diào)用
}
processData(2, 3, add);  // 隱式轉(zhuǎn)換

函數(shù)類型需顯式聲明指針或引用:

void processData(FuncType* callback, int a, int b) {
    (*callback)(a, b);  // 通過(guò)指針調(diào)用
}
processData(&add, 2, 3); // 顯式取地址

2. 模板與類型推導(dǎo)

函數(shù)指針類型可直接用于模板參數(shù):

template <typename T, typename Compare>
void sort(T* arr, int size, Compare comp) {
    // 使用 comp 作為比較函數(shù)
}
sort(data, 100, MyCompare);  // MyCompare 隱式轉(zhuǎn)換為指針

函數(shù)類型需轉(zhuǎn)換為指針或引用:

template <typename T>
using Callback = void(*)(T);   // 模板別名必須為指針類型
Callback<int> cb = [](int x) { };  // ambda 需兼容函數(shù)指針

五、常見(jiàn)的錯(cuò)誤

1. 錯(cuò)誤聲明函數(shù)類型變量

#include <iostream>
using namespace std;

bool MyComp(int val1, int val2) { return val1 > val2; }

int main() {
    decltype(MyComp) fun2;  // 錯(cuò)誤!decltype(MyComp) 是函數(shù)類型
    fun2 = MyComp;         // 無(wú)法賦值
}

錯(cuò)誤原因:decltype(MyComp) 推導(dǎo)為函數(shù)類型 bool(int, int),無(wú)法實(shí)例化對(duì)象。

修復(fù)方法:使用 decltype(&MyComp) 或顯式聲明指針類型:

decltype(&MyComp) fun2;    // 推導(dǎo)為函數(shù)指針類型
using FuncPtr = bool(*)(int, int);
FuncPtr fun2 = MyComp;     // 正確

2. 模板參數(shù)必須為函數(shù)指針類型

map<Person, int, decltype(MyCompare)> group(MyCompare);  // 錯(cuò)誤!
map<Person, int, decltype(&MyCompare)> group(MyCompare); // 正確

分析:STL 容器(如 map)要求模板參數(shù)是可調(diào)用對(duì)象類型,而函數(shù)類型無(wú)法直接實(shí)例化,必須傳遞指針類型。

六、函數(shù)類型與函數(shù)指針類型的底層機(jī)制

1. 內(nèi)存模型與調(diào)用約定

函數(shù)類型不占用內(nèi)存空間,僅存在于編譯器的類型系統(tǒng)中。

函數(shù)指針存儲(chǔ)函數(shù)的入口地址,調(diào)用時(shí)通過(guò) call 指令跳轉(zhuǎn)到目標(biāo)地址執(zhí)行。

2. 函數(shù)引用的本質(zhì)

函數(shù)引用(如 FuncType& ref = myFunction;)是函數(shù)類型的別名,其行為與指針等價(jià),但語(yǔ)法更接近直接調(diào)用:

ref(1, 2);      // 直接調(diào)用,無(wú)需解引用
(*ptr)(1, 2);   // 指針需顯式解引用

3. 與 Lambda 表達(dá)式的交互

無(wú)捕獲的 Lambda 可隱式轉(zhuǎn)換為函數(shù)指針:

void(*ptr)(int) = [](int x) { cout << x; };  // 捕獲Lambda

帶捕獲的 Lambda 無(wú)法轉(zhuǎn)換為函數(shù)指針,需使用 std::function 或模板。

這個(gè)詳細(xì)的解釋可以看文章 C++面試題:C++11 引入 Lambda 解決什么問(wèn)題?

七、總結(jié)

責(zé)任編輯:趙寧寧 來(lái)源: CppPlayer
相關(guān)推薦

2011-06-14 11:15:13

Qt 面試題 函數(shù)指針

2025-05-23 08:15:00

C++constexpr字面類型

2023-11-22 13:22:51

C++函數(shù)

2010-01-18 15:53:27

C++析構(gòu)函數(shù)

2011-07-14 10:39:08

強(qiáng)制類型轉(zhuǎn)換函數(shù)C++

2011-07-15 01:20:58

C指針函數(shù)函數(shù)指針

2025-02-06 13:23:09

C++函數(shù)參數(shù)

2024-01-29 01:30:00

函數(shù)C++編程

2010-02-06 09:31:42

C++函數(shù)對(duì)象

2024-01-17 23:10:59

C++函數(shù)模板開(kāi)發(fā)

2021-05-31 07:55:44

smartRepeatJavaScript函數(shù)

2021-10-27 11:00:30

C++語(yǔ)言面試

2011-07-20 17:54:02

C++

2021-06-18 12:30:36

C++函數(shù)指針編程語(yǔ)言

2010-01-28 13:45:06

C++數(shù)組

2009-08-13 17:30:30

C#構(gòu)造函數(shù)

2013-07-23 13:06:50

2010-02-01 09:18:49

C++函數(shù)指針

2010-02-02 15:01:59

C++成員函數(shù)指針

2011-07-20 16:09:08

C++
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 成人不卡 | 国产精品成人一区二区三区夜夜夜 | 国家aaa的一级看片 h片在线看 | 国产精品久久久久久中文字 | 亚洲午夜视频在线观看 | 精品1区2区 | 久久亚洲一区 | 欧美一区二区免费在线 | 欧美日韩一区二区三区四区 | 亚洲精品电影在线观看 | 综合精品在线 | 人人叉| 亚洲精品视频在线播放 | 久久网日本 | 草久网 | 中文字幕一区二区三区在线观看 | 九九热国产精品视频 | 精品一区二区三区四区视频 | 国产精品免费一区二区 | 欧美三级免费观看 | 看av片网站 | 麻豆国产一区二区三区四区 | 欧美精品首页 | 色婷婷久久久亚洲一区二区三区 | 欧美日韩久久 | 无码一区二区三区视频 | 国产精品黄 | 91在线视频观看 | 亚洲444kkkk在线观看最新 | 久久久成人免费一区二区 | 亚洲激情在线观看 | 亚洲精品成人在线 | 国产精品1区2区 | 女女百合av大片一区二区三区九县 | 欧美视频二区 | 99精品欧美一区二区三区综合在线 | 美女天堂 | 黄色在线免费网站 | 国产一区不卡 | 亚洲精品美女 | 日韩欧美中文在线 |