【问题标题】:C #define statement, enum, structC#define 语句、枚举、结构
【发布时间】:2012-01-26 01:45:27
【问题描述】:

我有一些包含此 typedef 的遗留代码:

typedef enum simple_op_enum {
    #define SOP(OPCODE, NAME, FORM, SUIFOP) OPCODE ,
    #include "simple_ops.def"
    LAST_OP
} simple_op;

#include 文件包含几行格式:

/*  no operand instructions */
SOP( NOP_OP,    "nop ",     BASE_FORM,  io_nop)

标记“simple_op”稍后出现在结构中:

typedef struct simple_instr_struct {
    simple_op opcode;           /* the opcode */

有几件事我不明白:

  1. #define 语句末尾有一个逗号有什么作用?我认为那是非法的。

  2. 枚举正在完成什么,尤其是 LAST_OP

  3. 如何访问 simple_instr_struct 中操作码的值?

【问题讨论】:

标签: c struct enums c-preprocessor


【解决方案1】:
  1. 这并不违法,它是预处理器将所有 SOP(x, y, z) 实例替换为的一部分。

  2. 它正在使用simple_ops.def 中的内容创建一个枚举。因为该文件的内容是SOP(w, x, y, z),所以它们都会变成w,而enum 将是:

typedef enum simple_op_enum {
   NOP_OP , // <- notice the space before the comma, like the #define does
   ...      // the others
   LAST_OP
} simple_op;

它还使LAST_OP 成为最后一个枚举值。这可能是代码可以使用LAST_OP 来确定有多少枚举值(或最高的枚举值,或类似的东西)。

#include 这个东西是一个聪明的技巧,因此定义可以都在同一个地方(文件),#includes 的代码只是将SOP 定义为它需要的任何东西。然后修改该文件将影响需要它的整个代码,并且代码会以任何需要的方式使用它们。例如,某些代码可能只需要名称,因此它将SOP 定义为#define SOP(w, x, y, z) x 以提取名称。

3) 你可以通过simple_instr_struct_instance.opcode访问它

【讨论】:

    【解决方案2】:

    如果对宏有疑问,您可以随时使用预处理器查看它们的扩展方式:

    gcc -E file.c -o file.txt

    如果包含许多头文件,输出会很大,但你会在某处找到你的宏 - 可能接近尾声

    【讨论】:

      【解决方案3】:

      #define 末尾的逗号是合法的。它是宏的一部分。枚举的常量用逗号分隔,这个宏担心这一点。

      enum 只是一个 var,它可以包含您在 enum 声明中指定的任何值。由于它们被转换为数字,因此 LAST_OP 将等于可能性的数量。

      你可以像这样访问成员:

      struct simple_instr_struct a;
      a.opcode=LAST_OP;
      

      【讨论】:

        【解决方案4】:
        1. 逗号只是使用宏时将发生的文本替换的一部分。在这种情况下,它是在每个操作码之后添加一个逗号,以便列表将生成有效的enum 语法。

        2. #define#include 的结果是一个如下所示的枚举:

          typedef enum simple_op_enum {
            NOP_OP,
            .
            .
            .
            LAST_OP
          } simple_op;
          

          您可以通过查看通过 C 预处理器运行源代码的输出来看到相同的结果。 LAST_OP 只是新枚举中的最后一个条目。

        3. 您需要定义该类型的变量:

          struct simple_instr_struct myStruct;
          

          然后访问你关心的字段:

          myStruct.opcode
          

        【讨论】:

        • LAST_OP的定义——它是一个enum常量,特别是最后一个。
        【解决方案5】:

        它将操作码提取为枚举

        枚举需要逗号分隔,因此它采用 OPCODE 并在其后放置一个 , 有效地生成

        typedef enum simple_op_enum {
        NOP_OP, BLAH , WHATEVER , ANOTHER ,
        LAST_OP
        } simple_op;
        

        枚举的目的是对所有可用的操作码进行枚举。

        LAST_OP 有助于了解诸如最终有多少操作码之类的信息,也意味着枚举列表中的最后一项没有悬空的逗号。

        如果你有一个 struct 的实例,'blah',那么你可以通过 blah.opcode = NOP_OP; 得到它

        【讨论】:

          猜你喜欢
          • 2017-12-13
          • 1970-01-01
          • 2014-06-21
          • 2021-05-21
          • 2010-11-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多