簡體   English   中英

定義函數類型和函數指針類型有什么區別?

[英]What is the difference between defining a function type and a function pointer type?

據我所知,我可以定義一個函數類型:

typedef void (fn)(void);

我還可以定義一個函數指針類型:

typedef void (*pfn)(void);

有2個功能。 第一個函數的參數類型是一個函數,另一個是函數指針:

void a(fn fn1)
{
    fn1();
}

void b(pfn fn1)
{
    fn1();
}  

我實現了一個函數回調:

void callback(void)
{
    printf("hello\n");
}

並將其作為參數傳遞給a和b:

int main(void) {
    a(callback);
    b(callback);
    return 0;
}

a和b都運行良好,並打印"hello"

所以我想知道定義函數類型和函數指針類型有什么區別? 或者實際上,它們是一樣的?

函數類型在參數列表中被視為相應的函數指針類型。

(非指針)函數類型基本上有兩個實際應用:

  1. 如果您發現它太巴洛克式,請避免使用函數指針語法。

     int apply(int (*f)(int), int x) { return f(x); } int apply(int f(int), int x) { return f(x); } 
  2. 聲明相同類型的多個功能。

     int add(int, int); int subtract(int, int); int multiply(int, int); int divide(int, int); typedef int arithmetic(int, int); arithmetic add, subtract, multiply, divide; 

后者對於避免重復非常有用。 但請注意,函數類型不允許使用const來防止指針被重新分配。 所以編譯得很好:

#include <stdio.h>

int pred(int const i) { return i - 1; }
int succ(int const i) { return i + 1; }

int apply(int f(int), int const x) {
  // Oops, didn’t really mean to reassign ‘f’ here.
  f = pred;
  return f(x);
}

int main() {
    printf("%i\n", apply(succ, 1));
    return 0;
}

您可以通過使指針const來避免這種潛在的錯誤來源:

int apply(int (* const f)(int), int const x) {
  // error: assignment of read-only parameter ‘f’
  f = pred;
  return f(x);
}
fn fn2 = callback;

在標准C中是非法的

void a(fn fn1)

行為與void a(fn *fn1)完全相同。 它是一種僅在函數形式參數列表中允許的特殊語法,類似於void b(int x[])實際行為與void b(int *x)完全相同。 如果你執行sizeof fn1你將獲得函數指針的大小。

順便說一句,你在fn的定義中有多余的括號,這更簡單:

typedef void fn(void);

指針版本需要括號來關聯*

鑒於您可以使用函數指針( &funcfunc*func**func ,...最終作為函數func的相同值)的濫用,兩者之間幾乎沒有實際差異。 您可以使用fn *來指示指向函數的指針,這不是一個簡單的轉換。

但是,這里是對代碼的溫和調整,使用類型為pfn的非參數變量並嘗試(不成功)使用fn類型的非參數變量。 這不會編譯,因此在文件范圍(全局)或本地范圍而不是參數列表中使用時會有所不同。

pfn.c

typedef void (fn)(void);
typedef void (*pfn)(void);

static void callback(void)
{
    printf("hello\n");
}

static void a(fn fn1)
{
    fn fn2 = callback;
    fn *fn3 = callback;
    fn1();
    fn2();
    (*fn2)();
    fn3();
    (*fn3)();
}

static void b(pfn fn1)
{
    pfn fn2 = callback;
    fn1();
    fn2();
}  

int main(void)
{
    a(callback);
    b(callback);
    return 0;
}

匯編

$ gcc -g -O3 -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
>     -Werror  pfn.c -o pfn
pfn.c: In function ‘a’:
pfn.c:13:5: error: function ‘fn2’ is initialized like a variable
     fn fn2 = callback;
     ^
pfn.c:13:8: error: nested function ‘fn2’ declared but never defined
     fn fn2 = callback;
        ^
$

看看最后一段這里

這有助於您更好地理解fucntion和函數指針的typedef。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM