関数宣言 は、関数の名前およびそのパラメーターの 数と型を明確にします。関数宣言は、戻りの型、名前、およびパラメーター・リストで 構成されます。さらに、関数宣言はオプションで、その関数のリンケージを指定することができます。 C++ では、宣言で、例外指定、const 修飾、または volatile 修飾を指定することもできます。
宣言は、コンパイラーが関数を使用する前に、コンパイラーに対して、関数の形式 と存在を通知します。すべての宣言が一致する場合は、1 つの関数を 1 つのプログラム内で複数回宣言することができます。 関数の暗黙宣言は許可されていません。 すべての関数は、呼び出される前に明示的に宣言しておく必要があります。 C89 では、明示的なプロトタイプなしで関数が呼び出される場合、 コンパイラーは暗黙宣言を提供します。コンパイラーは、関数呼び出し のパラメーターと関数宣言におけるパラメーターとのミスマッチを検査します。 コンパイラーは、引き数の型の検査および引き数の変換のためにも関数宣言を使用します。
関数定義 には、関数宣言と関数本体が含まれます。 1 つの関数には 1 つの定義しか認められません。
通常、宣言はヘッダー・ファイルに入れますが、関数定義はソース・ファイルに入れます。
>>-+--------+--+----------------+--function_name----------------> +-extern-+ '-type_specifier-' '-static-' .-,-------------. V | >--(----+-----------+-+--+--------+--)--+----------+------------> '-parameter-' '-,--...-' +-const----+ '-volatile-' >--+-------------------------+--;------------------------------>< '-exception_specification-'
関数引き数 は、関数呼び出しの括弧内で使用する式です。 関数仮パラメーター は、関数宣言または定義の括弧内で宣言された、 オブジェクトまたは参照です。関数を呼び出すとき、引き数が評価されます。そして各パラメーターが、 対応する引き数の値を使用して初期化されます。 引き数受け渡しのセマンティクスは、代入のセマンティクスと同じです。
宣言の中には、パラメーター・リスト内にパラメーターの名前がないものもあります。 つまり、下記の例のように、宣言は単にパラメーターおよび戻り値の型を指定するだけのものがあります。 これはプロトタイピング と呼ばれます。関数プロトタイプは、関数の 戻りの型、関数の名前、およびパラメーター・リストで構成されます。次の例は、このことを示しています。
int func(int,long);
関数プロトタイプは、C と C++ との間の互換性を保持するのに必要とされます。 空のパラメーター・リストを持つ関数の非プロトタイプ形式は、C ではその関数のパラメーター数が不明であることを意味しますが、C++ ではその関数はパラメーターを取らないことを意味します。
関数の戻りの型
関数は、配列の型および関数の型以外は 、任意の型の値を戻すように定義できます。配列および 関数呼び出しの結果を処理するには、その配列または関数へのポインターを戻す必要があります。関数は、関数を指すポインター、または配列の最初のエレメントを 指すポインターを戻すことができます。しかし、配列または関数の型を持っている値を戻すことはできません。 関数が値を戻さないように指示するには、戻りの型を void として関数を宣言します。
戻りのステートメントに式が含ま れない場合、関数の戻りの型は、void にする必要があります。ただし、 戻りのステートメントに式が含まれる場合、関数の戻りの型を void にすることはできません。 これは、コンパイラーが戻り式を関数の戻りの型に代入するかのように変換するためです。
関数の戻りの型が void である場合や、
関数がコンストラクターまたはデストラクターである場合、関数の戻りのステートメントには
式は不要です。このような場合、関数は、値を戻しません。関数が値を戻す場合、
戻りのステートメントには、式が含まれている必要があります。この式は、この式を含む
関数の戻りの型に暗黙的に変換された後、関数の呼び出し元に戻されます。
関数は、volatile 型または const 型のデータ・オブジェクトを戻すものとして 宣言することはできません。しかし、volatile または const オブジェクトへのポインターを 戻すことはできます。
C++ での関数の宣言時の制限
すべての関数宣言では、戻りの型を指定する必要があります。
メンバー関数だけが、括弧で囲まれたパラメーター・リストの後に、const または volatile 指定子を持つことができます。
exception_specification は、関数が指定されたリスト の例外だけを throw するよう制限します。
関数の宣言時のその他の制限
省略符号 (...) を C++ における唯一の引き数にすることもできます。この場合は、コンマは必要ありません。 C では、唯一の引き数として省略符号を持つことはできません。
戻りまたは引き数の型の中で、型は定義できません。 例えば、C++ コンパイラーでは、print() の以下のような 宣言ができます。
struct X { int i; }; void print(X x);
C コンパイラーでは、以下の宣言ができます。
struct X { int i; }; void print(struct X x);
C コンパイラーおよび C++ コンパイラーのどちらも、 同じ関数を次のように宣言することはできません。
void print(struct X { int i; } x); //error
この例は、クラス X のオブジェクト x を引き数として採用する関数 print() を宣言しようとしています。 しかし、引き数リスト内では、クラス定義はできません。
別の例では、C++ コンパイラーでは、counter() の以下のような宣言ができます。
enum count {one, two, three}; count counter();
同様に、C コンパイラーでは、以下の宣言ができます。
enum count {one, two, three}; enum count counter();
C および C++ のどちらのコンパイラーでも、同じ関数を次のように宣言することはできません。
enum count{one, two, three} counter(); //errorcounter() の宣言の例では、 関数宣言の戻りの型に列挙型定義を 入れることはできません。
関連参照