• ベストアンサー

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の値がでてきますか?

質問者が選んだベストアンサー

  • ベストアンサー
  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.1

> 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)

noname#62605
noname#62605
回答No.6

printfの式の評価順による影響です。これは処理系(コンパイラ)などの判断に依存する部分もありますので、なるべく依存しないようなつくりにしましょう。 (前略) int ret_sts = 0; … ret_sts = f(1); printf("%d %d",ret_sts,count); (後略) とすれば問題ないはずです。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

i=0; f(i++, i++); は未定義動作になるからどんな処理になるかわからないはずです>#4. f(0, 1) かもしれませんし f(1, 0) かもしれませんし, あるいは f(0, 0) かもしれません. もちろん未定義なので (その他の結果も含めて) どうなっても文句はいえないんですが.

  • dummyplug
  • ベストアンサー率58% (134/230)
回答No.4

皆さんの回答にあるとおりなのですが、補足しておくと関数の引数の評価順序は(記憶によれば)不定だったはずです。 ですので、 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)
回答No.3

関数呼び出しを実行する前に, 関数の引数 (と関数へのポインタ) は全て評価されます. そして, 関数の引数 (と関数へのポインタ) の評価順序は規定されていませんから, printf で表示される count の値は f(1) の実行前のものかもしれませんし実行後のものかもしれません. #1 のように変更すればいかなる処理系でも同じ結果になりますが, #2 にある「引数の順序」の変更ではまだ処理系に依存します (し, 変更しても結果が変わらない処理系があってもよい).

  • shred
  • ベストアンサー率35% (25/70)
回答No.2

printf("%d %d",f(1),count); を printf("%d %d",count,f(1)); に変更するか、もしくは f(1)を明示的に先に実行させた上で値をprintfに渡す。 関数呼び出し規約による問題です。

関連するQ&A