次の関数はint
、2 番目の引数の型として使用します。
memchr(const void *buf, int ch, size_t count);
型に使われていますがcharacter
。関数が型int
の引数に使用するように定義されているのはなぜですか? char
これには特別な理由がありますか?
これは、C 言語の進化の非常に早い時期から存在する、非常に「古い」標準関数であるためです。
古いバージョンの C には、関数プロトタイプなどはありませんでした。関数が宣言されていないか、「不明な」パラメータ リストで宣言されています。
void *memchr(); /* non-prototype declaration */
このような関数を呼び出すと、すべての引数が自動引数昇格char
の対象となりました。つまり、そのような関数は型または型の引数値を受け取ることはありませんでしたshort
。このような引数は常に呼び出し元によって型に暗黙的に昇格されint
、関数自体は実際にint
. (これは、上記のように宣言された関数、つまりプロトタイプなしの関数に対して、最新の C でも当てはまります。)
最終的に C 言語が開発されてプロトタイプ関数宣言が導入されるようになったとき、新しい宣言を標準関数の従来の動作および既にコンパイル済みの従来のライブラリに合わせることが重要でした。
これが、従来の関数宣言の引数リストにchar
またはなどの型が表示されない理由です。short
同じ理由で、そこで使用されている type も表示されませんfloat
。
これはまた、何らかの理由で K&R スタイルで定義された既存のレガシー関数のプロトタイプ宣言を提供する必要がある場合、プロトタイプでプロモートされたパラメーターの型を指定することを覚えておく必要があることも意味します。たとえば、次のように定義された関数の場合
int some_KandR_function(a, b, c)
char a;
short b;
float c;
{
}
適切なプロトタイプ プロトタイプ宣言は実際には
int some_KandR_function(int a, int b, double c);
だがしかし
int some_KandR_function(char a, short b, float c); // <- Incorrect!
char
、signed char
、およびunsigned char
は 3 つの異なるタイプであるためです。char
特定の実装では、署名されているか署名されていないかわかりません。
まれなシステム (Keith のメモを参照) を除いて、型int
はこれら 3 つの型が持つことができるすべての値で構成されます。