トップページ > 過去ログ > 記事閲覧
()の計算順
名前:ど素人です 日時: 2008/10/09 21:13

()を用いて計算する時、内部では()が深い程先に計算されているのですか? それとも前から順に計算されて、適宜()が出るたび内部を計算するのですか? 低レベルな質問ですが、どなたか教えていただけないでしょうか。 例えばこんな感じのソースです。一応動くんですが、もしかしてメモリを破壊しているんじゃなかろうかと少し不安になったので……。 char number[3]; int i,j; number[0]=0; number[1]=8; number[2]=4; j=0; for (i=0;i<5;i++){ if(i<3 && (number[i]>5)){j+=number[i];} }

Page: 1 |

Re: ()の計算順 ( No.1 )
名前:さかな 日時:2008/10/09 21:47

>もしかしてメモリを破壊しているんじゃなかろうかと少し不安になったので……。 そんなことはありません。 ちゃんと()の深い順から計算されます。 もし心配なら、2*(2*(2+4))などの計算をやってみてください。
Re: ()の計算順 ( No.2 )
名前:ど素人です 日時:2008/10/09 22:15

ありがとうございます。 つまり優先順位が高い程内部でも先に演算されるんですね。 これで安心……っていや、それだと逆にやばいッス。 自分の場合、()の中から先に計算されてたら(i<3)の所でif文を抜けられずにnumber[5]とかを参照したりしてる事になりそうです。しかも自分、それに代入なんかもしてるかもしれないので余計にやばい……。 とりあえずi<3にあたる部分に()をつけて先に計算されるようにします。 教えていただいてありがとうございました!
Re: ()の計算順 ( No.3 )
名前:ど素人です 日時:2008/10/09 22:18

上、number[5]じゃなくて[4]ですね。間違えました。
Re: ()の計算順 ( No.4 )
名前: 日時:2008/10/10 01:19

>()の中から先に計算されてたら(i<3)の所で >if文を抜けられずにnumber[5]とかを >参照したりしてる事になりそうです 言っていることがよくわかりませんが、 上記で提示しているコードでは、 ifの中でiは変動していません。 よってi<3に()をつけても計算結果に影響しないと 思いますが。。。 >number[5]じゃなくて[4]ですね。間違えました。 number[5]であってと思いますが。。。 for (i=0;i<5;i++) iの変動範囲は 0 - 4 です。 number[4]で定義した領域は4ですが、 C言語の配列は0オリジンなので、 0-3の4つになります。 char number[3]; for (i=0;i<5;i++){ if(i<3 && (number[i]>5)){j+=number[i];} } まぁ、動けばいいということならいいんですが、 そもそも、3つしか用意していない領域に対して、 なぜ、ループを5回も回す必要があるのか理解不能。 こういうコードはバグを生み出す元凶になります。 素直に char number[3]; for (i=0;i<3;i++){  if((number[i]>5)){j+=number[i];} } ではだめなの? #まぁ、なぜchar型の中身と整数値である5を #比べているのかも微妙ではありますが。。。
Re: ()の計算順 ( No.5 )
名前:YKN 日時:2008/10/12 13:51

おそらく、拝察するに if(i<3 && (number[i]>5)){j+=number[i];} この、最初の条件式である、 「i<3」 を満たした時だけ 「number[i]>5」の条件判定をさせたいって事ではないでしょうか? もし「i<3」と「number[i]>5」が同時に判定されちゃうのだとしたら i = 4 の時に number[4] になっちゃってまずいですもんね。 私もこういうのは不安に思ってましたが、 if文の条件式は、最初の判定が満たされなかった場合、 以降の判定は無視される、とどこかで聞いてからは 気にせず使ってますね。
Re: ()の計算順 ( No.6 )
名前:けいし 日時:2008/10/13 20:17

アトリエミュート開発担当の、けいしと申します。 C・C++では、"&&"や"<"なども『演算子』ですので、 if(i<3 && (number[i]>5)){j+=number[i];} は、 if(i<3 && number[i]>5){j+=number[i];} と同じです("4+(3*2)"と書くのに似ている)。 そして、C・C++では、 if・while・do-whileの条件文の評価が確定された段階で、 以後の条件文内の演算をスキップすることが 定義されていますので、 if(i<3 && number[i]>5){j+=number[i];} は、 if(i<3) { if(number[i]>5){j+=number[i];} } と同じです。 よってiが4のときも、 バッファ外を参照することはありません! 安心して大丈夫です><
Re: ()の計算順 ( No.7 )
名前:憂煉 日時:2008/10/13 22:16

>>けいしさん コンパイラの最適化によって異なってくるので安心とまでは言えないですよー 演算子の優先順位はこのページが詳しいです。 ttp://www9.plala.or.jp/sgwr-t/c/sec14.html#s14-5
Re: ()の計算順 ( No.8 )
名前:IW 日時:2008/10/14 00:54

> 憂煉さん > コンパイラの最適化によって異なってくるので  C++の場合言語仕様によって、 if(A && B){}  と書いたとき、Aと Bの operator&&()が働くと、Aと B両方が 実行されることはありますが、コンパイラの最適化によって 異なってくるとは知りませんでした。  最適化されるとどういうふうに、変わってくる可能性があるのでしょうか?
Re: ()の計算順 ( No.9 )
名前: 日時:2008/10/14 02:04

>>コンパイラの最適化によって異なってくる これはありえません。 けいしさんも書かれていますが、 Cの規格では、以下のように規定されています。 (X3010 - 6.5.13) 論理AND演算子の意味規則として、 ビット単位の2項&演算子と異なり,&&演算子は 左から右への評価を保証し第1オペランドの値が 0と比較して等しい場合、第2オペランドは評価しない。 つまり1の条件が偽である場合2の条件は 処理されません。 条件が常に一定である場合など特殊な場合に コンパイラが最適化によりif文を消したりすること はあるかもしれませんが、これらが処理系において 最適化の過程で消されるということは、 まずありえません。 なくなったら式の評価結果が変わってしまいます。 副作用として有名なのは、 以下のようなコードの場合、 1の条件の結果次第でhugaの値が 変わってしまうなどです。 int hoge=0,huga=0; int huge[2]; if( hoge==1 && huge[huga++]==0 ){ /* */} hogeが1の場合hugaは評価されインクリメント されますが、hogeが1でない場合、 hugaとそれに対するインクリメント演算子は 処理されないため、インクリメントされない というような場合が考えられます。 また、C++でもX3010に基づきCが提供する機能に 加えての言語仕様となるため、この辺りの仕様は Cと同じです。(X3014 - 1.1)

Page: 1 |