【问题标题】:Use function pointer with void in C在C中使用带有void的函数指针
【发布时间】:2021-03-31 15:43:43
【问题描述】:

我想在 C 中创建一个类似于课程注册的结构。为此,我使用了 struct 而不是 table。

STUDENT *createStudent(){
    return (STUDENT *) malloc(sizeof(STUDENT));
}

TEACHER *createTeacher(){
    return (TEACHER *) malloc(sizeof(TEACHER));
}

COURSE *createCourse(){
    return (COURSE *) malloc(sizeof(COURSE));
}

COURSEREGISTRATION *createCourseRegistration(){
    return (COURSEREGISTRATION *) malloc(sizeof(COURSEREGISTRATION));
}

我想将这些函数传递给带有函数指针的变量。喜欢;

void *createNode(int choise){
    void (*fp[]) () = {createStudent, createTeacher, createCourse, createCourseRegistration};
    return (fp[choise] ());
}

我想用 func 指针ma​​lloc 并在这个函数(main func)中得到一个错误;

STUDENT *studentHead = NULL;
void *temp = studentHead;
temp = createNode(0);//Zero for student

我没有清楚地理解 func 指针。我该怎么办?我哪里错了?或者我可以在这种情况下使用 func 指针吗?

谢谢

编辑: 我解决了这样的问题;

#define CREATESTUDENT 0
#define CREATETEACHER 1
#define CREATEDCOURSE 2
#define CREATECOURSEREGISTRATION 3

void createNode(void **temp, int choise){
    switch(choise){
        case CREATESTUDENT:
            *temp = (STUDENT *) malloc(sizeof(STUDENT));
            break;
        case CREATETEACHER :
            *temp = (TEACHER *) malloc(sizeof(TEACHER));
            break;
        case CREATEDCOURSE :
            *temp = (COURSE *) malloc(sizeof(COURSE));
            break;
        case CREATECOURSEREGISTRATION :
            *temp = (COURSEREGISTRATION *) malloc(sizeof(COURSEREGISTRATION ));
            break;
    }
}

并使用了调用函数;

STUDENT *temp = studentHead;
createNode(&temp, CREATESTUDENT);

【问题讨论】:

  • 你遇到了什么错误
  • 函数必须具有返回类型 void * 才能按照您在 createNote 中的使用方式使用
  • 你可能会觉得Do I cast the result of malloc?很有趣。
  • @P__JsupportswomeninPoland [错误] void 值没有被忽略,因为它应该被忽略

标签: c function pointers function-pointers


【解决方案1】:

您将fp 声明为{

void (*fp[]) () = {

这是一个指向返回 void 的函数的指针数组。你想要返回指针的函数,所以你想要

void *(*fp[])() = {

但是你仍然有一个问题,你用来初始化这个数组的函数指针是错误的类型——它们都是返回指向真实类型(不是 void)的指针的函数。因此,虽然这可能会起作用,但就标准而言,它实际上是未定义的行为。

如果您将所有create 函数更改为返回void * 而不是STUDENT *(和类似的),那么它是安全的。

【讨论】:

    【解决方案2】:

    简短的回答:您的函数 ptr 签名是 void () 而不是 void* ()

    高兴地庆祝 c++ 并不太关心函数返回类型:)

    TL;DR;

    为什么要让生活变得比他们需要的更艰难? 为什么不使用简单的开关

    void *createNode(int choice){
      switch(choice){
        case 0:
          return createStudent();
        case 1:
          return createTeacher();
        ...
        ...
      }
    }
    

    注意:我从一开始就没有看到创建createNode 的意义。这似乎具有误导性的签名,我会让 API 用户明确调用 createStudentcreateTeacher 等。

    一些编码风格建议:

    • typedef 你的函数签名
    • 声明您的函数数组(最好作为模块的成员或静态)

    【讨论】:

    • 你是绝对正确的,但我在本教程中尝试不同的东西(使用 func 指针),但我想我不能:)
    【解决方案3】:

    根据您的代码,fpvoid,而不是 void* 函数。无论choice 是什么,您总是不会从createNode 返回任何内容。

    【讨论】:

    • 他正在返回void*,它只是在约定中写成void *createNode(),比如变量声明可以是int* pIntint *pInt
    • @TomerW 不,他绝对不是;如您所见,fp 是一个指向void 类型函数的函数指针数组。每当您调用从 fp 取消引用的函数时,它将返回 void,他最终会从 createNode 返回。
    • 我的错,以为你的意思是 createNode 函数本身..(所以我不明白为什么它被否决)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-21
    • 2015-02-18
    • 1970-01-01
    • 2018-04-19
    • 2019-02-03
    • 2018-08-25
    • 1970-01-01
    相关资源
    最近更新 更多