• ベストアンサー

グローバル変数の定義について質問です。

下記は私が作成した簡易サンプルプログラムです。 #include <stdio.h> #include <stdlib.h> #include <math.h> double a=1; double b=2; double c=3; double f(){ double y; scanf("%lf",&y) ; return y; } double g(){ double y; y=f()*a; return y; } void main(){ double y; y=g()*b*c; printf("y = \n",y) ; } このプログラムでは実行しても答えが出ません。 グローバル変数でscanfを使用して入力した値を上記double g()で使用することは不可能なのでしょうか。 また、もし可能な方法があるのでしたら教えていただければ幸いです。 よろしくお願いします。

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

  • ベストアンサー
  • titokani
  • ベストアンサー率19% (341/1726)
回答No.10

#9です。 なるほど、ニュートンラプソン法について、詳しくはわからないのですが、そういった場合はmain関数でscanfを行って、引数で、方程式を解く関数に渡すのが普通でしょうか。 void calc(double a); int main() { double a; scanf("%lf",&a); calc(a);//この中で方程式を解く。 return 0; } ループについても、cals関数の中で行えば、入力は常に一回で済みます。 本当は解の出力についてもmain関数で行いたいところですが、解が何個になるのか不明なので、例がかけません。 解が1個なら、 double calc(double a); int main() { double a; double x; scanf("%lf",&a); x=calc(a);//この中で方程式を解く。 printf("x=%f\n",x); return 0; } という感じですし、2個ならば void calc(double a,double *px,double *py); int main() { double a; double x,y; scanf("%lf",&a); calc(a,&x,&y);//この中で方程式を解く。 printf("x=%f,y=%f\n",x,y); return 0; } という感じですが、二次以上の式で解が二組以上になったりすると少々面倒なので、calcの中で直接出力するのでも、とりあえずはいいかと思います。

jamboxy
質問者

お礼

お礼のお返事遅くなりましてまことに申し訳ありません。 今は至らないながらも皆様のアドバイスをもとにいろいろ考えながらためしています。 皆様のご協力には本当に感謝しています。 この場を借りてお礼申し上げます。ありがとうございました。 まだまだ分からないところだらけですので、今後ともお力添えいただけたら幸いです。

その他の回答 (9)

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.9

#1です。 >一度入力をしたらその値を再度入力せずにループをして答えを得るプログラムについて、再度アドバイス、ご指摘をいただければ幸いです。 そんなプログラムはいくらでも書けますが、普通はグローバル変数は使いませんし、こんな関数の作り方もしません。 なぜ、グローバル変数を使っているのかとか、関数を2つも作っているのかとか明らかにしていただけると、それなりのソースを示すこともできると思います。 あと、 >cは何かしらのゴミが入り、 という話ですが、この場合、cはグローバル変数ですので、0で初期化されることが規格で定められています。ゴミが入るということはありません。もちろん、あまり行儀はよくないので、明示的に初期化するほうがいいとは思います。

jamboxy
質問者

お礼

私の説明不足を深くお詫びすると共に、このような自分勝手な質問に対しご回答いただけていることを感謝いたします。 他の回答を頂いた方のお礼にも書かせていただいたのですが、現在私は連立方程式を解くためニュートンラプソン法のプログラムを作成しています。私が解きたい式には3つの未知数が存在するため、3連立方程式を立ててプログラムを作成しているのですが、その式の中には未知数のほかに状況によって変動する値が存在します。この値は未知数ではなく、状況に応じた値(定数)がすでに決まっています。 私としてはいちいちプログラムの実行が終了してから、値を修正して再度実行するよりも、一度実行したら各状況に合わせて自身で入力した値で計算が出来るようなプログラムを作成したいと考えたおりました。 しかしながら自身の勉強不足のためうまく作成することが出来ず、皆様に頼ってしまっている次第です。 見苦しい言い訳となってしまいますが、現在独学でプログラムを修学しているため思うようにプログラムの作成が出来ず、頼るばかりとなってしまっています。

  • Alice022
  • ベストアンサー率37% (3/8)
回答No.8

あ、すみません。嘘を書きました。 プロトタイプ宣言はメイン関数の上にサブ関数と一緒の定義になってますね。 プロトタイプ宣言の部分は一部訂正して、いらないところは省いて下さい。

  • Alice022
  • ベストアンサー率37% (3/8)
回答No.7

#include <math.h> ★math.hに関数のプロトタイプ宣言をしていると思うので、g()に引数を設定してあげる如何でしょうか。 double g( double *d ); //関数プロトタイプ宣言 ------------------------------------------------ double a=1; double b=2; //double c; double c = 0; //初期化 double f(){ double y; scanf("%lf",&y) ; return y; } double g( double *d ){ double y; //y=f()*a; y = *d * a; //y=f()*a;の変更、ポインタで値を受け取ったので、値を参照して計算します。 return y; } void main(){ int i; double y; y = f(); //main関数が一番始めに動くので、ここで入力するようにする。一度だけの入力となる。 for(i=0;i<=10;i++){ c=c+1; y=g( &y )*b*c; //入力データのポインタを渡します。g()で計算された値が掛け算で計算され、yに入ります。 } printf("y = %lf\n",y) ; } ------------------------------------------------ と、以上な感じです。 すみません、コンパイルで確かめてないので、コーディングミス があるかもしれませんが…、色々考え方があると思いますので、参考程度です。

jamboxy
質問者

お礼

私自身のプログラムを丁寧に修正していただきまことにありがとうございます。 元は私自身のものなので非常に分かり易く、丁寧なご回答に頭が下がるばかりです。 皆様から頂いたご指摘、ご指導を参考に自身でも再度勉強し直したいと思います。

  • BLK314
  • ベストアンサー率55% (84/152)
回答No.6

>一度入力をしたらその値を再度入力せずに >ループをして答えを得るプログラムについて、 >再度アドバイス、ご指摘をいただければ幸いです。 flagで制御すればよいのでは? こんな感じです #include <stdio.h> #include <stdlib.h> #include <math.h> double a=1; double b=2; double c; double f(){ static int flag; if (!flag) { double y; scanf("%lf",&y) ; flag = 1; } return y; } double g(){ double y; y=f()*a; return y; } void main(){ int i; double y; for(i=0;i<=10;i++){ c=c+1; y=g()*b*c; } printf("y = %lf\n",y) ; }

jamboxy
質問者

お礼

プログラムのサンプルまで作成していただき、まことにありがとうございます。 flogやその他の制御等のご指摘をいただき、非常に参考になりました。 私としては、ニュートンラプソン法で連立方程式を解くときに呼び出した変数を使用した式を解きたかったのです。そのため今回質問広場の皆様のお力をお借りいたした次第です。丁寧なご回答再度お礼申し上げます。

  • Alice022
  • ベストアンサー率37% (3/8)
回答No.5

こんにちは。 titokaniさんへの返答内容を参照すると、 printf("y = %lf", y); という記述でも答えは表示されたけれど、 for文を加えループにしたら、答えが表示されなくなってしまった。 という感じに読み取れますので、asuncionさんのアドバイスのように 1回は入力していると思うので、10回分の入力を待ってしまっているのだと思います。 for文の中で、g()がコールされています。 g()は、f()をコールしています。 f()では、scanf()によりユーザーからの入力を求めています。 この動作を10回以下まで繰り返します。 なので、画面に表示されなかったら、何かしらの値を後、10回入力してあげることで、答えが表示されると思います。 あと気になる点ですが、ちゃんとした答えが出ているのか変数cは何かしら初期化をしてあげて下さい。 変数宣言で、初期化していないのは、for文の中で、 c=c+1; とし、値を代入させているからだと思いますが、始めにcが初期化されていないので、cは何かしらのゴミが入り、+1計算されてしまいますので、意図した値を確認することができません。

jamboxy
質問者

お礼

ご回答、ご指摘まことにありがとうございます。 先に頂いた回答のお礼として書かせていただいたのですが、私としては先のプログラムにて一度入力をしたらその値を再度入力せずにループをして答えを得るプログラムを作りたかったのですが、うまくいきませんでした。 おこがましいのは承知でお願いいたします。一度入力をしたらその値を再度入力せずにループをして答えを得るプログラムについて、再度アドバイス、ご指摘をいただければ幸いです。

  • php504
  • ベストアンサー率42% (926/2160)
回答No.4

scanfでdoubleを読み込むのは%lfですがprintfでdoubleを表示するのは%fです(ほとんどのコンパイラが%lfでも動きますが) floatの場合もdoubleに変換されて表示されます

jamboxy
質問者

お礼

丁寧なご指導ご指摘まことにありがとうございます。 皆様のご指摘を受けるたび自身の勉強不足を痛感しております。 また、アドバイス、ご指摘をよろしくお願います。

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

おっと失礼。 10回分ではなく11回分でした。

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

>下記のようにループにしたところ答えが出ません。 答えが出ないのではなく、10回分の入力を待っているのです。 for文によるループの中で、g()を実行しています。 その、g()の中で、f()を実行しています。 その、f()の中で、scanf()を実行しています。 これでおわかりですね。

jamboxy
質問者

お礼

的確なご指摘ありがとうございます。 補足にて説明いただいたようにやはり11回呼び出されてしまっているようです。 私としては一度入力をしたらその値を再度入力せずにループをして答えを得るプログラムを作りたかったのですが、先に質問させていただいたプログラムとなってしまいました。 重ね重ねになってしまうのですが、もしよろしければアドバイスいただけたら幸いです。よろしくお願いします。

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.1

>このプログラムでは実行しても答えが出ません。 >printf("y = \n",y) ; printf("y = %f\n",y) ; では?

jamboxy
質問者

お礼

ご指摘まことにありがとうございます。 初歩的なミスでお恥ずかしい限りです。 出力を変えたら計算できていました。 しかし、このプログラムを下記のようにループにしたところ答えが出ません。 原因や対処法などご教授いただければ幸いと存じます。 重ねての質問となりますが、よろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <math.h> double a=1; double b=2; double c; double f(){ double y; scanf("%lf",&y) ; return y; } double g(){ double y; y=f()*a; return y; } void main(){ int i; double y; for(i=0;i<=10;i++){ c=c+1; y=g()*b*c; } printf("y = %lf\n",y) ; }

関連するQ&A

専門家に質問してみよう