• ベストアンサー

繰り返しのプログラム

自作関数stress1とstress2を使用した時の繰り返しのプログラムです。 実行はできるのですがyとzの値が変化が現れずに表示されてしまいます。自作関数を使わずにfor文の中に計算式を入れた場合はきちんと変化して値が表示されます。 自作関数を使用した場合の繰り返しはどうしたら良いのでしょうか? int main(void) { double v,w,x,y,z; printf("W0="); scanf("%lf",&w); printf("W1="); scanf("%lf",&x); for (v=w; v<=x; v+=100) { y= stress1(v); z= stress2(v); printf("σ1=%lf,σ2=%lf\n",y,z);  } return 0; }

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

  • ベストアンサー
回答No.1

C言語には、ローカル変数とグローバル変数というものがあります。最初に習ってるうちはローカル変数しかでてきません。ローカル変数というのは、関数内(および関数の引数として)で宣言された変数です。その関数内でしか使用できません。グローバル変数は関数の外で宣言された変数でどの関数でも使用できます。 ですから、自作関数を使用した場合、渡した引数はその関数の処理が終わると消えてしまいます。要するに、元の関数(main関数など)では、変化が現れないわけです。そこでポインタの登場ですね。 ポインタ変数を*pとすると、そのアドレスの値を変えることができます。メモリ上のアドレスの値を変えてしまうので、当然、もとの変数の値もかわります。以下、プログラム例を示します。 void kansu(int *, int *); int main(void) {   int num = 1, num2 = 2;   kansu(&num1,&num2) // &は住所を渡す際の記号   printf("%d %d\n",num1,num2);   return 0; } // 値を交換する関数 void kansu(int *p, int *p2) {   int a;  //交換のためには変数が3つ必要   a=*p;   *p=*p2;   *p2=a; } なお、上記ソースはint変数num,num2の値を交換するプログラムです。 また、スペースには全角を使っているので、コンパイルするとエラーになりますので、ご注意を。 ポインタのアドレスを渡すときは&記号を使い、そのアドレスの変数を変えたり見たりする時は*記号を使います。難しいといわれてますが、それだけです。なぜポインタと大騒ぎされるのか理由がさっぱりわからないです(これ本当)。では、がんばってください。

すると、全ての回答が全文表示されます。

その他の回答 (6)

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.7

★回答 ・回答者 No.2 さんの補足から、関数の戻り値の型が double 型が正しいのに質問者さんは  int 型で定義しています。→このため、回答者 No.5 さんの補足で小数点以下がカット  された『σ1=3.000000』、『σ2=2.000000』が続くのです。 ・自作関数を使用しない場合が正しく『σ1=2.057815』、『σ1=2.062388』、『σ1=2.066961』  と変化したのは double 型の小数点以下をカットしなかったからです。  つまり、自作関数の 『stress1』、『stress2』関数の戻り値が int 型なので小数点以下を  カットされて正しく出来なかったのです。→回答者 No.6 さんの回答どおりですね。 正しくは: double stress1( double v ) {  double ans1;    ans1 = v * E / (A * E + a * e);  return ans1; } double stress2( double v ) {  double ans2;    ans2 = v * e / (A * E + a * e);  return ans2; } 最後に: ・コンパイラの警告レベルを一番高く設定すれば、今回のミスは未然に防げます。  つまり、戻り値が int 型なのに double 型をリターンしようとしているので、ここで警告  メッセージが出るのです。→もし本当に int 型でリターンしたい場合はキャストします。  『return (int)ans1;』という感じです。 ・よって、オプション設定などを見直して下さい。 ・私は警告レベルを一番高く設定していますので、今回のようなミスはコンパイラさんから  ときどき教えてもらいます。→さすが構文解析をちゃんと行ってコンパイルしているだけある! ・という訳で一度オプション設定を変更してみましょう。 ・以上。おわり。

ykiyki
質問者

お礼

ありがとうございます。 おかげでちゃんとしたプログラムが出来ました。 コンパイラの警告レベルの設定の設定があるのも知りませんでした。。 これから設定してプログラムを作っていきたいと思います。

すると、全ての回答が全文表示されます。
  • taunamlz
  • ベストアンサー率20% (175/843)
回答No.6

int stress1(double v) ここがおかしいと思います。 戻り値の double ans1; がdoubleなのですから、 double stress1(double v) とすべきだと思います。 int stress2(double v) も同様です。

ykiyki
質問者

お礼

ありがとうございます。 きちんと動きました。

すると、全ての回答が全文表示されます。
noname#38837
noname#38837
回答No.5

No.4の回答者さんがおっしゃるように stress1()とstress2()のリターン値が間違っているというのが一番考えられそうですが 各自作関数の内容と、 >yとzの値が変化が現れずに表示されてしまいます >計算式を入れた場合はきちんと変化して値が表示されます の実際の表示例を示していただけるとなにか糸口がつかめるかもしれません また >for (v=w; v<=x; v+=100) { のwとxには何が入っていますか? 何を入れても不具合は同じですか?

ykiyki
質問者

補足

例えばwには45000、xに65000を入れるとσ1=2.000000 σ2=1.000000 w=65000,x=85000とするとσ1=3.000000 σ2=2.000000 が続きます。 自作関数を使用しない場合、45000と65000とすると σ1は2.057815 2.062388 2.066961と変化していき、σ2も同様に変化しています。

すると、全ての回答が全文表示されます。
  • PG_RankB
  • ベストアンサー率40% (12/30)
回答No.4

ゲームプログラマやソフトウェアエンジニアしています。 既出ですが、stress1とstress2と言う関数の中身が見れないと答えようが無いですね。 ただし、yとzが変化しないとあるので、それらは関数の戻り値格納用の様ですし、stress関数の中で何らかの計算をした結果をきちんとreturnしていないのでは無いかと思いますが。

すると、全ての回答が全文表示されます。
回答No.3

ちょっと訂正。 「ポインタ変数を*p」というのは、本当は変数名はpです。*はポイントしてくれって言う命令です。ポインタ変数の宣言は以下のとおりです。 int *p; しかし初心者にわかりやすくいうと (int *)p; って感じになります。まぁ、細かいことは気にせずにどんどんプログラムを組んでください。一種の約束事ですので、どうしようもありません。C言語の規約を作っているアメリカの協会に文句をいうしかないです。要するに、「こう書け!」という約束事ですね。 がんばってください。 **************************以下、余談************************* void kansu(int a, int b); int main(void) {   int num=1, num=2;   kansu(num1, num2);   printf("%d %d\n", num1, num2);   return 0; } void kansu(int a, int b) {   int temp;   temp=a;   a=b;   b=temp; }  // int 変数a, b, tempはローカル変数(関数内変数)ですので、kansuが終わった時点でメモリから消滅します。よって、main関数内の変数にはなんら変化があらわれません。kansu関数のa,bとmain関数のnum1,num2は別の変数であり、関連性はありません。 がんばってくだあし。

ykiyki
質問者

お礼

ポインタ変数の意味が今まで分からなかったのですがkamkamkam3さんのおかげで理解できました。 プログラムを作るときは注意してやりたいと思います。

すると、全ての回答が全文表示されます。
noname#26650
noname#26650
回答No.2

>自作関数stress1とstress2 これらの関数の中身がわかれば、何かがわかるかもしれません。 現在は、これらの関数がブラックボックス状態であるため、 何も回答できません。

ykiyki
質問者

補足

自作関数はこう作りました。 アドバイスよろしくお願いします。 #include <stdio.h> #define E 21000 #define e 12500 #define A 7850 #define a 23550 int stress1(double v) { double ans1; ans1=v*E/(A*E+a*e); return ans1; } int stress2(double v) { double ans2; ans2=v*e/(A*E+a*e); return ans2; }

すると、全ての回答が全文表示されます。

関連するQ&A