web-dev-qa-db-ja.com

void()が値を返さない場合、なぜそれを使用するのですか?

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;
    }
    
33
Matteo Italia

この質問は言語の歴史に関係しています。C++はCから借りたものであり、Cは型なしのすべてをintとして暗黙的にタイプするのに使用されていました(結局のところ、それは恐ろしい考えでした)。これには、プロシージャとして意図された関数が含まれていました(関数とプロシージャの違いは、関数呼び出しは式であり、プロシージャ呼び出しはステートメントであることを思い出してください)。初期のCの本を読んでそれを正しく思い出すと、プログラマーはこの欠点に#defineでパッチを当てていました:

#define void int

この規則は、後にC標準で採用され、voidキーワードが導入され、プロシージャとして意図されている関数を示します。これは非常に役に立ちました。コンパイラーは、コードが何も返さないように意図されていない関数からの戻り値を使用しているかどうかを確認し、返すべき関数について警告し、代わりにコントロールを最後まで実行させることができるからです。

7
dasblinkenlight

void()は何も返さないことを意味します。

voidnothingを意味しません。 voidtypeからrepresentはありません。それは微妙な違いです:representationは、それが何も表さない場合でも必要です。

このtypeは、何も返さない関数のreturn typeとして使用されます。これは、void*として使用される場合、一般的なデータを表すためにも使用されます。 voidnothingを表しているのに対し、void*everythingを表しているのはおもしろそうです。

7
Nawaz

C、C++、Javaなどの命令型プログラミング言語では、void型の関数とメソッドが副作用として使用されます。これらは返す意味のある値を生成しませんが、多くの可能な方法の1つでプログラムの状態に影響を与えます。たとえば、Cのexit関数は値を返しませんが、アプリケーションを中止するという副作用があります。別の例として、C++クラスには、インスタンス変数の値を変更するvoidメソッドがある場合があります。

5
waldrumpus

時々あなたは戻り値を必要としないからです。それが私たちがそれを使用する理由です。

3
Rango

原因は、グローバル変数に対して何らかの計算を行って結果をグローバル変数に入れなければならない状況や、引数などに応じて何かを出力したい状況を考えます。これらの状況では、値を返さないメソッドを使用できます。ボイド

1
Vins

次に関数の例を示します。

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番目の関数はより高速です。構造体全体をコピーする必要はありません。

1
Mateusz N

voidがない場合、関数が値を返さないことをコンパイラにどのように伝えますか?

関数は値を返す必要はありません。関数が値を返さないことをコンパイラーに伝えるには、voidの戻り型が使用されます。

0
Zain

おそらくコンパイラに「すべてのCPUレジスタをプッシュしてポップする必要はありません!」

時にはそれを返すのではなく、何かを印刷するために使用できます。例については http://en.wikipedia.org/wiki/Mutator_method#C_example を参照してください

0
Tech163