• ベストアンサー

小数点表示とvoidについて

こんにちは。 C言語初級者になります。 参考書を片手に勉強しているのですが いくつか不明な点があり、投稿させて頂きました。 参考書記載の、下記サンプルソースなのですが実行すると 「waru」が正しく表示されません。 どうやら計算結果が小数点の場合、「0」となるようです。 質問(1) 「waru」の結果を小数点表示で出力したい場合、どう修正すれば宜しいのでしょうか? 「int waru」宣言をdoubleやfloat宣言に修正しても駄目でした。。。 質問(2) このサンプルソースは「void keisan( int a, int b )」が 2回記述されていますが、1回目の意味が分かりません。 2回目の記述はkeisan関数で、計算させている部分だとは思うのですが。。。 また、このkeisan関数が何故void型なのか分かりません。 上級者の方から見れば簡単かとは思いますが どうぞ分かりやすい説明をお願いいたします。 ~~~~~~~~ ここから ~~~~~~~~~~ #include <stdio.h> void keisan( int a, int b ); int main( int argc, char* argv[] ) { int a, b; scanf( "%d", &a ); scanf( "%d", &b ); keisan( a, b ); return 0; } void keisan( int a, int b ) { int tasu, hiku, kakeru; int waru; tasu = a + b; hiku = a - b; kakeru = a * b; waru = a / b; printf( "tasu:%d\n", tasu ); printf( "hiku:%d\n", hiku ); printf( "kakeru:%d\n", kakeru ); printf( "waru:%d\n", waru ); return; }

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

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

端的に言えば、 double a, b; scanf( "%d", &a ); scanf( "%d", &b ); この関係が間違っています。 double は、"%d" で scanf() できません。 この場合は、うまい具合に型変換はしてくれないので、"%lf" を使いましょう。 ついでにいえば、printf() も "%d" で double は表示できません。 "%f" (こちらは、"%lf" ではなく、"%f" が正解です)を使います。 また、「プロトタイプ」で指定するのは関数における仮引数の型です。 ですから、main() 側の a, b は int のままでも問題ないのです。 それを受ける方(keisan() )の引数が double であることがわかっていれば、あとはつじつま合わせをしてくれます。

golgo20
質問者

お礼

分かり易い説明ありがとう御座います。 基本的な間違いだったみたいですね。 お陰様で勉強になりました。

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

その他の回答 (6)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

実務の観点でいえば「最初から double で定義すべきかどうか」は取り組んでいる問題から決まってしまうことも多いと思います. ここで挙がっているのは「四則演算の例」なので, どうすべきかはわかりません. あと「プロトタイプ」の話があったのでちょっとだけ触れておきますが, プロトタイプで void keisan(double a, double b) となっている (もちろん実際の関数の定義もこれにあわせてある) のであれば, この関数に引数を渡すときに自動的に double に変換されます.

golgo20
質問者

補足

ご回答ありがとうございます。 早速プロトタイプ宣言をdouble型に修正して 実際の関数の定義も合わせてコンパイルしてみましたが、駄目でした。 何が悪いのでしょうか? コンパイラはgccになります。 ~~~~~~~~ ここから ~~~~~~~~~~ #include <stdio.h> void keisan( double a, double b ); int main( int argc, char* argv[] ) { double a, b; scanf( "%d", &a ); scanf( "%d", &b ); keisan( a, b ); return 0; } void keisan( double a, double b ) { double tasu, hiku, kakeru; double waru; tasu = a + b; hiku = a - b; kakeru = a * b; waru = a / b; printf( "tasu:%d\n", tasu ); printf( "hiku:%d\n", hiku ); printf( "kakeru:%d\n", kakeru ); printf( "waru:%d\n", waru ); return; }

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

まず、Cの特性として、「それより下にあるものは見えない」というのがあります。 ですから、 main() { .... keisan(a, b); .... } void keisan(int a, int b) { .... } と書いたとき、main() で呼び出されている関数の実体は「見えない」ことになります。 見えない関数が呼び出されたとき、コンパイラは以下の仮定をします。 ・関数の返値は int である。 ・関数に渡す引数は、書かれているとおりである。 ですから、この仮定が正しい限り、プロトタイプがなくても何とか動きます(最新のCの規格ではアウトだったかもしれない。C++だとアウトです) プロトタイプは、もともと、引数の方チェックと返値の方チェックのためのものです。が、単なる型チェックだけではなく、型変換のためにも使われます。 たとえば、 void keisan(double a, double b); という関数を作ること可能です。 ただし、 main() { int a, b; ... keisan(a, b); ... } void keisan(double a, double b) { ... } というプログラムを書くと(多分、void keisan() の行でエラーに鳴ったと思いますが)コンパイルできたとしてもうまく動きません。 先頭に void keisan(double a, double b); とプロトタイプ宣言してあれば、main() の中で呼び出したとき、int → double という暗黙の型変換をやってくれます。 実引数と仮引数の間で、暗黙の型変換もできなければ、エラーになります。 上記のように「下にあるものは見えない」ので、単一のファイルの中だけであれば、 void keisan(double a, double b) { .... } int main() { int a, b; ... keisan(a, b); } のように、呼び出される方が上にあれば、ちゃんと見えるので、うまく動きます。

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

waru = (double)a/b; は「a を double に変換してから b で割り, その商を変数 waru に入れる」という意味です. 「この行だけ」という器用なことはできませんし, double に変換しているのは a だけです (演算規則から b も double に変換されますが, これは (double) というキャストの直接の結果ではありません).

golgo20
質問者

補足

早速のご回答ありがとうございます。 分かり易い説明で助かります。 「この行だけaとbがdouble型になる」 と勘違いするところでした。 double型に変換しているのはaだけなんですね。 しかし、この方法は一般的なのですか? 最初からdouble宣言する必要はないという認識で宜しかったでしょうか? 宜しくお願いします。

すると、全ての回答が全文表示されます。
  • php504
  • ベストアンサー率42% (926/2160)
回答No.3

間違い ×プロタイプ宣言 ○プロトタイプ宣言 参考URL http://wisdom.sakura.ne.jp/programming/c/c27.html

golgo20
質問者

補足

早速のご回答ありがとうございます。 またURLの送付もありがとうございます。 続いての質問で恐縮ですが、下記のようなサンプルコードの場合 なぜプロトタイプ宣言は不要なのでしょうか? 初歩的な質問ですみません。 宜しくお願いします。 ~~~~~~ ここから ~~~~~~ #include <stdio.h> int main( void ) { int kaitou; kaitou = tasizan( 3, 8 ); printf( "3 + 8 = %d\n",kaitou ); return 0; } int tasizan( int suji1, int suji2 ) { int ans; ans = suji1 + suji2; return ans; }

すると、全ての回答が全文表示されます。
  • php504
  • ベストアンサー率42% (926/2160)
回答No.2

回答1 waru はもちろん floatかdoubleにしないといけません。 それでも waru = a / b; ですと a / b の計算時点で結果は整数になるので waru にはその結果である整数が代入されてしまいます。 a / b を少数で求めるには割られる数である a もfloatかdoubleにしないといけません。 最後に表示ですが %d は整数の表示なのでfloatやdoubleでこれを使うと変な値として表示されてしまいます。 float,doubleの表示には %f を使います。 double waru; waru = (double)a / b; printf( "waru:%f\n", waru ); 回答2 最初の記述は関数のプロタイプ宣言と呼ばれるものです。 void型というのは戻り値のない関数ということです。 returnのない、returnで値を返さない関数はvoid型にしないといけません。

golgo20
質問者

補足

早速のご回答ありがとうございます。 waru = (double)a/b; この記述なのですが「この行だけaとbはdouble型になる」 という認識で宜しかったでしょうか? また、この「(double)a/b」の使い方は一般的なのでしょうか? 本来ならば、やはりaもbも、文頭でdouble型宣言をするべきなのでしょうか? 宜しくお願いします。

すると、全ての回答が全文表示されます。
  • shimix
  • ベストアンサー率54% (865/1590)
回答No.1

>「waru」の結果を小数点表示で出力したい場合、どう修正すれば宜しいのでしょうか? > >「int waru」宣言をdoubleやfloat宣言に修正しても駄目でした。。。 表示の書式が %d ですから。書式文字列についてはマニュアルで確認してください(どう表示させたいのかで違ってきますしね)。

golgo20
質問者

お礼

早速のご回答ありがとうございます。 確かに%dは整数表示でしたね。 忘れてました。

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

関連するQ&A