簡體   English   中英

C中的函數指針,有無*?

[英]function pointer in C, with or without *?

對於C中的函數指針,有沒有*之間有區別?

像我這樣的函數指針聲明

typedef void (*DListVisitNode) (Node*, void*);
void DListTraverse( NodeList* , DListVisitNode , void*);

我有這樣的代碼

void print_index( Node* node, void* ctx)
{
    printf("index:%d\n", node->index);
}

void* print_content( Node* node, void* ctx)
{
    printf("content:%s\n", node->content);
}
void DListTraverse(NodeList* nodelist, DListVisitNode visit_func, void* ctx)
{
    Node* cur_node = nodelist->headnode;
    while( cur_node != NULL)
    {
        visit_func( cur_node, ctx );
        cur_node = cur_node->nextnode;
    }
}

DListTraverse( nodelist, print_content, NULL );
DListTraverse( nodelist, print_index, NULL );

兩個DListTraverse都可以正常工作,但帶有*的那個會像這樣發出警告

warning: passing argument 2 of ‘DListTraverse’ from incompatible pointer type

之后我會刪除*,但它們之間的區別是什么?

print_content定義為返回void*即通用原始指針。

print_index定義為返回void即沒有任何結果。

這些是不同的簽名。 只有print_index匹配DListVisitNode

我的編碼風格是通過typedef定義簽名

  typedef void signature_t (int);

請注意,上面沒有涉及指針。 這用一個int參數命名函數的簽名而沒有結果。

然后,當需要指向上述簽名的這些函數的指針時,使用signature_t*

這是真的是函數的名稱就像數組的名稱; 語言隱式地將它們轉換為指針。 所以DListTraverse(nodelist, print_content, NULL)被理解為DListTraverse(nodelist, &print_content, NULL)

您應該在編譯器上啟用所有警告; 使用gcc意味着將-Wall -Wextra作為編譯器的程序參數。

您已將print_content聲明為返回void * (指針),這意味着它與DListVisitNode不匹配。 但是,由於函數實際上沒有返回任何內容(沒有返回語句),因此您應該再次收到警告。

您可能會對以下與typedef之間的區別感到困惑:

typedef void (*DListVisitNode) (Node*, void*);
typedef void * (*DListVisitNode) (Node*, void*);

或者等效地,在以下兩種類型之間:

  • void (*) (Node *, void *)

  • void * (*) (Node *, void *)

前者是指向返回void的函數的指針,后者是指向返回void *的函數的指針。 每個打印功能都是一個這樣的功能的示例。

當然,不同類型的函數指針是不兼容的,不能隱式轉換,因為這肯定沒有意義:你不能只假裝一個函數實際上有一個完全不同的簽名,並期望能夠以任何有意義的方式調用它。 這就像假裝自行車是一輛汽車,然后試圖在加油站加油。

typedef void (*DListVisitNode) (Node*, void*);     

定義一個指向函數作為類型采用兩個參數Node *void * ,並返回一個void
使用上面的語句后, DListVisitNode可以用作類型 ,確切的類型如上所述。

void* print_content( Node* node, void* ctx) 

返回void *而不是void
C是強類型語言,c標准規定編譯器必須報告任何類型違規,因此存在類型不匹配 ,編譯器會向您報告。 基本上,如果您的函數沒有返回任何內容,請使用返回類型作為void或者如果您打算返回特定類型,則使用該特定類型作為返回類型。

暫無
暫無

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

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