47

試行錯誤しながら数字を「推測」しようとするコンソールアプリケーションを書いていたのですが、うまくいきましたが、ぼんやりと書いた部分が気になりました。

コードは次のとおりです。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int x,i,a,cc;
    for(;;){
    scanf("%d",&x);
    a=50;
    i=100/a;
for(cc=0;;cc++)
{
    if(x<a)
    {
        printf("%d was too big\n",a);
        a=a-((100/(i<<=1))?:1);

    }
    else if (x>a)
    {
        printf("%d was too small\n",a);
        a=a+((100/(i<<=1))?:1);

    }
    else
    {
        printf("%d was the right number\n-----------------%d---------------------\n",a,cc);
        break;
    }
}
}
return 0;
}

より具体的には、私を混乱させた部分は

a=a+((100/(i<<=1))?:1); 
//Code, code
a=a-((100/(i<<=1))?:1);

以前は、 0(またはfalse)が返さ((100/(i<<=1))?:1)れた場合、式全体が1と評価されることを確認していました。条件の一部を残して、真に空の場合に機能するようにしました。正しく機能しているように見えますが、残すリスクはありますか。条件付きの空のその部分?100/(i<<=1)((100/(i<<=1))?:***1***)((100/(i<<=1))? _this space_ :1)

4

2 に答える 2

70

これはGNUC拡張機能です(?:wikipediaエントリを参照)。したがって、移植性のために、2番目のオペランドを明示的に指定する必要があります。

'true'の場合、条件付きの結果を返します。

次のステートメントはほぼ同等です。

a = x ?: y;
a = x ? x : y;

唯一の違いは、最初のステートメントにxあり、常に1回評価されますが、2番目のステートメントでは、 xtrueの場合は2回評価されます。したがって、唯一の違いは、評価xに副作用がある場合です。

いずれにせよ、これは構文の微妙な使用法だと思います...そして、コードを維持している人たちに共感を持っているなら、オペランドを明示的に述べる必要があります。:)

一方、これは一般的なユースケースにとってはちょっとしたトリックです。

于 2010-07-23T14:33:54.807 に答える
24

これはC言語のGCC拡張です。の間に何も表示?:されない場合、真の場合は比較の値が使用されます。

条件式の中央のオペランドは省略できます。次に、最初のオペランドがゼロ以外の場合、その値は条件式の値です。

したがって、式

    x ? : y

ゼロ以外の場合、xの値があります。それ以外の場合、yの値。

この例は完全に同等です

    x ? x : y

この単純なケースでは、中間オペランドを省略する機能は特に有用ではありません。これが役立つのは、最初のオペランドに副作用が含まれている場合、または含まれている可能性がある場合です(マクロ引数の場合)。次に、中央でオペランドを繰り返すと、副作用が2回実行されます。中央のオペランドを省略すると、再計算による望ましくない影響なしに、すでに計算された値が使用されます。

于 2010-07-23T14:32:45.437 に答える