![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
またまた float がらみでつまずています。
以下のようなソース(2つのファイルに分割されています)を実行すると、
f = 2.000000
と表示されました。
test1.c で、func() のプロトタイプを書いてないのが諸悪の根源だとは思うのですが(警告もでています)プロトタイプの役割は、
・引数の型の不整合がないようにする
・必要に応じて、仮引数と実引数の型変換を発生させる
だと思います。
このソースでは(たまたまですが)引数の型もあっているので、正常に実行できそうな気がするのですが、なぜ、結果がおかしくなってしまうのでしょうか。
確かに、プロトタイプがないのは好ましくはないですが。
test1.c に、int func(float f); を追加したときには、確かに f = 0.010000 と表示されます。
また、f と func() の引数を double にしたときには、プロトタイプがなくても、正常に実行されます。
----- test1.c -------------
int main()
{
float f = 0.01;
func(f);
return 0;
}
----- test2.c -------------
#include <stdio.h>
int func(float f)
{
printf("f = %f", f);
return 0;
}
----- ここまで ------------
![](http://oshiete.xgoo.jp/images/v2/common/profile/M/noimageicon_setting_04.png?e8efa67)
No.3ベストアンサー
- 回答日時:
既に回答にあるように、プロトタイプがない場合、float は、double に「格上げ」されてから、関数に渡されます。
これは、大昔のC……その頃まだ、プロトタイプという概念もなかった頃(先行宣言はあった)、引数においては、
・int より小さい整数(char も)は、int に
・float は、double に
それぞれ格上げされてから関数に渡されると、そう決めた(知る人ぞ知る『K&R』の時代にまでさかのぼる)というのが前段にあるわけです。
※なぜ、わざわざそう決めたのかは、わかりませんでした。
時代が下って、プロトタイプが存在するようになった現在、プロトタイプで決められた引数の型に対して、「代入するのと同じように」型変換(同じ型なら、もちろん、変換無し)されて受け渡されるようになりました。
※ただし、printf() のような可変引数の部分は、「省略された引数リスト」ということで、プロトタイプの場合と同じ「格上げ」が発生する。
そういうわけで、プロトタイプなしで関数を呼び出したときに、引数が float だと、格上げの影響でdouble に変換されてから関数に渡されました。
受けとるほうの関数は、float が来たと思っているので、良くないことが起こりましたとそういうわけです。
引数が double だった場合には、格上げなど無しでそのまま渡されるので、(たまたま引数があっていれば)正常に実行されたというわけです。
ありがとうございました。
「格上げ」で、いろいろ検索してしまいました。
そいうえば、printf() の場合、float は、double に変換して渡されるというのは聞いたことがありました。
同じような話だったのですね。
ありがとうございました。
No.4
- 回答日時:
ほんと~に初期のころは, 関数に引数として渡す時だけでなく, 式の中で使うときは常に
・int より小さい整数型 (char と short) は int にする
・float は double にする
という変換をしてましたよね>#3.
「float で計算させるといったん double に変換してから計算するので遅くなる」という話を聞いたものです.
ありがとうございました。
そういえば、char は int にして計算されるというのは、聞いたことがありました。
float が一度 double に変換されるのも、聞いたことあるような。
それぞれ聞いたことはあるのに、なにか、頭の中でつながってなかった気がします。
No.1
- 回答日時:
>・引数の型の不整合がないようにする
不整合をチェックして一致しなければエラーにする。
>・必要に応じて、仮引数と実引数の型変換を発生させる
こんな事はしません。
>f と func() の引数を double にしたときには、プロトタイプがなくても、正常に実行されます。
偶然でしょうね。
関数プロトタイプがなくて、偶然の結果を信じる人が多くて、プロトタイプ書かなくてもいいと
言い張る人は多いです。
ま、宗教のようなものですから相手にしないことです。
この回答への補足
>・必要に応じて、仮引数と実引数の型変換を発生させる
たとえば、
void func(int i);
というプロトタイプに対して、
func(12.3);
という呼び出しは、double -> int への型変換を発生させると思うのですが。
この場合、プロトタイプがないとコンパイルではエラーがなく(警告は出ますが)実行時には見事に失敗します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語: ポインタ 5 2022/06/01 08:33
- C言語・C++・C# C言語 共用体について コマンドライン引数で値を2つ入力したときに、argv[2]の値をUNI u1 4 2022/04/25 20:34
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- C言語・C++・C# (C言語)めちゃくちゃな値になってしまいます。 5 2022/08/13 11:55
- C言語・C++・C# Cのオブジェクトファイルの逆アセンブル 5 2023/05/13 01:51
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# 至急教えてください! プログラミングの問題です! お願いします! 出力2と全く同じ出力をするように、 2 2022/06/22 23:10
- C言語・C++・C# C言語について コマンドラインで >変数 12.00 (char型) と、小数点付きの値を共用体に渡 1 2022/04/22 16:56
- C言語・C++・C# Cのdoubleの浮動小数点表示について 3 2023/04/17 13:14
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
float型とdouble型の変数の違い...
-
C言語で台形公式を使った二重積...
-
C言語を実行すると-infが出てき...
-
c言語で、繰り返し文の中で、0....
-
doubleの変数にintとintの割り...
-
プログラムでの数字につく”f”の...
-
Cで3乗根を求める方法
-
ceilでの切り上げ処理について
-
C言語 入力した数値の平均値の...
-
至急です! マクロ定義で #defi...
-
C 開放してるのにエラー(doubl...
-
C# 割合の記述について
-
関数におけるif文とreturn文に...
-
2分法で方程式の複数の解を自...
-
C言語の型による処理速度の違い
-
二分探索で方程式の解を求める方法
-
バイナリから実数を取得したい...
-
たくさんの数の平均を求める方...
-
C言語における複素数の四則演算...
-
C言語 関数プロトタイプ宣言の...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プログラムでの数字につく”f”の...
-
doubleの変数にintとintの割り...
-
float型とdouble型の変数の違い...
-
c言語で、繰り返し文の中で、0....
-
C言語を実行すると-infが出てき...
-
C言語 関数プロトタイプ宣言の...
-
C 開放してるのにエラー(doubl...
-
C言語の型による処理速度の違い
-
至急です! マクロ定義で #defi...
-
関数におけるif文とreturn文に...
-
c言語のプログラミングについて...
-
2分法で方程式の複数の解を自...
-
-1.#IND00と出てしまうのですが...
-
doubleは常に%lfとするべきなのか
-
C言語のpow関数の不具合
-
C言語で-23乗を取り扱うには
-
C言語で台形公式を使った二重積...
-
Cで3乗根を求める方法
-
sin(x)の近似について
-
2次方程式の解を求めるプログ...
おすすめ情報