C++の関数は、プログラムの部品(モジュール)として、特定の処理をひとまとめにする機能です。関数には、max() のように計算結果を「返す」ものと、単に特定の動作(アクション)を実行するだけのものがあります。
void キーワードは、関数が**「値を返さない」**ことを明示するために使用されます。
void関数とは?
void は「空(から)」を意味します。関数の定義において、戻り値の型として void を指定すると、その関数は return 文で値を返す必要がない(返してはならない)ことを示します。
// void関数の基本構文
void functionName( /* 仮引数リスト */ ) {
// 実行したい処理
// この関数は値を返さない
// return; (return文はあっても良いが、値は返せない)
}
void 関数は、計算結果を求めるためではなく、画面への表示、ファイルへの書き込み、システムの状態変更など、何らかの「動作」や「副作用」を実行することを目的に使用されます。
void関数の基本的な例
void 関数の最も単純な例は、指定された回数だけ何かを実行する関数です。
#include <iostream>
/**
* @brief 指定された回数だけ警告音を鳴らし、メッセージを表示する
* @param alertCount 鳴らす回数
*/
void issueAlert(int alertCount) {
std::cout << "--- 警告 ---\n";
while (alertCount > 0) {
std::cout << "!";
// \a は警告音(ビープ音)の拡張表記
std::cout << '\a';
alertCount--;
}
std::cout << "\n------------\n";
}
int main() {
int pendingTasks = 5;
if (pendingTasks > 3) {
// issueAlert関数を呼び出す
// この関数は値を返さないので、変数に代入することはできない
issueAlert(pendingTasks);
std::cout << "タスクが溜まりすぎています。\n";
}
return 0;
}
main 関数は issueAlert(pendingTasks) を呼び出しています。プログラムの流れは issueAlert 関数に移り、alertCount が 5 で初期化され、while ループが実行されます。処理が完了すると、流れは main 関数に戻ります。
関数の汎用性を高める設計
関数は、特定の処理に特化しすぎると再利用が難しくなります。例えば、「エラーメッセージを赤色で表示する」という関数は便利ですが、「ログメッセージを色付きで表示する」という関数の方が、より汎用性が高いと言えます。
関数は、なるべく多くの状況で再利用できるように、引数(パラメータ)を使って動作をカスタマイズできるように設計することが推奨されます。
#include <iostream>
#include <string>
/**
* @brief 汎用的なログメッセージを表示する
* @param level ログレベル (例: "INFO", "WARNING", "ERROR")
* @param message 表示するメッセージ本文
*/
void logMessage(std::string level, std::string message) {
// 本来はファイルやネットワークに書き込むが、ここでは標準出力に表示
std::cout << "[" << level << "]: " << message << std::endl;
}
// logMessage を使って、より具体的な処理を行う関数(部品)
void reportError(std::string errorMessage) {
// 別の関数 (logMessage) を呼び出して処理を委ねる
logMessage("ERROR", errorMessage);
// (ここでは省略) エラー関連の追加処理...
}
int main() {
// logMessage を直接呼び出す
logMessage("INFO", "アプリケーションを起動しました。");
// ... 処理 ...
// reportError 関数を呼び出す
reportError("設定ファイル 'config.ini' が見つかりません。");
logMessage("INFO", "アプリケーションを終了します。");
return 0;
}
この例では、logMessage という汎用的な部品を作成し、reportError という別の関数がその部品を利用しています。このように、関数を「プログラムの部品」として組み合わせることで、複雑な処理を構造的に構築できます。
実引数と仮引数の型
関数を呼び出す際、仮引数とは異なる型(例: int を期待する場所に double)の実引数を渡した場合、C++コンパイラは可能であれば暗黙の型変換を試みます。
#include <iostream>
// 画面の明るさを設定する (0-100 の整数を期待)
void setDisplayBrightness(int percentage) {
if (percentage < 0) { percentage = 0; }
if (percentage > 100) { percentage = 100; }
std::cout << "画面の明るさを " << percentage << "% に設定しました。\n";
}
int main() {
// ユーザーの希望値は浮動小数点数
double userPreference = 75.8;
// double型 (75.8) を int型の仮引数に渡す
setDisplayBrightness(userPreference);
return 0;
}
実行結果:
画面の明るさを 75% に設定しました。
double 型の 75.8 が int 型の仮引数 percentage に渡される際、小数点以下が切り捨てられ 75 としてコピーされます(値渡し)。これは便利な機能ですが、意図しない精度の低下を引き起こす可能性もあるため、注意が必要です。
引数を受け取らない関数
関数によっては、動作を実行するために外部からの情報を一切必要としない場合があります。その場合、仮引数リスト () の中を空にして宣言します。
#include <iostream>
/**
* @brief プログラムの著作権情報を表示する
* (引数は不要)
*/
void displayCopyright() {
std::cout << "-------------------------------------\n";
std::cout << "(C) 2025 My Sample Application.\n";
std::cout << "All rights reserved.\n";
std::cout << "-------------------------------------\n";
}
int main() {
// 引数なしで関数を呼び出す
displayCopyright();
// ... メインの処理 ...
return 0;
}
displayCopyright() は、呼び出されるたびに常に同じ固定の処理を実行します。
まとめ
voidは、関数が値を返さないことを示す戻り値の型です。void関数は、計算結果を得るためではなく、画面表示や状態変更などの「動作」を実行するために使用されます。- 引数(パラメータ)を適切に設計することで、関数の汎用性を高め、プログラムの部品として再利用しやすくなります。
- 関数は、引数を全く受け取らない(
()を空にする)形でも定義できます。
