繁体   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