偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

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

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

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

一、定義

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

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

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

本質:

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

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

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

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

本質:

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

二、語法區(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風格函數(shù)類型
// 函數(shù)指針類型別名
typedef void(*FuncPtrTypeLegacy)(int, int); // 正確,C風格函數(shù)指針類型

2. 變量聲明與初始化

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

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

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

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

三、使用規(guī)則

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

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

void myFunction(int, int);
FuncPtrType ptr = myFunction;    // 隱式轉換,等價于 ptr = &myFunction

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

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

2. 賦值與調用的限制

函數(shù)類型別名:

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

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

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

四、使用場景對比

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

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

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

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

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

2. 模板與類型推導

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

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

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

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

五、常見的錯誤

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

#include <iostream>
using namespace std;

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

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

錯誤原因:decltype(MyComp) 推導為函數(shù)類型 bool(int, int),無法實例化對象。

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

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

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

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

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

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

1. 內存模型與調用約定

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

函數(shù)指針存儲函數(shù)的入口地址,調用時通過 call 指令跳轉到目標地址執(zhí)行。

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

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

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

3. 與 Lambda 表達式的交互

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

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

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

這個詳細的解釋可以看文章 C++面試題:C++11 引入 Lambda 解決什么問題?

七、總結

責任編輯:趙寧寧 來源: CppPlayer
相關推薦

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++析構函數(shù)

2011-07-14 10:39:08

強制類型轉換函數(shù)C++

2011-07-15 01:20:58

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

2025-02-06 13:23:09

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

2010-02-06 09:31:42

C++函數(shù)對象

2024-01-29 01:30:00

函數(shù)C++編程

2024-01-17 23:10:59

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

2021-05-31 07:55:44

smartRepeatJavaScript函數(shù)

2021-10-27 11:00:30

C++語言面試

2011-07-20 17:54:02

C++

2021-06-18 12:30:36

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

2013-07-23 13:06:50

2010-01-28 13:45:06

C++數(shù)組

2010-02-01 10:22:51

C++數(shù)據(jù)指針

2016-12-20 16:35:52

NodeJSC++類型轉換

2009-08-13 17:30:30

C#構造函數(shù)

2010-02-01 09:18:49

C++函數(shù)指針
點贊
收藏

51CTO技術棧公眾號