1

私は C プログラミング言語を学ぶのが初めてで、コンパイラにエラーがあると思っていたので、この質問は私を混乱させます。

関数がその定義/プロトタイプが発生する前に呼び出されると仮定すると、その引数に関して誤っているのは次のうちどれですか?

A. char 型はすべて int 型に変換されます。

B. short 型はすべて int 型に変換されます。

C. float 型はすべて double 型に変換されます。

D. char、short、および float 以外のすべての型は、変更されずに渡されます。

E. 各引数は、対応する仮パラメーターの型に変換されます。

4

3 に答える 3

4

C89 または C90 で関数呼び出しがある場合 (同じこと。1 つは ANSI C、もう 1 つは ISO C)、次のようになります。

  • 戻り値の型は であると想定されますint
  • char(and signed charand unsigned char) およびshort(and unsigned short) はint(または、例外的にandでunsigned intある場合は) に変換され、 andは に変換されます。unsigned shortsizeof(unsigned short) == sizeof(unsigned int)floatdouble
  • ポインターは変更されないことに注意してください。
  • 関数は varargs 関数ではないと見なされます。printf()またはなどの varargs 関数をscanf()正しく呼び出すには、スコープ内にプロトタイプが必要です。

というわけで、答えはEです。

標準 (現在のバージョン、ISO/IEC 9899:2011) は次のように述べています。

6.5.2.2 関数呼び出し

¶6 呼び出された関数を示す式がプロトタイプを含まない型を持つ場合、各引数に対して整数昇格が実行され、型を持つ引数はfloatdouble に昇格されます。これらは、デフォルト引数プロモーションと呼ばれます。引数の数がパラメーターの数と等しくない場合、動作は未定義です。関数がプロトタイプを含む型で定義されており、プロトタイプが省略記号 (, ...) または昇格後の引数の型がパラメーターの型と互換性がない場合、動作は未定義です。関数がプロトタイプを含まない型で定義されており、昇格後の引数の型が昇格後のパラメーターの型と互換性がない場合、次の場合を除き、動作は未定義です。

  • 一方の昇格型は符号付き整数型で、もう一方の昇格型は対応する符号なし整数型であり、値は両方の型で表現可能です。

  • 両方の型は、文字型またはの修飾または非修飾バージョンへのポインター voidです。

「間違っている」と未定義の動作につながることに注意してください。未定義の動作は何としても避ける必要があります。このプログラムは、コンピューター上のすべてのファイルを消去することを含め、何でも実行できますが、それは標準に従って許容されます。実際、プログラムがそれを行うことはめったにありません (さらに、「鼻の悪魔」というフレーズにつながる「悪魔が鼻から飛び出す」ことはめったにありませんが (それを検索してください)、未定義の動作に直面しても許容されます)。

可能な限り、スコープ内のプロトタイプなしで関数を呼び出さないというポリシーにする必要があります。新しいコードはすべてその基準を満たす必要があります。運悪く古いコードを維持しなければならない場合は、フローに沿って進む必要があるかもしれませんが、すべてのコードを-Wmissing-prototypes -Wstrict-prototypes -Wold-style-declaration -Wold-style-definition -Werrorin effect などのオプションでコンパイルできるようになることを目指してください。これらは、関数プロトタイプと関数定義の問題を報告する GCC オプションです。

于 2013-11-01T21:40:25.000 に答える
0

みんな、ありがとう!私は答えを見つけました。

+すべての部分整数 (char および short) は int または unsigned 型に変換されます。

+ float 型はすべて double 型に変換されます。

+他のすべてのタイプは変更されません。

そうそう、答えはEです。

道徳的なサポートをありがとう!

于 2013-11-01T22:08:58.703 に答える
0

次の場合に関数呼び出しが行われるとどうなるかを確認してください

1. コンパイラは、呼び出しの前にプロトタイプを検出しました:

各引数の値は、割り当てによるかのように、対応するパラメーターの型に暗黙的に変換されます。

2. コンパイラは、呼び出しの前にプロトタイプを検出していません。

コンパイラはデフォルトの引数昇格を実行します: (1)float引数は に変換されdoubleます。(2) 整数昇格が実行され、charshort引数が変換されますint(C99 では、整数昇格が実行されます)。
だから答えは

E. 各引数は、対応する仮パラメーターの型に変換されます。

ただし、デフォルトのプロモーションに頼るのは危険であることに注意してください。次の例を検討してください。

#include <stdio.h>

int main(void)
{
     double x = 3.0;
     printf("Square: %d\n", square(x));

     return 0;
}

int square(int n)
{
     return n*n;
}

が呼び出された時点squareで、コンパイラはまだプロトタイプを認識していないため、 square が type の引数を期待していることを知りませんint。代わりに、コンパイラは に対してデフォルトの引数昇格を実行しますがx、効果はありません。型の引数が必要ですが、代わりに値intが与えられているため、呼び出しの効果はundefinedです。 doublesquare

于 2013-11-01T21:48:15.800 に答える