![](/img/trans.png)
[英]Difference between function with returned type pointer and function pointer
[英]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"
。
所以我想知道定義函數類型和函數指針類型有什么區別? 或者實際上,它們是一樣的?
函數類型在參數列表中被視為相應的函數指針類型。
(非指針)函數類型基本上有兩個實際應用:
如果您發現它太巴洛克式,請避免使用函數指針語法。
int apply(int (*f)(int), int x) { return f(x); } int apply(int f(int), int x) { return f(x); }
聲明相同類型的多個功能。
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);
指針版本需要括號來關聯*
。
鑒於您可以使用函數指針( &func
, func
, *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.