0

我在 c 中有这个枚举

枚举是否像 Java 中的 0..n?

typedef enum tag_result
{
   // Success:
   succeeded   = 0,
   no_error    = 0,

   // General errors
   general_errors,
      err_failed,
      err_no_memory,
      err_invalid_argument,
      err_aborted
} result;
4

6 回答 6

3

是的。

实际上,当涉及到数字/索引或 - 正如 java 所称的 - 序数C更灵活时,您可以定义一个开始甚至定义每个枚举的数字:

int main(int argc, char** argv)  
{ 
    printf("RED:   %d\n", (int) RED );
    printf("GREEN: %d\n", (int) GREEN );
    printf("BLUE:  %d\n", (int) BLUE );
    return 0;  
} 

enum colors { RED, GREEN, BLUE};

输出将是

RED:   0
GREEN: 1
BLUE:  2

enum colors { RED = 4, GREEN, BLUE};

输出将是

RED:   4
GREEN: 5
BLUE:  6

enum colors { RED = 1, GREEN = 3, BLUE = 5};

输出将是

RED:   1
GREEN: 3
BLUE:  5
于 2013-09-29T13:36:13.897 回答
1

枚举是否像 Java 中的 0..n?

是的,它确实

于 2013-09-29T13:10:56.937 回答
0

是的,但这是您可以通过打印值轻松检查的内容

 result r = general_errors;
 printf("%d\n", r );
 r = err_failed;
 printf("%d\n", r );
 r = err_no_memory;
 printf("%d\n", r );
 r = err_invalid_argument;
 printf("%d\n", r );
 r = err_aborted;
 printf("%d\n", r );

将打印

 1
 2
 3
 4
 5
于 2013-09-29T13:11:23.270 回答
0

C 枚举是整数。该语言只是提供了一些语法来进行名称到 int 的替换(以及编译器可以强制执行的一些其他项目)。

如果你想要一个类似 Java 的枚举,你需要创建一堆全局对象。由于 C 缺乏对 Java 枚举合约的强制执行,因此您需要尽最大努力实现它们。

因此,这在两个方面使问题复杂化。现在您需要模拟一个对象并模拟枚举(如果您想要在 c 中使用类似 Java 的枚举)。

为了模拟一个对象,有一些技术很好用。关键是尽早退出只实现您需要的功能,因为您添加的功能越多,就越难:

typedef struct tag_result {
   int enum_value;
   char* enum_name;
} result;

result* getEnumByValue(int index);

result* getEnumByName(char* name);

并在.c文件中

// resize to match entries
int enum_limit = 5;
result enums[enum_limit];

// it is your responsibility to not duplicate values.
enums[0].enum_value = 0;
enums[0].enum_name = "invalid_argument";
enums[1].enum_value = 1;
enums[1].enum_name = "no_memory";

result* getEnumByName(char* name) {
  int index;
  for (index = 0; index < enum_limit; index++) {
     if (strcmp(enums[index].enum_name, name)) {
       return enums[index];
     }
  }
  return 0;
}

result* getEnumByValue(int value) {
        int index;
  for (index = 0; index < enum_limit; index++) {
     if (enums[index].enum_value == value) {
       return enums[index];
     }
  }
  return 0;
}

现在,如果你想要封装,你可以将结构分成两部分,一是暴露的,一是隐藏的。第一种技术是只暴露typedef struct s_result result,让结构的布局在.h. 一开始有点棘手,但它保证了包含不会暴露任何内容并提供.c文件中的完全访问权限。如果您使用这种技术,您需要添加访问器方法。

int getResultValue(result* item) {
   return (*item).enum_value;
}

char* getResultName(result* item) {
   return (*item).enum_name;
}

有些人进一步打破了这一点,有一个“公共”和一个“私人”标题。一个结构引用另一个结构(由 void* 指针隐藏)。这个想法是通过不公开“私有”标头指针的类型来隐藏数据。自然要将这些位拼接在一起,您需要了解接线的构造函数,

result* new_resultEnum(int value, char* name) {
  result* newItem = (result*)malloc(sizeof(struct s_result));
  (*newItem).private = (p_result*)malloc(sizeof(struct s_p_result));
  (*newItem).private.enum_value = value;
  (*newItem).private.enum_name = name;
  return newItem;
}

使用这种技术,您可以轻松地通过 C 的函数指针添加成员方法(尽管语法有点挑战性)。

  ... added to the constructor above ...
  (*newItem).getValue = result_getValue;

公开“getValue”方法。有一个警告。在 C 中传递“this”指针并没有真正的好方法,因为成员函数缺乏“知道”它们在结构中的能力,以及“知道”该结构从哪里开始的能力。是的,有一些变通方法,但它们开始花费更多的时间和金钱。我通常只是不打扰,这使得这样的代码很常见。

  result* myresult;
  (*myresult).getValue(myresult);

虽然我希望您喜欢更深层次的表面处理,但您应该比成员函数更早停止。也许我应该比多态的实现更早停止:)

于 2013-09-29T14:11:01.173 回答
0

是的,默认情况下第一个枚举数的值为 0。但也可以在说明符中显式设置枚举数的值。任何后续枚举器的值都必须是最后一个枚举器的值加一。

enum demo {
   first,
   second = 4,
   third,
   fourth
};

这里first的值为 0,但其余三个的值为 4、5、6。

于 2013-09-29T13:37:53.337 回答
0

是的。在 C 中,枚举始终从 0 开始,除非您明确指定另一个值。任何未指定的值都将从最后指定的值单调增加。

请注意,枚举只保证是一个足够大的整数类型来表示枚举中的值。它可能不是整数。一些 C 编译器将使用 char 或 short 来表示小型枚举。

于 2013-09-29T13:36:54.067 回答