- ベストアンサー
C言語の引数について
- C言語の引数について質問があります。calc_proc関数を実装した後に引数で値をmainに戻す方法が分からないため教えて欲しいです。
- C言語の引数についての質問です。calc_proc関数を実装したが、引数で値をmainに戻す方法が分かりません。どなたか教えていただけますか?
- C言語の引数についての質問です。calc_proc関数を実装した後に引数で値をmainに戻す方法が分かりません。教えていただけますか?
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
「引数で値をmainに戻す」というのは、 関数への引数にアドレス渡し(ポインタともいうけど)を使って、 関数のなかでそのアドレスが示す領域を書き換ることで、 値をmain()に戻すということになります。 (値渡しの変数だと 関数内では値がコピーされた独立した変数になるので この値渡しの変数に代入しても関数の終了とともに捨てられるけど、 アドレス渡しだと関数内で代入した値を関数の呼び出し側に 戻すことができます。 scanf( ) の引数のうち、int型やfloat型の変数に&をつけて、 アドレス渡しにしているのもこのためですね) あと、現在のように、int n1変数に戻すようにしたのでは、 n1は、int型なので いくらfloat型にキャストしても 結局 int型への代入時に、割り算の小数点以下が切り捨てられるので、 演算結果には、float型の変数にしたほうがよいでしょう。 (もちろん計算結果が整数になってよいものなら、int型に代入してもいいけど) ということは、関数としては int calc_proc(int n1, char op, int n2, float *answer) { ~ *answer = 代入式; ~ } のようにポインタ変数の示す領域を書き換えるという形ですね。 別途、戻り値も使うということなので 演算子が正常で、分母ゼロの割り算もしてないときは return 0; 異常な時はエラー時はreturn 1; の戻り値にして、main( )側では if ( calc_proc(num1,op,num2, &answer ) != 0 ) { エラー時の中断処理; } printf ( ) やfprintf( )で answerを使って出力 のように自作の関数を使うって感じでしょうね。
その他の回答 (2)
- m-take0220
- ベストアンサー率60% (477/782)
calc_procが値を返しているのは、 > return 0; の部分だけなので、どんな値を引数にしても0が返ってくるはずです。なので、このコードは課題を満たしていない思います。それを気づかせるために言われたのではないでしょうか。 そもそも、この関数の最初の引数は、値を使用しているだけなのでポインタにする必要がありません。ポインタを使えと言われたから使った、という理由であれば、私が判定するなら不正解です。 あと、calc_proc内でエラー判定してるのに、main側ではエラーかどうか分からないので、mainに戻った後の処理はエラーが発生したなかった場合と同じ処理になってますよね。この辺も改善する必要があると思います。そう考えると、ポインタを使用する必要性が見えてくるかもしれません。
- AsarKingChang
- ベストアンサー率46% (3467/7474)
「引数で値をmainに戻すパターンを実装する」 ↑問題文?なのか、その学校がおかしいのか? C言語では、引数で値を戻す戻さないは制御できないですよ。 プロトタイプは事前に決まっていて void func は引数に何を与えようが常にvoid=返り値はない int func は引数に何を与えようが常にint=どうであれ、必ずintを返さなければならない なので、そのまま解釈すると 「引数で値を返す」だと int func( int a ) { return (a); } 見ての通りそのままの解釈では「何の意味もない事をやれ」と 言ってるのと同じです。食いついて、何を聞きたいの?ってのを 聞き直した方がいい結果になるかもです。 後おまけ、 float calc_proc(int* n1, char op, int n2) { この中、全部おかしいです。 (float)*n1 + n2; ←計算はしているが答えを求めていない(どこにも格納していない) (float)(float)*n1 / n2; ←2度もキャストしているか答えを求めていないので、特に意味がない。 default: printf("input error"); ここにbreakがない(確かに、最後に書いているので、書かなくても結果は変わらない) ただ、間違ってその下に別のcaseを書いたとき、結合してしまうので、習慣的には 書いておいた方がいいかも それと、その後の関数と質問の、 「戻り値、値渡し、ポインタ渡しを用いたサブ関数を実装する」 との関連性が、前回同様にないので、要件定義がはっきりしてないと、 なんか間違った方向に言ってるようなそんな気分です。 なので、まずは、要件定義そのものを修正してみてはいかがでしょうか? プログラムで一番大事なのは、相手が何を求めてるかを読み解く方が コード書く事より、ずっと大事な事で、そこが伝わらないと、 追加もなにもないのですよね。 実際、「そんなもん」ですよ。
お礼
ありがとうございました。