「お昼の放送」の思い出

C言語を勉強中 b += a ? 1 : 0;  という1文があり??な状態になってしまいました。(+=、?:の意味はわかります。おそらく。)

これは aが0以外ならb=b+1;、aが0ならb=b+0; (aは条件であり、bにたされるわけではない。)。if文より文が短く、処理も早い、という利点。 で間違いないですか?


自信を持って次に進みたいので、どなたか教えていただきたいと思います。お願いします。

A 回答 (6件)

★解釈は合っています。


>if文より文が短く、処理も早い、という利点。 で間違いないですか?
 ↑
 条件演算子(三項演算子)は『if』文を使わないため関数の引数や『for』文の式にも
 記述できるメリットがあります。
 私はマクロ関数などでは良く使います。
 もちろん代入文とかでも使うこともあります。
 多用すると分かりにくくなるため注意が必要かもしれませんね。

サンプル1:
int i;

for ( i = 0 ; i < (sw ? 100 : 200) ; i++ ){
 :
}
※変数『sw』の真偽により繰り返しの回数を100か、200に制御しています。
※通常あまりこのような事はしませんが、for文の条件式として利用できます。

サンプル2:
int sign;

sign = ((value < 0) ? -1 : (value > 0) ? +1 : 0);
※変数『value』の符号情報を sign に -1、0、+1 をセットします。
※このような使い方はマクロ関数を用意してたまに利用しています。

その他:
>自信を持って次に進みたいので、どなたか教えていただきたいと思います。お願いします。
 ↑
 それなら1つ問題です。
 (1)ans = (a ? b : c ? d : e);
 (2)ans = (a ? b ? c : d : e);
 この2つの式は動作が全く異なりますが、日本語(文章)で説明できますか?
・補足にどう解釈したかを書いてみて下さい。

この回答への補足

まずは、回答ありがとうございます。
それと、私の勉強に付き合っていただきありがとうございます。
(1) aが真ならb、aが偽ならc ? d : e 
          ↓
  aが真ならans = b、aが偽かつcが真ならans = d、aが偽かつcも偽ならans   = eの3パターンに。
(2) aが真ならb ? c : d 、aが偽ならe 
          ↓
  aが真かつbも真ならans = c、aが真かつbが偽ならans = d、aが偽ならans = e
と考えました。どうですか?

補足日時:2008/01/23 04:04
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
出題していただいた問題を解いてみましたので、お時間あるときにでも、ぜひ正否を教えていただきたいです。
回答で示して頂いた例も、こんな使い方があるのかと、驚きました。未熟すぎな私ですが、プログラミングの幅が広がったと思います。
お時間を割いていただき本当にありがとうございます。

お礼日時:2008/01/23 04:32

★Tacosan さん、ご指摘ありがとうございます。


 質問者さんへ訂正します。
 間違い⇒なお ? の前は条件式ですので変数だけの場合はその内容が『真』=0、『偽』=0以外を判定します。
 正しい⇒なお ? の前は条件式ですので変数だけの場合はその内容が『偽』=0、『真』=0以外を判定します。
 ※良く見たら真偽が逆転していました。恥ずかしいです。ごめんなさい。

最終問題の解答:
(a) (b) (ans)    (x) (y) (z)
真  真  ans = 1;  2  2  4
真  偽  ans = 1;  2  2  4
偽  真  ans = 2;  1  3  4
偽  偽  ans = 4;  1  2  5

こんな感じになります。
>if文より文が短く、処理も早い、という利点。
この記述は私がC言語を始めた最初のころに本に書かれていました。
今の時代はコンパイラの最適化が優れていますので処理が処理が早くなるかは分かりません。

>b += a ? 1 : 0;
この場合は私も if を使って記述します。
その方が見やすいです。

※昔は速度を気にして1つの変数を使いまわしたり、『resister』キーワードを付けていました。
※最近はこんな小細工しなくてもCPU処理が全体的に高速処理してくれますのであまり気にしなくても
※良いです。それよりもループ処理に時間が掛からないようにアルゴリズムを見直すべきです。

★最後に変わった使い方を紹介します。(普段はこんな使い方はしません)
#include <stdio.h>
#include <stdlib.h>

// メイン関数
int main( void )
{
 int a;
 
 printf( "『CTRL-D』+『Enter』キーで終了します。\n" );
 
 while ( scanf("%d",&a) == 1 ){
  (a > 0) ? printf("(プラス)です。\n\n") :
  (a < 0) ? printf("(マイナス)です。\n\n") : 0;
 }
 return 0;
}
キーボードから +1、-1、0 と打ち込んでみて下さい。
以上。
    • good
    • 0
この回答へのお礼

回答だけではなく、使用例や理解する為の問題まで考えていただいてありがとうございました。やっぱりプログラミングは実際に使ってみるのが一番ですね。大変勉強になりました。

お礼日時:2008/01/24 03:09

正直なはなし, 今どきの普通のコンパイラなら


b += a ? 1 : 0;

if (a)
++b;
の間に速度差があるとは思えないですね. 読み易さは明らかに後者の方が優れているので, 前者のように書く必要はないと思います.
ちなみに挙げ足とりになって申し訳ないのですが「式の値が 0 なら偽, 0 でなければ真」ですね>#4.
あとついでにいうと, C において 5+3 == 8 という式が条件判断に使えるように, 5+3 という式も条件判断に使えます>#3. 前者は「条件が成り立てば 1, 成り立たなければ 0」を返すだけです. true とか false などという高尚なものは C にはありません (ちなみに Pascal にもない).
    • good
    • 0
この回答へのお礼

訂正して頂いてありがとうございます。

お礼日時:2008/01/24 02:39

★答え合わせ


>(1) aが真ならb、aが偽ならc ? d : e 
>          ↓
>  aが真ならans = b、aが偽かつcが真ならans = d、aが偽かつcも偽ならans   = eの3パターンに。
>(2) aが真ならb ? c : d 、aが偽ならe 
>          ↓
>  aが真かつbも真ならans = c、aが真かつbが偽ならans = d、aが偽ならans = e
>と考えました。どうですか?
 ↑
 正解です。
>(1)ans = (a ? b : c ? d : e);
>(2)ans = (a ? b ? c : d : e);
 ↑
 これらはカッコを使うと分かりやすくなります。
 ↓
 (1)ans = (a ? b : (c ? d : e));
 (2)ans = (a ? (b ? c : d) : e);
 ※もし条件演算子で入れ子にする場合は積極的にカッコをいれた方が良いでしょう。
 ※私はカッコを入れるタイプです。もちろん省略しても同じですが誰が見ても分かるようにしておく。

(1)の解答:
(a) (c) (ans)
真  真  ans = b;
真  偽  ans = b;
偽  真  ans = d;
偽  偽  ans = e;

(2)の解答:
(a) (b) (ans)
真  真  ans = c;
真  偽  ans = d;
偽  真  ans = e;
偽  偽  ans = e;

その他:
 一覧として書き出せば良く分かります。
 なお ? の前は条件式ですので変数だけの場合はその内容が『真』=0、『偽』=0以外を判定します。
 分かっているとは思いますが、通常は関係演算子などと組み合わせて利用します。
・最後にもう1つ問題です。
 int x = 1;
 int y = 2;
 int z = 4;
 
 ans = (a ? x++ : b ? y++ : z++);
 このような場合はどうなるでしょうか?
・また補足に書いてみて下さい。
 ans、x、y、zのそれぞれの値も書いて下さい。

この回答への補足

(a) (b)
真 真 ans=1,x=2,y=2,z=4
真 偽 ans=1,x=2,y=2,z=4
偽 真 ans=2,x=1,y=3,z=4
偽 偽 ans=4,x=1,y=2,z=5
でどうですか?
たしかx++は式を評価したあとにx=x+1;とおぼえてるんですが…。

補足日時:2008/01/24 02:52
    • good
    • 0

おはようございます



aが、0とか、0以外と理解しているようですが、三項条件文は、正確に言うと、aの条件が、trueか、falseです。

つまり、b+=(5+3)?1:0;という、書き方は、三項条件文では、間違いになります。正確には、b+=((5+3)==8)?1:0;が、正しい書き方になります。if分に置き換えると、

if (5+3==8)
{
  b=b+1;
}
else
{
  b=b+0;
}
と、理解しやすくなります。

それと、"if分より処理が早い"と言うのは、現代では、コンパイラ(C言語を解釈して、コンピュータが理解できるコードに変更する)の性能や、CPU(マルチコアや、キャッシュ)の性能によって、大幅に異なりますので、一概には言えません。

インクリメント演算子、一つをとっても、++i;と、i++;で、実行環境では、処理スピードも変化する場合もあります。

処理スピードは、コンパイラのオプティマイズに任せて、人から見た時に判りやすいコードを書くこと(コメントを多く)をお勧めします^^
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
どこかでif文を多用すると処理が遅くなるという話を聞いたことがあって、それが頭の隅に残ってたんですが、そんなに気にすることでもないのですね^^)。

お礼日時:2008/01/24 02:36

>aが0以外ならb=b+1;、aが0ならb=b+0; (aは条件であり、bにたされるわけではない。

)
そう。

>if文より文が短く、処理も早い、という利点。
別に短かくはないでしょう

if ( a ) b++;

の方が明確だと思いますけど。
    • good
    • 0
この回答へのお礼

プログラミングは同じ働きでも書き方によって、見やすさや理解のしやすさが全く違ってくるということが実感できました。if(a) b++;はとても見やすく、わかりやすいですね。回答ありがとうございました。

お礼日時:2008/01/23 03:44

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報