質問: ### 問題点 フィボナッチ数列と関数を呼び出した回数を求めるプログラムを書いたのですが、下記のプログラムでは関数を呼び出した回数がカウントされず次の部分 scanf("%d",&num); printf("%d %d\n",fib(num),count); これをint型の変数Fを用いて、 scanf("%d",&num); F=fib(num); printf("%d %d\n",F,count); このようにしたら正確に実行することができました。これってなぜですかね? ### ``` #include int count; int fib(int n) { count++; if(n==1 || n==2) return 1; return fib(n-1)+fib(n-2); } int main() { int num; count=0; scanf("%d",&num); printf("%d %d\n",fib(num),count); return 0; } ``` また、カウントをポインタを使って行おうとして、次のようにプログラムを少し改良したのですが Segmentation fault (コアダンプ) と出ました。解決法を教えてください。 ``` #include int *count; int fib(int n) { *++count; if(n==1 || n==2) return 1; return fib(n-1)+fib(n-2); } int main() { int num,F; *count=0; scanf("%d",&num); F=fib(num); printf("%d %d\n",F,*count); return 0; } ```
回答: すでに回答されていますが、 printf("%d %d\n", fib(num), count);ではprintfに "%d %d\n", fib(num), count という3つの引数を渡します。Cは値渡しなので値を計算しないといけないのですがその計算順序は決まっていません(順序を規定しない、という規格)。つまり、コンパイラの癖等によりどのような順序で引数を計算されても問題ないようなプログラムを書かないとダメです。 現在お使いのコンパイラなら printf("%d %d\n", count, fib(num)); なら正常に動く可能性がありますが、それはたまたまであって、コンパイラが変わったり最適化レベルを変えると挙動が変わる可能性があります(挙動が変わっても規格通りなので文句は言えません)。 対応ですが、すでにお気づきのように 一旦fib()の戻り値を変数に入れるのでもいいですし、 printf("%d \n", fib(num));printf("%d\n", count); とpritfを2回に分けて呼び出すのでも。