【问题标题】:C comparison char and intC比较char和int
【发布时间】:2009-06-18 01:18:11
【问题描述】:

在下面的代码块中,7 的 if 语句中发生的隐式转换是什么?我会认为它最终会是 (0x98

char minstogo = 0x98;
if(minstogo <= 7) {
   DoMyStuff();
}

【问题讨论】:

    标签: c


    【解决方案1】:

    Whenever you have a binary operator (one of + - * / % &lt;&lt; &gt;&gt; &amp; | ^ == != @987654333 @&lt;=&gt;&gt;=) 两个不同类型的整型操作数之间,在运算前将两种类型转换为通用类型。决定转换为类型的规则是(来自 C99 标准的第 6.3.1.8 节):

    如果两个操作数的类型相同,则不需要进一步转换。

    否则,如果两个操作数都具有有符号整数类型或都具有无符号 整数类型,具有较小整数转换等级类型的操作数是 转换为具有更高等级的操作数的类型。

    否则,如果具有无符号整数类型的操作数的秩大于或 等于另一个操作数的类型的等级,然后操作数与 有符号整数类型转换为无符号操作数的类型 整数类型。

    否则,如果带符号整数类型的操作数的类型可以表示 无符号整数类型的操作数类型的所有值,然后 将无符号整数类型的操作数转换为 带符号整数类型的操作数。

    否则,两个操作数都转换为无符号整数类型 对应于带符号整数类型的操作数的类型。

    在这种情况下,char 可以是有符号或无符号整数类型——它的符号是实现定义的。不过幸运的是,int 可以表示char 的所有可能值,无论char 是否已签名,假设您在一个chars 为8 位且ints 为至少 16 位。

    如果char是有符号的,那么上面的第二段适用,所以两个操作数都被转换为int(等级更高的类型;等级的定义有点复杂,但它本质上相当于位大小类型)。由于 0x98 作为有符号的char 为负数,因此将其转换为整数 -104,即小于 7。

    如果 char 是无符号的,则适用第四段。未签名的char 将转换为 152 作为int,大于 7。

    永远不要依赖chars 被签名或未签名。如果您需要某种符号的 8 位整数,显式使用 signed charunsigned char,或使用 C99 类型 int8_tuint8_t,定义 int &lt;stdint.h&gt;

    很容易被整数提升规则引起的细微错误所困扰。我强烈建议您始终使用带有 gcc 的-Wall 进行编译,这会警告您有符号和无符号整数之间的比较,这通常会导致错误。

    【讨论】:

      【解决方案2】:

      这里可能发生的是 char 是有符号值,因此 0x98 注册为负数。因此它小于 7

      同样在这种情况下,7 将不会进行任何转换。相反,char 将扩大到与 7 相同的整数类型,然后进行比较。

      【讨论】:

        【解决方案3】:

        将 chars 表示为 8 位字节,将 minstogo 设置为 0x98 是二进制值 10011000。符号位已设置,它是一个负整数值。您可能需要一个 unsigned char 以便测试评估为 false。

        【讨论】:

          【解决方案4】:

          它将与0x98 &lt;= 7 评估相同,除非平台的char 类型默认为带符号且CHAR_BIT 为8。在这种情况下,minstogo 的值将为负,minstogo &lt;= 7 将为真。

          【讨论】:

            【解决方案5】:

            0x98 是 152。

            由于您声明了“char”,而不是“unsigned char”,因此您尝试将 152 分配给范围为 -128 - 127 的类型。

            这将溢出,并给您一个负数,即

            【讨论】:

              【解决方案6】:

              使用具有当前设置的编译器,char 是有符号类型:并且由于设置了其值的高位 (0x80),因此该值是负数。当 minstogo 被加宽时,该负号被保留(通过符号扩展),因此 minstogo 被加宽为小于 7 的负整数(例如 0xFF98)。

              【讨论】:

              • 它有一个实现定义的标志。有时(在某些主机上)已签名,有时(在其他主机上)未签名。
              • char 是有符号还是无符号因平台、编译器和配置而异;例如,PowerPC ABI 建议 char 是无符号的,而 GCC 采用 -fsigned-char/-funsigned-char 开关来覆盖平台默认值。可移植代码不应依赖于 char 的(未)签名。
              • OP 的编译器将他的 char 视为有符号类型。
              • 使用 MSVC,默认情况下已签名,并带有编译器选项使其未签名。
              • 在 x86 上,所有编译器都遵循 ABI 对签名字符的建议。我并不是说这是 OP 的问题。事实上,这个问题很明显。我与您的总体陈述争论不休,即“char 是有符号类型”——这需要用“在某些系统上”或“在这种情况下”进行限定,因为在当今许多活跃使用的现有系统上,它是非常错误的。
              猜你喜欢
              • 2011-07-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-01-18
              • 2022-01-24
              • 2013-05-10
              相关资源
              最近更新 更多