在C中初始化一个结构数组,然后再取消引用

时间:2013-01-09 19:23:11

标签: c arrays struct function-pointers dereference

我正在尝试构建一个串行命令解释器,所以我想将我的命令存储在一个数组中。我希望每个命令都有一个名称和一个函数指针,以便我可以将命令名称与我输入的名称进行比较然后调用该函数。我对C不太好,所以请帮忙!这是我到目前为止所拥有的。

命令数组将是一个结构数组。每个结构都有一个字符串和一个函数指针。这里有错误,但我不知道如何修复它们。这些是在main之前完成的。

typedef struct cmdStruct {
    char cmd[16];
    void (*cmdFuncPtr)(void);
}CmdStruct;

void (*ledFuncPtr)(void);
void (*cmd2FuncPtr)(void);

// assign pointers to functions
ledFuncPtr = &LedFunction;
cmd2FuncPtr = &Cmd2Function;

//build array of structs
CmdStruct cmdStructArray[] = cmdStructArray = { {"led",   ledFuncPtr   },
                                                {"cmd2",  cmd2FuncPtr  },  };

稍后,我将通过struct数组将其与收到的命令进行比较。

// go through the struct array to do string comparison on each struct's string member
for (int i = 0; i < sizeof(cmdStructArray); i++) {
    // string comparison of received command and string of struct
    if(strcmp(cmdStructArray[i].cmd, receivedCmd)==0) {
        // dereference function pointer
        (*cmdStructArray[i].cmdFuncPtr)(void);
    }
}

我做错了哪些部分,我该如何解决?

2 个答案:

答案 0 :(得分:4)

sizeof(cmdStructArray)不在元素中,而是以字节为单位。

使用sizeof(cmdStructArray)/sizeof(cmdStructArray[0])

答案 1 :(得分:3)

正如已经注意到的那样,你的周期会产生错误的迭代次数。 sizeof array确实为您提供了数组中元素的数量,而不是数组中的字节数。您必须计算sizeof array / sizeof *array才能获得元素数量。

此外,您的函数调用语法无效

 (*cmdStructArray[i].cmdFuncPtr)(void);

以上不会编译。您不能在函数调用中将void指定为参数。 (void)语法只能在函数声明中使用。如果函数不接受任何参数,则调用应为

 (*cmdStructArray[i].cmdFuncPtr)();

此外,这也不会编译

CmdStruct cmdStructArray[] = cmdStructArray = { {"led",   ledFuncPtr   },
                                                {"cmd2",  cmd2FuncPtr  },  };

你为什么两次在这个宣言中提到cmdStructArray


一些额外的,基本上是化妆品的评论:

首先,由于您的命令可能是编译时已知的字符串文字,因此您可以将结构的第一个成员声明为const char *指针而不是char数组

typedef struct cmdStruct {
  const char *cmd;
  void (*cmdFuncPtr)(void);
} CmdStruct;

初始化语法不会更改。这将使您无需担心阵列的大小(16目前在那里)。

其次,不清楚为什么必须声明函数ledFuncPtrcmd2FuncPtr的中间指针而不是直接初始化数组。这个

的目的是什么?
void (*ledFuncPtr)(void);
void (*cmd2FuncPtr)(void);

// assign pointers to functions
ledFuncPtr = &LedFunction;
cmd2FuncPtr = &Cmd2Function;

CmdStruct cmdStructArray[] = { {"led",   ledFuncPtr  },
                               {"cmd2",  cmd2FuncPtr }, };

当你可以这么做时

CmdStruct cmdStructArray[] = { {"led",   &LedFunction  },
                               {"cmd2",  &Cmd2Function }, };

(根本没有介绍ledFuncPtrcmd2FuncPtr)?

第三,您不必将*&运算符与函数指针一起使用。这也会起作用

CmdStruct cmdStructArray[] = { {"led",   LedFunction   },
                               {"cmd2",  Cmd2Function  }, };

cmdStructArray[i].cmdFuncPtr();

无论如何,这是一个纯粹的化妆品问题,是个人偏好的问题。