質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

680閲覧

c言語 フィボナッチ数列

maikeru

総合スコア68

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2017/10/23 04:42

###問題点
フィボナッチ数列と関数を呼び出した回数を求めるプログラムを書いたのですが、下記のプログラムでは関数を呼び出した回数がカウントされず次の部分
scanf("%d",&num);
printf("%d %d\n",fib(num),count);
これをint型の変数Fを用いて、
scanf("%d",&num);
F=fib(num);
printf("%d %d\n",F,count);
このようにしたら正確に実行することができました。これってなぜですかね?

C

1#include <stdio.h> 2 3int count; 4 5int fib(int n) 6{ 7count++; 8 9if(n==1 || n==2) 10return 1; 11return fib(n-1)+fib(n-2); 12} 13 14int main() 15{ 16int num; 17count=0; 18 19scanf("%d",&num); 20printf("%d %d\n",fib(num),count); 21 22return 0; 23 24}

また、カウントをポインタを使って行おうとして、次のようにプログラムを少し改良したのですが
Segmentation fault (コアダンプ)
と出ました。解決法を教えてください。

C

1#include <stdio.h> 2 3int *count; 4 5int fib(int n) 6{ 7*++count; 8 9if(n==1 || n==2) 10return 1; 11return fib(n-1)+fib(n-2); 12} 13 14int main() 15{ 16int num,F; 17*count=0; 18 19scanf("%d",&num); 20F=fib(num); 21printf("%d %d\n",F,*count); 22 23return 0; 24 25}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

(1)

c

1printf("%d %d\n", fib(num), count); 2 3```のような可変長引数を自作する場合を考えると分かり易いかもしれません。 4printfのような処理を自作する場合 va_list を使って引数にアクセスしますが 5スタックに積まれている引数へのアクセスを va_list なポインタで行います。 6この時、ポインタの先頭には1番目の引数、次には2番目の引数、と引数の順番 7通りにポインタを進める事でアクセスできます。 8つまりスタックには逆順に積み上げられているという事です。 9上の例では 10・最初にcountがスタックに積まれる 11・次にfib(num)の戻り値がスタックに積まれる 12という事です。 13countがスタックに積まれた時点でまだfib(num)が実行されていないのでfib()の中で 14更新されるcountはまだ反映される前です。 15 16参考:[va_list の解説ページ](https://qiita.com/kurasho/items/1f6e04ab98d70b582ab7) 17 18 19 20(2) 21*count はポインタですが初期化せずに使っているのでどのメモリを指し示しているのかが不定です。 22mainの冒頭で 23```c 24*count=0; 25 26```で初期化していますがその前にcountの実体がどこなのかを初期化しておく必要があります。 27例えば 28```c 29count = malloc(sizeof(int)); 30 31```や 32```c 33int data; 34count = &data; 35 36```等のような事です。

投稿2017/10/23 05:03

HiroshiWatanabe

総合スコア2160

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

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回に分けて呼び出すのでも。

投稿2017/11/01 01:14

a_saitoh

総合スコア702

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問