1
#include<stdio.h>

main()
{
      unsigned  x=1;
      signed char y=-1;
      clrscr();
      if(x>y)
       printf("x>y");
      else
     printf("x<=y");
}

符号付き文字の値が-128から127に増加しました。したがって、予想される出力は「x> y」であるはずですが、そうではありません。コンパイラは出力を返します-"x<=y"。理由を説明できますか?

4

6 に答える 6

7

比較では、signed charはに変換されるためunsigned int、非常に大きな値のように見えます。コンパイラが警告することを期待します。つまり、「署名されたものと署名されていないものを比較すると混乱します」という行の何かです。

この変換は、「関係演算子」で義務付けられています。

両方のオペランドが算術型の場合、通常の算術変換が実行されます。

于 2012-07-29T12:32:26.797 に答える
2

C11§6.8al3p95:

両方のオペランドが算術型の場合、通常の算術変換が実行されます。

C11§6.3.1.8al1p53:

[...]符号なし整数型のオペランドのランクが他のオペランドの型のランク以上の場合、符号付き整数型のオペランドは符号なし整数型のオペランドの型に変換されます。

したがって、符号なしタイプに昇格し、 ( )yより大きくなります。x1

于 2012-07-29T12:44:11.873 に答える
0

対照的に、一方のオペランドが符号なしの場合、もう一方のオペランドは、その型が符号付きであれば暗黙的に符号なしに変換されます。

詳細はこちら:符号付き/符号なしの比較

于 2012-07-29T12:34:56.147 に答える
0

あなたの場合、signedcharはunsignedintに変換されるため、-1ではなく大きな正の整数を取得します。これは、行われた通常の算術変換中に何が起こるかを説明するANSIC標準ドラフトからの抜粋です。

3.2.1.5通常の算術変換

算術型のオペランドを期待する多くの二項演算子は、同様の方法で変換を引き起こし、結果型を生成します。目的は、結果のタイプでもある共通のタイプを生成することです。このパターンは、通常の算術変換と呼ばれます。まず、一方のオペランドの型がlong doubleの場合、もう一方のオペランドはlongdoubleに変換されます。それ以外の場合、一方のオペランドのタイプがdoubleの場合、もう一方のオペランドはdoubleに変換されます。それ以外の場合、一方のオペランドのタイプがfloatの場合、もう一方のオペランドはfloatに変換されます。それ以外の場合、積分昇格は両方のオペランドで実行されます。次に、次のルールが適用されます。一方のオペランドの型がunsigned long intの場合、もう一方のオペランドはunsignedlongintに変換されます。それ以外の場合、一方のオペランドの型がlong intで、もう一方の型の型がunsigned intの場合、longintがunsignedintのすべての値を表すことができる場合、unsignedint型のオペランドはlongintに変換されます。longintがunsignedintのすべての値を表すことができない場合、両方のオペランドがunsignedlongintに変換されます。それ以外の場合、一方のオペランドの型がlong intの場合、もう一方のオペランドはlongintに変換されます。 それ以外の場合、一方のオペランドの型がunsigned intの場合、もう一方のオペランドはunsignedintに変換されます。 それ以外の場合、両方のオペランドの型はintです。

于 2012-07-29T12:43:35.637 に答える
0

すべての警告、つまりgccの場合のコンパイルに慣れてください。

gcc -Wall -Wextra -pedantic source.c -o prog

あなたの場合、旗-Wextraは次のメッセージを出します:

warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

それは理由を説明していませんが、少なくとも警告します;)。

説明は、関係演算子と比較した場合、 toを評価する符号付き変数-1はtoを評価する符号なしと等しいということです。UINT_MAX

その場合、コンパイラは明確に定義された何かを実行する必要があり、これが人々が思いついたものです...

于 2012-07-29T12:48:00.657 に答える
0

コンパイラがunsignedintとsignedintの比較を確認すると、signed intがunsignedにプロモートされます。これは、これを(Linuxボックスで)signedintに追加することを意味します。

#define UINT_MAX    (~0U) (defined in this header file : /include/linux/kernel.h)

したがって、ここで UINT_MAX -1(UINT_MAX + y)xと比較しています。これは、出力を明確に説明しています。

編集:より明確にするために:32ビットマシン上--->UINT_MAX = 2 147 483 648 = 2**31

よろしく。

于 2012-07-29T13:13:18.063 に答える