1. ホーム
  2. c

[解決済み】C言語における>>>=演算子とは?

2022-04-01 13:55:22

質問

同僚からパズルのように渡されたこのCプログラムが、実際にどのようにコンパイルされ、実行されるのかがわかりません。これは何ですか? >>>= 演算子と不思議な 1P1 リテラル?ClangとGCCでテストしてみました。警告は出ず、出力は "?

#include <stdio.h>

int main()
{
    int a[2]={ 10, 1 };

    while( a[ 0xFULL?'\0':-1:>>>=a<:!!0X.1P1 ] )
        printf("?");

    return 0;
}

解決方法は?

ラインです。

while( a[ 0xFULL?'\0':-1:>>>=a<:!!0X.1P1 ] )

には グラフ :><: に変換されます。 ][ とそれぞれ同じなので、同等です。

while( a[ 0xFULL?'\0':-1 ] >>= a[ !!0X.1P1 ] )

リテラル 0xFULL と同じです。 0xF (これは 15 ); である。 ULL が指定されているだけです。 である。 unsigned long long リテラル . いずれにせよ、ブール値としては真なので 0xFULL ? '\0' : -1 は、次のように評価されます。 '\0' であり、これは 文字リテラル その数値は単に 0 .

一方。 0X.1P1 16進数浮動小数点数リテラル は2/16=0.125に等しい。 いずれにせよ、0でない以上、ブール値としても真であるため、これを2回否定して !! を再び生成します。 1 . こうして、全体が単純化される。

while( a[0] >>= a[1] )

演算子 >>= 複合代入 は、左オペランドを右オペランドで指定されたビット数だけ右にビットシフトし、その結果を返します。 この場合、右オペランド a[1] は常に値 1 と等価なので

while( a[0] >>= 1 )

または、同等に

while( a[0] /= 2 )

の初期値は a[0] は10です。 右に1回シフトした後、5、(切り捨て)2、1、最後に0となり、ここでループが終了します。 このように、ループ本体は3回実行される。