【C】 36_函數與指針分析

函數類型

  • C 語言中的函數都有本身特定的類型
  • 函數的類型由返回值參數類型參數個數共同決定
    int add(int i, int j) 的類型爲 int(int, int)
  • C 語言中經過 typedef 爲函數類型重命名
    typedef type name(parameter list)

面試

typedef int f(int, int);
typedef void p(int);

函數指針

  • 函數指針用於指向一個函數
  • 函數名是執行函數體的入口地址
  • 能夠經過函數類型定義函數指針: FuncType* pointer;
  • 也能夠直接定義: type (*pointer)(parameter list);函數

    • pointer 爲函數指針變量名
    • type 爲所指函數的返回值類型
    • parameter list 爲所指函數的參數類型列表

面試小問題

  • 如何使用 C 語言直接跳轉到某個固定的地址開始執行?
經過函數指針完成,使用固定的地址初始化函數函數指針。多用於嵌入式設備開發中。

實例分析: 函數指針的使用

Test_1.c指針

#include <stdio.h>

typedef int(FUNC)(int);

int test(int i)
{
    return i * i;
}

void f()
{
    printf("Call f()...\n");
}

int main()
{
    FUNC* pt = test;
    void (*pf)() = f;
    
    printf("pf = %p\n", pf);
    printf("f = %p\n", f);
    printf("&f = %p\n", &f);
    
    pf();
    
    (*pf)(); 
    
    printf("Fucntion pointer call: %d\n", pt(2));

    return 0;    
}
輸出:
pf = 0x8048400
f = 0x8048400
&f = 0x8048400
Call f()...
Call f()...
Fucntion pointer call: 4

分析:
f    <==> pf
pf() <==> (*pf)()

Test_2.ccode

#include <stdio.h>

typedef int(FUNC)(int);

int test(int i)
{
    return i * i;
}

void f()
{
    printf("Call f()...\n");
}

int main()
{
    FUNC* pt = test;
    void (*pf)() = (void(*)())(0x8048400);   // pf 由一個固定的內存地址初始化!!
    
    printf("pf = %p\n", pf);
    printf("f = %p\n", f);
    printf("&f = %p\n", &f);
    
    pf();
    
    (*pf)();
    
    printf("Fucntion pointer call: %d\n", pt(2));

    return 0;    
}
輸出:
pf = 0x8048400
f = 0x8048400
&f = 0x8048400
Call f()...       【跳轉到一個固定的地址,成功執行】
Call f()...       【跳轉到一個固定的地址,成功執行】
Fucntion pointer call: 4

回調函數

  • 回調函數是利用函數指針實現的一種調用機制
  • 回調機制原理事件

    • 調用者不知道具體事件發生時須要調用的具體函數
    • 被調函數不知道什麼時候被調用,只知道須要完成任務
    • 當具體事件發生時,調用者經過函數指針調用具體函數
  • 回調機制中的調用者和被調用者互不依賴

實例分析: 回調函數使用示例

#include <stdio.h>

typedef int(*Weapon)(int);

void fight(Weapon wp, int arg)
{
    int result = 0;
    
    printf("Fight boss!\n");
    
    result = wp(arg);
    
    printf("Boss loss: %d\n", result);
}

int knife(int n)
{
    int ret = 0;
    int i = 0;
    
    for(i=0; i<n; i++)
    {
        printf("Knife attack: %d\n", 1);
        ret ++;
    }
    
    return ret;
}

int sword(int n)
{
    int ret = 0;
    int i = 0;
    
    for(i=0; i<n; i++)
    {
        printf("Sword attack: %d\n", 10);
        ret ++;
    }
    
    return ret;
}

int gun(int n)
{
    int ret = 0;
    int i = 0;
    
    for(i=0; i<n; i++)
    {
        printf("Gun attack: %d\n", 5);
        ret ++;
    }
    
    return ret;
}

int main()
{
    fight(knife, 3);
    fight(sword, 4);
    fight(gun, 5);

    return 0;
}
輸出:
Fight boss!
Knife attack: 1
Knife attack: 1
Knife attack: 1
Boss loss: 3
Fight boss!
Sword attack: 5
Sword attack: 5
Sword attack: 5
Sword attack: 5
Boss loss: 4
Fight boss!
Gun attack: 5
Gun attack: 5
Gun attack: 5
Gun attack: 5
Gun attack: 5
Boss loss: 5

小結

  • C 語言中的函數都有特定的類型
  • 可使用函數類型定義函數指針
  • 函數指針是實現回調機制的關鍵技術
  • 經過函數指針能夠在 C 程序中實現固定地址跳轉

以上內容參考狄泰軟件學院系列課程,請你們保護原創!內存

相關文章
相關標籤/搜索