void f()
は、f
が何も返さないことを意味します。 void
が何も返さない場合、なぜそれを使用するのですか? void
の主な目的は何ですか?
Cが発明されたときの規則は、戻り値の型を指定しなかった場合、コンパイラーはint
を返す必要があると自動的に推論しました(パラメーターについても同様です)。
しかし、多くの場合、何かを実行して何も返す必要がない関数を記述します(たとえば、画面に何かを出力するだけの関数について考えてください)。このため、何も返さないように指定するには、「戻り値の型」としてvoid
キーワードを使用する必要があると判断されました。
void
は他の目的にも役立つことに注意してください。特に:
関数のパラメーターのリストとして指定する場合、関数はパラメーターを取らないことを意味します。これはCでは必要でした。パラメーターなしの関数宣言は、コンパイラーがパラメーターリストを指定しないままにしておくことを意図していたためです。 C++では、これは不要です。空のパラメーターリストは、関数にパラメーターが許可されないことを意味します。
void
もポインタで重要な役割を果たします。 void *
(およびそのバリエーション)は、「指定されていないものへのポインタ」を意味します。これは、実際に使用せずにポインターを格納/渡す必要がある関数を作成する必要がある場合に役立ちます(最後にのみ、実際にポインターを使用するには、適切な型へのキャストが必要です)。
また、(void)
へのキャストは、値を意図的に未使用としてマークするためによく使用され、コンパイラの警告を抑制します。
int somefunction(int a, int b, int c)
{
(void)c; // c is reserved for future usage, kill the "unused parameter" warning
return a+b;
}
この質問は言語の歴史に関係しています。C++はCから借りたものであり、Cは型なしのすべてをint
として暗黙的にタイプするのに使用されていました(結局のところ、それは恐ろしい考えでした)。これには、プロシージャとして意図された関数が含まれていました(関数とプロシージャの違いは、関数呼び出しは式であり、プロシージャ呼び出しはステートメントであることを思い出してください)。初期のCの本を読んでそれを正しく思い出すと、プログラマーはこの欠点に#define
でパッチを当てていました:
#define void int
この規則は、後にC標準で採用され、void
キーワードが導入され、プロシージャとして意図されている関数を示します。これは非常に役に立ちました。コンパイラーは、コードが何も返さないように意図されていない関数からの戻り値を使用しているかどうかを確認し、返すべき関数について警告し、代わりにコントロールを最後まで実行させることができるからです。
void()は何も返さないことを意味します。
void
はnothingを意味しません。 void
はtypeからrepresentはありません。それは微妙な違いです:representationは、それが何も表さない場合でも必要です。
このtypeは、何も返さない関数のreturn typeとして使用されます。これは、void*
として使用される場合、一般的なデータを表すためにも使用されます。 void
がnothingを表しているのに対し、void*
はeverythingを表しているのはおもしろそうです。
C、C++、Javaなどの命令型プログラミング言語では、void
型の関数とメソッドが副作用として使用されます。これらは返す意味のある値を生成しませんが、多くの可能な方法の1つでプログラムの状態に影響を与えます。たとえば、Cのexit
関数は値を返しませんが、アプリケーションを中止するという副作用があります。別の例として、C++クラスには、インスタンス変数の値を変更するvoidメソッドがある場合があります。
時々あなたは戻り値を必要としないからです。それが私たちがそれを使用する理由です。
原因は、グローバル変数に対して何らかの計算を行って結果をグローバル変数に入れなければならない状況や、引数などに応じて何かを出力したい状況を考えます。これらの状況では、値を返さないメソッドを使用できます。ボイド
次に関数の例を示します。
struct SVeryBigStruct
{
// a lot of data here
};
SVeryBigStruct foo()
{
SVeryBigStruct bar;
// calculate something here
return bar;
}
そして今ここに別の関数があります:
void foo2(SVeryBigStruct& bar) // or SVeryBigStruct* pBar
{
bar.member1 = ...
bar.member2 = ...
}
2番目の関数はより高速です。構造体全体をコピーする必要はありません。
void
がない場合、関数が値を返さないことをコンパイラにどのように伝えますか?
関数は値を返す必要はありません。関数が値を返さないことをコンパイラーに伝えるには、voidの戻り型が使用されます。
おそらくコンパイラに「すべてのCPUレジスタをプッシュしてポップする必要はありません!」
時にはそれを返すのではなく、何かを印刷するために使用できます。例については http://en.wikipedia.org/wiki/Mutator_method#C_example を参照してください