web-dev-qa-db-ja.com

なぜintとfloatの合計がintなのですか?

次のコードを検討してください。

float d  = 3.14f;
int   i  = 1;
auto sum = d + i;

cppreference.com によると、iは、floatに追加するときにdに変換する必要があります。しかし、実際にコードを実行すると、sumが4であることがわかります。これはなぜですか?

興味深いことに、コンパイラを明示的にC11モードにすると、sumが4.14であることがわかりました。 C11標準は、結果に影響するどのような規則を変更しますか?

C++コンパイラを使用して同じコードをコンパイルするとどうなりますか?

45
jfxu

C(およびC++)では、3.14f + 1は、floatからintへの型昇格のため、float型です。

ButC90まで、およびそのような標準はCコンパイラのデフォルトである可能性があります。これはint型に割り当てられ、int自動保存期間を持つ変数のデフォルトタイプです。 C99以降、暗黙のintが撤回されたため、コンパイルは失敗しますが、コンパイラーはまだ警告を出して許可しています。

(C++ 11以降では、autoは型を推測するようコンパイラーに指示します。sumは値3.14f + 1floatになります。C++ 98またはC++ 03としてコンパイルしても動作する場合がありますが、C++に関する警告が生成されます11個の拡張機能 これは、たとえばclangが行うことです 。このC++ 11でのautoの再定義は、CとC++の間の別の重要な相違を表しています。)

129
Bathsheba

本当に簡単です。

古いバージョンのC(C99より前)では、次のように書くことができます。

auto n = 3;

nは、値が3のint型になります。

auto n = 3.14f;

そしてnstillは値が3のintタイプです。

これは暗黙のintと呼ばれ、K&Rはそれを非常に有名にしました。

あなたはそれを見ることができます

auto sum = d + i;

float type d + iを、暗黙的なsumであるintに割り当てるだけです。

したがって、答え4。

Cの新しいバージョン(C99以降)では、暗黙的なintが削除されました。

5
P45 Imminent

一部のコンパイラでは、.c拡張は、C++ではなくCとしてコンパイルされます。

float d = 3.14f;
int i = 1;
auto sum = d + i;

次のようにコンパイルされます:

float d = 3.14f;
int i = 1;
int sum = d + i;

C言語では、autoは保存期間を指定するためのキーワードです。 auto変数を作成すると、「自動保存期間」が設定されます。これらのオブジェクトを「ローカル変数」と呼びます。 Cでは、関数内のすべての変数はデフォルトでローカルです。そのため、キーワードautoはほとんど使用されません。

autoキーワードは、C言語では役に立ちません。これは、C言語の前に、ローカル変数を宣言するためにそのキーワードが必要なB言語が存在したためです。 (BはNBに開発され、Cになりました。)

2
Amir Saniyan