40

以下是c#代码:

   static void Main(string[] args)
    {
        uint y = 12;
        int x = -2;
        if (x > y)
            Console.WriteLine("x is greater");
        else
            Console.WriteLine("y is greater");
    }

这是 C++ 代码:

int _tmain(int argc, _TCHAR* argv[])
{
unsigned int y = 12;
int x = -2;
if(x>y)
    printf("x is greater");
else
    printf("y is greater");

return 0;
}

两者都给出不同的结果。我错过了一些基本的东西吗?任何想法?

4

3 回答 3

48

C++ 和 C# 是不同的语言。在比较的情况下,它们有不同的处理类型提升的规则。

在 C++ 和 C 中,它们通常被比较为好像它们都是无符号的。这称为“无符号保留”。C++ 和 C 编译器传统上使用“无符号保留”,并且在 C++ 标准和 K&R 中指定了它的使用。

在 C# 中,它们都被转换为有符号长整数,然后进行比较。这被称为“保值”。C# 指定值保留。

ANSI C 也指定了值保留,但仅在处理 short 和 char 时。短裤和字符(有符号和无符号)以保留值的方式上转换为整数,然后进行比较。因此,如果将 unsigned short 与有符号 short 进行比较,结果会像 C# 示例一样。任何时候转换到更大的大小时,都会以保留值的方式完成,但是如果两个变量的大小相同(而不是短裤或字符)并且其中一个是无符号的,那么它们将作为无符号量进行比较ANSI C。comp.lang.c FAQ中对这两种方法的优缺点进行了很好的讨论。

于 2011-11-25T07:54:39.163 回答
12

在 C++ 中,当您比较 anunsigned int和 asigned int时,将signed int转换为unsigned int. 将负数转换signed int为 anunsigned int是通过添加 来完成的UINT_MAX + 1,它大于12因此结果。

在 C# 中,如果您得到相反的结果,则这意味着在 C# 中,两个表达式都被转换为(或) 1,然后进行比较。signed int signed longlongSystem.Int64

在 C++ 中,您的编译器一定已经给了您警告:

警告:有符号和无符号整数表达式之间的比较

规则:
始终认真对待编译器发出的警告!

1正如 svick 在评论中正确指出的那样。

于 2011-11-25T07:55:55.490 回答
4

我不知道 C# 的标准,但在 C++ 标准中,usual arithmetic conversions将应用于关系运算符的两个操作数:

[......enum, floating point type involed......] 

— Otherwise, the integral promotions (4.5) shall be performed on both operands.
  Then the following rules shall be applied to the promoted operands:

    — If both operands have the same type, no further conversion is needed.

    — Otherwise, if both operands have signed integer types or both have
      unsigned integer types, the operand with the type of lesser integer
      conversion rank shall be converted to the type of the operand with
      greater rank.

    — Otherwise, if the operand that has unsigned integer type has rank
      greater than or equal to the rank of the type of the other operand, the
      operand with signed integer type shall be converted to  the type of the
      operand with unsigned integer type.

    — Otherwise, if the type of the operand with signed integer type can
      represent all of the values of the type of the operand with unsigned
      integer type, the operand with unsigned integer type shall be converted
      to the type of the operand with signed integer type.

    — Otherwise, both operands shall be converted to the unsigned integer type 
      corresponding to the type of the operand with signed integer type.

因此,当unsigned int与 比较时intint将转换为unsigned int,转换为 时-2将成为一个非常大的数字unsigned int

于 2011-11-25T08:30:19.180 回答