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# では、両方とも符号付き long に変換されてから比較されます。これを「価値保存」といいます。C# では、値の保持が指定されています。

ANSI C も値の保存を指定していますが、これは short と char を扱う場合のみです。Short と char (符号付きおよび符号なし) は、値を保持する方法で int にアップコンバートされてから比較されます。したがって、unsigned short を signed short と比較すると、結果は C# の例のようになります。より大きなサイズへの変換が行われるときはいつでも、値を保持する方法で行われますが、2 つの変数が同じサイズ (short や char ではない) で、どちらかが符号なしの場合、それらは符号なしの量として比較されます。 ANSI C. comp.lang.c FAQ には、両方のアプローチの長所と短所に関する良い議論があります。

于 2011-11-25T07:54:39.163 に答える
12

unsigned intC++ では、 anと aを比較するとsigned intsigned intは に変換されunsigned intます。負数signed intを に変換するにunsigned 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 に答える