为什么模数处理不同的int和枚举?

时间:2014-12-04 12:46:52

标签: c enums ansi modulus

如果运行以下代码,您将看到模数结果在整数上可能为负,但在枚举上始终为正。

我的情况没问题(我用它来循环选项的菜单列表),但我想确定它是ANSI约束,而不是编译器实现。< / p>

#include <stdio.h>

enum targets {
    TARGET1,
    TARGET2,
    TARGET3,
    TARGET4,
    NUMTARGETS,
};

int main() {
    int i;
    enum targets selected_enum = TARGET3;
    int selected_int = TARGET3;

    for (i = 0; i < 10; i++) {
        selected_enum = (selected_enum - 1) % NUMTARGETS;
        printf("Selected_enum = %d\n", selected_enum); /* I only see positive values */
    }

    for (i = 0; i < 10; i++) {
        selected_int = (selected_int - 1) % NUMTARGETS;
        printf("Selected_int = %d\n", selected_int); /* I see negative values */
    }

    return 0;
}

2 个答案:

答案 0 :(得分:3)

首先你必须写

selected_enum = ( enum targets )( ( selected_enum - 1 ) % NUMTARGETS );

而不是

selected_enum = ( selected_enum - 1 ) % NUMTARGETS;

至于你得到的结果,它是实现定义的。

根据C标准(6.7.2.2枚举说明符)

  

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

和(6.3转换,6.3.1.1布尔,字符和整数)

  

- 任何枚举类型的等级应等于该等级   兼容的整数类型

例如MS VC ++ 2010输出

Selected_enum = 1
Selected_enum = 0
Selected_enum = -1
Selected_enum = -2
Selected_enum = -3
Selected_enum = 0
Selected_enum = -1
Selected_enum = -2
Selected_enum = -3
Selected_enum = 0
Selected_int = 1
Selected_int = 0
Selected_int = -1
Selected_int = -2
Selected_int = -3
Selected_int = 0
Selected_int = -1
Selected_int = -2
Selected_int = -3
Selected_int = 0

因此,您使用的编译器似乎将枚举兼容类型定义为无符号类型。

尝试运行以下代码

#include <stdio.h>

int main( void ) 
{
    enum targets { TARGET1, TARGET2, TARGET3, TARGET4, NUMTARGETS, };

    int i;
    enum targets selected_enum = TARGET3;
    int selected_int = TARGET3;

    for ( i = 0; i < 10; i++ ) 
    {
        if ( ( selected_enum = ( enum targets )( selected_enum - 1 ) ) >= 0 ) printf( "unsigned %u\n", +selected_enum );
        else  printf( "signed %d\n", selected_enum );
    }


    return 0;
}

在www.ideone.com上运行此程序后,我得到了

unsigned 1
unsigned 0
unsigned 4294967295
unsigned 4294967294
unsigned 4294967293
unsigned 4294967292
unsigned 4294967291
unsigned 4294967290
unsigned 4294967289
unsigned 4294967288

当MS VC ++ 2010(以及在线MS VC ++ 2014编译器)输出

unsigned 1
unsigned 0
signed -1
signed -2
signed -3
signed -4
signed -5
signed -6
signed -7
signed -8

答案 1 :(得分:0)

这里的目标是一个用户定义的数据类型,其范围在0到4之间。所以当 目标数据类型的值在零下将来自四个。这就是不会给出负值的原因。

在整数中,它是(两个/四个)字节。所以它允许负面。你可以检查一下。

为char变量指定一个大于127的值,然后使用%d打印它。你将获得 原因。

char a=170; printf("%d\n",a);

为此,您将获得输出为-86。