数学で関数がどのように定義されているかを覚えておくと役立つかもしれません。関数 f(x) は引数 x を取り、x から計算できる値を返します。たとえば、関数 sin は実数を取り、その数値のサインである別の実数を返します。
C++ 関数はこれのモデルです。そのため、関数を定義するときは、関数が受け取る型の引数 (これは括弧内の引数リストです) と関数が返す値の型 (これは呼び出した戻り値の型です) の両方をコンパイラに伝える必要があります。上記の「関数型」; C++ では、「関数型」という用語は別のものに使用されることに注意してください)。
したがって、C++ で正弦を計算する関数を作成する場合は、次のようにします。
double sin(double x)
{
// code to calculate the sine of x
}
ただし、ここで別の問題が発生します。通常、関数を単一の式として記述する数学とは異なり、C++ では、実行するステートメントのリストを記述します。そのステートメントのリストは通常、多くの値を操作します。では、どの値が実際に x のサインとして返されるべきかをコンパイラーにどのように伝えるのでしょうか?
これに対する答えはreturn
声明です。したがって、関数は次のようになります。
double sin(double x)
{
double result = 0;
// code to modify result so finally it contains the sine of x
return result;
}
ただし、return
コンパイラに「これが返す結果です」と伝えるだけでなく、「このステートメントに到達したら、終了し、今すぐ呼び出し元に戻る」ことにも注意してください。
たとえば、特別な処理を使用して NaN と無限値を検出する次のコードを考えてみましょう (簡単にするために、関数is_bad
とgetnan
はこの目的のために書かれていると仮定します)。
double sin(double x)
{
if (is_bad(x))
return getnan(); // when this is executed, the function *immediately* returns
// if we get here, we therefore know the value x is a regular number
double result;
// calculate the sine
return result;
}
呼び出し時に実行したいが、値を返す必要のないコードを書きたい場合があります。他の一部の言語では、これに別の構文を使用していますが、C++ は、型を導入するだけでこの違いをモデル化しています。そのタイプはvoid
. その場合、return
とにかく返すものが何もないため、明示的なステートメントは必要ありません。例えば:
void say_hello()
{
std::cout << "Hello!\n";
}
ただし、return
ステートメントは早期返品にも役立つ可能性があることに注意してください。そのため、その場合にも使用できます。
void say_hello(std::string to_whom)
{
if (to_whom = "satan")
return; // I don't say hello to satan!
std::cout << "Hello " << to_whom << "!\n";
}
最後に、main
関数についてのコメント: これには の必須の戻り値もありint
ます。その戻り値を使用して、プログラムの呼び出し元に、プログラムが正常に終了したかエラーが発生したかを伝えます。だからあなたは書くことができます(で定義された定数を使用して<cstdlib>
)
int main()
{
return EXIT_SUCCESS; // I've succeeded in doing nothing!
}
また
int main()
{
return EXIT_FAILURE; // I have no idea what I was supposed to do,
// so I couldn't do it :-)
}
EXIT_SUCCESS
代わりに、成功を示すために戻ることもできることに注意してください0
(実際、通常EXIT_SUCCESS
は値が だけです0
)
main
他の値を返す関数とは異なり、return
ステートメントを省略できるという追加のルールが追加されました。return 0;
これを行うと、関数の最後に記述した場合と同じ効果が得られます。