試行錯誤しながら数字を「推測」しようとするコンソールアプリケーションを書いていたところ、問題なく動作しましたが、ぼんやりと書いた特定の部分について疑問に思いました。
コードは次のとおりです。
_#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);
_
_((100/(i<<=1))?:1)
_を使用して、100/(i<<=1)
が0(またはfalse)を返した場合、式全体が1 _((100/(i<<=1))?:***1***)
_と評価されることを確認し、条件の一部を残して、真の空_((100/(i<<=1))? _this space_ :1)
_でした。正しく機能しているようですが、条件のその部分を空のままにしておくことにリスクはありますか?
これはGNU C拡張( ?: wikipedia entry を参照))であるため、移植性のために2番目のオペランドを明示的に記述する必要があります。
'true'の場合、条件付きの結果を返します。
次のステートメントはほぼ同等です。
a = x ?: y;
a = x ? x : y;
唯一の違いは、最初のステートメントにあります。x
は常に1回評価されますが、2番目のステートメントでは、x
がtrueの場合に2回評価されます。したがって、唯一の違いは、x
を評価するときに副作用がある場合です。
いずれにせよ、これは構文の微妙な使用法だと思います...そして、コードを維持している人たちに共感がある場合は、オペランドを明示的に述べる必要があります。 :)
一方、これは一般的なユースケースにとってはちょっとしたトリックです。
これは GCC拡張 C言語です。 ?:
の間に何も表示されない場合、真の場合は比較の値が使用されます。
条件式の中間オペランドは省略できます。次に、最初のオペランドがゼロ以外の場合、その値は条件式の値です。
したがって、式
x ? : y
それがゼロ以外の場合、xの値を持ちます。それ以外の場合、yの値。
この例は完全に同等です
x ? x : y
この単純なケースでは、中間オペランドを省略する機能は特に役に立ちません。有用になるのは、最初のオペランドに副作用が含まれている場合、または含まれている可能性がある場合です(マクロ引数の場合)。次に、途中でオペランドを繰り返すと、副作用が2回実行されます。中間オペランドを省略すると、再計算による望ましくない影響なしに、すでに計算された値が使用されます。