7

私は次のコードでかなり混乱しています:

#include <stdio.h>
#include <stdint.h>

int main(int argc, char ** argv)
{
    uint16_t a = 413;
    uint16_t b = 64948;

    fprintf(stdout, "%u\n", (a - b));
    fprintf(stdout, "%u\n", ((uint16_t) (a - b)));

    return 0;
}

それは戻ります:

$ gcc -Wall test.c -o test
$ ./test
4294902761
1001
$ 

式(a --b)のタイプはuint32_tのようです。両方の演算子がuint16_tであるため、理由がわかりません。

誰かが私にこれを説明できますか?

4

3 に答える 3

16

C標準はこれを非常に明確に説明しています(§6.5.6加法演算子):

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

(§6.3.1.8 通常の算術変換):

...整数昇格は両方のオペランドで実行されます。

(§6.3.1.1 ブール値、文字、および整数):

intが元の型のすべての値を表すことができる場合、値はint;に変換されます。... これらは整数プロモーションと呼ばれます。他のすべての型は、整数の昇格によって変更されません。

はプラットフォーム上intの のすべての値を表すことができるため、減算が実行される前に に変換されます。結果の型は で、として渡されます。引数でフォーマッタを指定しました。厳密に言えば、これは未定義の動作を引き起こしますが、プラットフォームでは、引数は 2 の補数表現として解釈され、出力されます。uint16_tabintintprintfint%uintint

于 2011-10-31T14:11:55.983 に答える
1

数値の最上位ビットを (16 ビット符号なし整数への明示的なキャストによって) 破棄すると、(0 と 2^16-1 の範囲内で) よりも小さい結果が得られます。前。

于 2011-10-31T14:17:41.393 に答える
0

C はunsigned int、引き算を行う前に引数を にプロモートします。これは標準的な動作です。

たとえば、unsigned int と signed int が存在する C 式では、どの型がどの型に昇格されますか? を参照してください。詳細については。

于 2011-10-31T14:03:12.137 に答える