函數指針和函數指針數組用法及其類型打印

寫在前面

本篇博客主要介紹函數指針的用法,並設計程序驗證函數名取地址,解引用等的異同。

函數指針

先看一段驗證程序:

#include <iostream>
#include <typeinfo>

void print(void) 
{
    std::cout << "Hello, world\n";
}
void func1(void) 
{
    void (*p1)(void) = print;
    void (*p2)(void) = &print;
    void (*p3)(void) = *print;
    p1();
    p2();
    p3();
    auto q1 = print;
    auto q2 = &print;
    auto q3 = *print;
    std::cout << "q1:" << q1 << ", type: " << typeid(q1).name() << std::endl;
    std::cout << "q2:" << q2 << ", type: " << typeid(q2).name() << std::endl;
    std::cout << "q3:" << q3 << ", type: " << typeid(q3).name() << std::endl;
}

int main()
{
    func1();
    return 0;
}

程序運行的結果是:

Hello, world
Hello, world
Hello, world
q1:1, type: PFvvE
q2:1, type: PFvvE
q3:1, type: PFvvE

觀察結果,我們不難得出,通過取地址、解引用獲取的指針是一樣的,並且指針的類型也是一樣的,這篇博客中的論點就有些偏差了,評論中同學給出的觀點可以驗證,那麼總結之,函數我們把它看成類似數組名一樣的變量,對數組名取地址和數組名是一樣的。

OK,至此我們可能想看一下類型"PFvvE"具體表示的是什麼名字,我們可以參考reference typeidstackoverflow,當然也可以在visual studio IDE環境中查看變量類型。

$ echo "PFvvE" | c++filt --types
void (*)()

函數指針數組

函數指針數組可參見函數指針和函數指針數組及其應用這篇博客,總結之,假設函數指針的類型是void (*func)(void),那麼對於的函數指針數組形式即爲:void (*funcArr[3])(void),見下面代碼:

void func1(void) {}
void func2(void) {}
void func3(void) {}

void (*p[3])(void) = {func1, func2, func3};

for (size_t i = 0; i < sizeof(p) / sizeof(p[0]); ++i) 
{
    p[i]();
}

————————

總結

  1. 函數指針的形式 typedef int (*fun_ptr)(int,int);;
  2. 對應的函數指針形式,int (*fun_ptr_arr[size])(int,int);
  3. 函數指針賦值時,推薦直接用函數名,因爲C/C++標準不推薦對函數名,數組名取地址,容易引起語義模糊。

6.5.3.2 Address and indirection operators
Some implementations have not allowed the & operator to be applied to an array or a function. (The construct was permitted in early versions of C, then later made optional.) The C89 Language Committee endorsed the construct since it is unambiguous, and since data abstraction is enhanced by allowing the important & operator to apply uniformly to any addressable entity.

————————

其他參考資料

  1. 函數指針
  2. C/C++獲取變量類型並輸出
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章