- ベストアンサー
C言語 外部変数について
#include<stdio.h> int count; int f(int x){ int i; for(i=0 ; x < 10 ; i++){ x*=2; count++; } return x; } int main(void){ count=0; printf("%d %d",f(1),count); return 0; } のようなプログラムを作って実行してみたところ f(1)の部分は1024と自分の目的通りの結果が返ってきましたが countの部分が0とでてきてしましました 関数内で10回の繰り返しを行ったので 10がはいってると思ったのですが どこを直せば10の値がでてきますか?
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
> f(1)の部分は1024 本当ですか? > for(i=0 ; x < 10 ; i++){ x < 10 のところが間違っていると思います。 > どこを直せば10の値がでてきますか? > printf("%d %d",f(1),count); ここを、 printf("%d\n", f(1)); printf("%d\n", count); のようにしてみたらいかがでしょうか。 もとのコードでcountが10にならなかったのは、 おそらく、式の評価順が関係していると思います。
その他の回答 (5)
printfの式の評価順による影響です。これは処理系(コンパイラ)などの判断に依存する部分もありますので、なるべく依存しないようなつくりにしましょう。 (前略) int ret_sts = 0; … ret_sts = f(1); printf("%d %d",ret_sts,count); (後略) とすれば問題ないはずです。
- Tacosan
- ベストアンサー率23% (3656/15482)
i=0; f(i++, i++); は未定義動作になるからどんな処理になるかわからないはずです>#4. f(0, 1) かもしれませんし f(1, 0) かもしれませんし, あるいは f(0, 0) かもしれません. もちろん未定義なので (その他の結果も含めて) どうなっても文句はいえないんですが.
- dummyplug
- ベストアンサー率58% (134/230)
皆さんの回答にあるとおりなのですが、補足しておくと関数の引数の評価順序は(記憶によれば)不定だったはずです。 ですので、 i=0; f(i++, i++); みたいなコードを書くとf(0,1)になるかf(1,0)になるかはわからない(処理系の実装に依存)だったと思います。 質問のケースだと、countの値を評価するのとf(1)を評価する(関数呼び出しする)のとの順序はどうなるかわかりません。f(1)を呼び出した後にcountの値を取り出すとは限らない、ということです。 一般的にはC言語の引数渡しの規約に関連して、後ろの引数から順に評価することが多いです。多いですが、それを前提としてコードを書くと動かないケースが出ます。(例えば最適化すると動かなくなるとか。) これを避けるには、printf()の引数でf(1)を評価するのでなく、printf()の実行前にf(1)を呼ぶようにします。
- Tacosan
- ベストアンサー率23% (3656/15482)
関数呼び出しを実行する前に, 関数の引数 (と関数へのポインタ) は全て評価されます. そして, 関数の引数 (と関数へのポインタ) の評価順序は規定されていませんから, printf で表示される count の値は f(1) の実行前のものかもしれませんし実行後のものかもしれません. #1 のように変更すればいかなる処理系でも同じ結果になりますが, #2 にある「引数の順序」の変更ではまだ処理系に依存します (し, 変更しても結果が変わらない処理系があってもよい).
- shred
- ベストアンサー率35% (25/70)
printf("%d %d",f(1),count); を printf("%d %d",count,f(1)); に変更するか、もしくは f(1)を明示的に先に実行させた上で値をprintfに渡す。 関数呼び出し規約による問題です。