Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C将枚举与无效值进行比较_C_Enums_Comparison - Fatal编程技术网

C将枚举与无效值进行比较

C将枚举与无效值进行比较,c,enums,comparison,C,Enums,Comparison,我想试着理解当我们比较枚举和无效值时编译器是如何工作的,以及程序在执行过程中做了什么 我在工作中发现了奇怪的源代码,不理解程序的行为,这并没有给我预期的结果 我写了下面的小程序来总结我的问题 我创建一个枚举E_编号,并实例化一个值为-1的变量a。 然后我对a执行比较,检查它是否属于枚举的范围 (我知道,这真的很奇怪,但这正是我在源代码中发现的!) 我希望结果告诉我不在范围内,因为第一个条件失败(a>=first\u ENUM)。 但是第二个条件(a 我的行为与gcc版本6.3.0 2017051

我想试着理解当我们比较枚举和无效值时编译器是如何工作的,以及程序在执行过程中做了什么

我在工作中发现了奇怪的源代码,不理解程序的行为,这并没有给我预期的结果

我写了下面的小程序来总结我的问题

我创建一个枚举E_编号,并实例化一个值为
-1
的变量
a
。 然后我对
a
执行比较,检查它是否属于枚举的范围

(我知道,这真的很奇怪,但这正是我在源代码中发现的!)

我希望结果告诉我不在范围内,因为第一个条件失败
(a>=first\u ENUM)
。 但是第二个条件
(a
的失败给了我正确的结果(参见
printf()

如果我在
If
条件中的
(int)
中投射
a
,我会得到例外结果

那么在执行过程中会发生什么呢?程序是否考虑将
-1
作为另一个可能的枚举值,该枚举值将定位在
NB\u MAX\u NUMBER
之后?枚举上的
=第一个枚举)和&(a=第一个枚举)?“TRUE”:“FALSE”);
printf(“第二个条件=%s\n”,(a
gcc程序.c

.\a.exe
不在范围内
第一个条件=真
第二个条件=假


我使用的是MINGW编译器(gcc(x86_64-win32-seh-rev1,由MINGW-W64项目构建)4.9.2)

枚举器常量为。枚举数类型是一个未指定的整数类型,能够表示所有枚举数常量

:

每个枚举类型应与char兼容,char是一个有符号整数 类型,或无符号整数类型。类型的选择很简单 实现定义,128),但应能够表示 枚举的所有成员的值。枚举类型为 直到终止列表的}之后才结束 枚举器声明,然后完成

由于您没有枚举任何负值,因此该类型很可能是无符号类型。如果是,则
(E\u Number)某些整数将始终大于或等于零(
0==FIRST\u ENUM

如果将
enum
列表展开为:

typedef enum{
    NUM_NOPE=-1,
    NUM_1 = FIRST_ENUM, 
    NUM_2, 
    NUM_3,
    NB_MAX_NUMBER
}E_Number; 

<>你会强制编译器使用一个带签名的类型,结果会被逆转。

在编译程序中,编译器认为<代码> EyNo.<代码>为<代码>无符号int ,因为所有的合法值都是无符号的,所以-1被认为是~0U,即> = FixStEnEnm和 /P> 我的行为与gcc版本6.3.0 20170516(Raspbian 6.3.0-18+rpi1+deb9u1)相同

但是,如果我这样改变你的定义:

#include <stdio.h>

#define FIRST_ENUM -1
typedef enum{
    NUM_1 = FIRST_ENUM, 
    NUM_2, 
    NUM_3,
    NB_MAX_NUMBER
}E_Number; 

int main()
{
    E_Number a = -2; 

    if ((a >= FIRST_ENUM) && (a < NB_MAX_NUMBER))
    {
        printf("In Range\n"); 
    }
    else
    {
        printf("Not in Range\n"); 
    }

    printf("1st condition = %s\n", (a >= FIRST_ENUM)?"TRUE":"FALSE"); 
    printf("2nd condition = %s\n", (a < NB_MAX_NUMBER)?"TRUE":"FALSE"); 

    return 0; 
}

引用自ISO/IEC 9899:1999,6.7.2.2p3

每个枚举类型应与char兼容,char是一个有符号整数 类型,或无符号整数类型。类型的选择很简单 实施定义,108),但应能够代表 枚举的所有成员的值


因此,当您声明枚举时,您无法事先确定C的实现将选择何种类型的数据来存储该变量。出于优化原因,如果在[-128,+127]之间存储枚举常量,编译器可能不会选择4字节的整数类型。实现可以选择char来存储枚举变量,但您不能确定。可以选择任何整数数据类型作为时间,因为它可以存储所有可能的值。

有趣的是,我无法再现结果(MSVC),正如我所期望的,后两个分别为FALSE和TRUE。我不喜欢它的编写方式。如果需要一个“无效”的
enum
成员,它应该成为
enum
的一部分。您确定此处显示的程序就是您编译和执行的程序吗?如何在
If
条件“帮助”中的
(int)
中“强制转换
a
?那部分工作如你所料。显然给出错误结果的部分中没有
if
。@eugene sh我理解你的评论!此代码存在于航空软件中,当函数“接收”枚举值时,它不确定结果是否有效,并且是否属于枚举值的范围。。。
pi@raspberrypi:~ $ ./a.out 
Not in Range
1st condition = TRUE
2nd condition = FALSE
#include <stdio.h>

#define FIRST_ENUM -1
typedef enum{
    NUM_1 = FIRST_ENUM, 
    NUM_2, 
    NUM_3,
    NB_MAX_NUMBER
}E_Number; 

int main()
{
    E_Number a = -2; 

    if ((a >= FIRST_ENUM) && (a < NB_MAX_NUMBER))
    {
        printf("In Range\n"); 
    }
    else
    {
        printf("Not in Range\n"); 
    }

    printf("1st condition = %s\n", (a >= FIRST_ENUM)?"TRUE":"FALSE"); 
    printf("2nd condition = %s\n", (a < NB_MAX_NUMBER)?"TRUE":"FALSE"); 

    return 0; 
}
pi@raspberrypi:~ $ ./a.out 
Not in Range
1st condition = FALSE
2nd condition = TRUE