我在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;
答案 0 :(得分: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
答案 1 :(得分:1)
枚举在Java中是否像0?n一样?
是的,
答案 2 :(得分: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
答案 3 :(得分:0)
是。在C枚举中,除非明确指定其他值,否则始终从0开始。任何未指定的值将从最后指定的值单调增加。
请注意,枚举仅保证是足够大的整数类型,以表示枚举中的值。它可能不是int。有些C编译器会使用char或short作为小枚举。
答案 4 :(得分:0)
是,默认情况下,第一个枚举数的值为0.但也可以在说明符中显式设置枚举数的值。任何后续枚举器必须具有最后一个枚举器的值值加一。
enum demo {
first,
second = 4,
third,
fourth
};
此处first
的值为0,但其余三个的值为4,5,6。
答案 5 :(得分: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);
虽然我希望你喜欢表面更深的划痕,但是你应该比成员函数更快地停下来。也许我应该比多态性的实现更早地停止了很多:)