web-dev-qa-db-ja.com

voidはC、C ++、およびC#で何を意味しますか?

void」という用語がどこから来ているのか、そしてなぜそれがvoidと呼ばれているのかについての基礎を探してください。質問の目的は、Cの経験がなく、突然Cベースのコードベースを検討している人を支援することです。

161
Nick Katsivelos

基本的には「なし」または「タイプなし」を意味します

Voidが使用される基本的な方法は3つあります。

  1. 関数の引数:int myFunc(void) - 関数は何もしません。

  2. 関数の戻り値:void myFunc(int) - 関数は何も返しません

  3. 一般的なデータポインタ:void* data - 'data'は未知の型のデータへのポインタであり、間接参照できません

注:関数引数のvoidはC++ではオプションであるため、int myFunc()int myFunc(void)とまったく同じであり、C#では完全に除外されています。戻り値には必ず必要です。

214
Gerald

私はいつも不在を意味すると解釈しました。 C言語では、このabsentの使用に一致する4つのケースがあります。

  • R f(void) - 関数パラメータは不在です
  • void f(P) - 戻り値はなしです
  • void *p - 指されるもののタイプは不在
  • (void) p - 値の使い方はなし

他のCの子孫は他のことのためにそれを使います。 Dプログラミング言語は、初期化子が存在しない場合にそれを使用します

  • T t = void; - 初期化値はなし

Voidを使用する方法は2つあります。

void foo(void);

または

void *bar(void*);

最初の引数は、引数が渡されていないこと、または引数が返されていないことを示します。

2番目は、データに関連付けられた型が事実上ないことをコンパイラに伝えます。つまり、既知の型にキャストされるまでは、指し示されたデータを利用することはできません。

たとえば、void*は、パラメータが事前にわからない関数を呼び出すインタフェースがあるときによく使用されます。

たとえば、Linuxカーネルでは、作業を延期するときに、実行する関数へのポインタと関数に渡すデータへのポインタを指定して、後で実行する関数を設定します。

struct _deferred_work {
sruct list_head mylist;
.worker_func = bar;
.data        = somedata;
} deferred_work;

それからカーネルスレッドは延期された作業のリストを調べ、それがこのノードに到達すると、それは効果的に実行します。

bar(somedata);

バーでは:

void bar(void* mydata) {
    int *data = mydata;
    /* do something with data */;
}
13

それは「値なし」を意味します。 voidを使用して、関数が値を返さないこと、またはパラメータがないこと、またはその両方を示すことができます。 Wordの一般的な使い方とほぼ一致していますvoid英語。

13
sharptooth

関数内に戻り値がないことを示します。

いくつかの言語は2種類のサブルーチンを持っています:手続きと関数です。手続きは単なる一連の操作ですが、関数は結果を返す一連の操作です。

Cとその派生物では、両者の違いは明白ではありません。すべて基本的に関数です。 voidキーワードは、値を返さないため、「実際の」関数ではないことを示します。

4
Rik

ボイドを「空の構造」と考えてください。説明させてください。

すべての関数は一連のパラメータを取ります。各パラメータは型を持ちます。実際、パラメータに対応する構造体スロットを使用して、パラメータを構造体にまとめることができます。これにより、すべての関数が厳密に1つの引数を持つようになります。同様に、関数は型を持つ結果を生成します。それはブール値でも、浮動小数点数でも、他の型指定された値の任意のセットを含む構造体でもかまいません。複数の戻り値を持つ言語が必要な場合は、それらを構造体にパッケージ化することを主張するのは簡単です。実際、私たちは常に関数が構造体を返すと主張することができました。現在、すべての関数は厳密に1つの引数を取り、厳密に1つの値を生成します。

さて、 "no"値を生成する関数が必要なときはどうなりますか?さて、3つのスロットを持つ構造体を形成したときに得られるものを考えてみましょう。それは3つの値を保持します。私が2つのスロットを持っているとき、それは2つの値を保持します。スロットが1つの場合は1つの値。そして、スロットがゼロのときは、... uh、ゼロ値、または "no"値を保持するので、voidを返す関数は、値を含まない構造体を返すものと考えることができます。言語のキーワードではなく、空の構造体で表される型の単なる同義語です(おそらくその単なる定義済みの型:)

同様に、値を必要としない関数は、空の構造体、たとえば "void"を受け入れるものと考えることができます。

私は自分のプログラミング言語をこのように実装することさえできます。 void値を渡すことはゼロバイトを占めるので、void値を渡すことは任意のサイズの他の値を渡すことの単なる特別な場合です。これにより、コンパイラは "void"の結果または引数を扱うことが容易になります。おそらく関数の結果を捨てることができる言語機能が欲しいでしょう。 Cでは、次の文で無効ではない結果関数fooを呼び出すとします。foo(...);コンパイラはfooが結果を生成することを知っていて、単にそれを無視します。 voidが値である場合、これは完全に機能し、現在では「手続き」(結果が無効な関数の単なる形容詞)は、一般的な関数のごくわずかな特殊な場合です。

Void *は少しおかしなものです。私は、Cデザイナーが上記のように無効だとは考えていません。彼らはただキーワードを作成しました。このキーワードは、誰かが任意の型へのポイントを必要としたときに利用可能でした。したがって、Cのイディオムとしてvoid *を使用します。voidを空の構造体として解釈する場合、実際にはうまく機能します。 void *ポインタは、その空の構造体が置かれている場所のアドレスです。

他の型Tのvoid *からT *へのキャストも、この観点で解決します。ポインターキャストは、最も一般的なアーキテクチャーで、格納レイアウト内のサブタイプSの要素が物理的にTの先頭に配置されている場合、S *をT *にキャストし、S *をT *にキャストするという事実を利用する完全なチートです。ほとんどのマシンポインタは単一の表現を持っているので、同じ物理マシンアドレスを使用した逆もまた同様です。型Sを型voidで置き換えるとまったく同じ効果が得られるため、void *への/からのキャストは有効です。

PARLANSEプログラミング言語は上記の考えをかなり厳密に実行します。私たちはその設計にこだわり、戻り型としての "void"には細心の注意を払っていなかったので、手続きのためのlangaugeキーワードを持っています。その大部分は単純な構文の変更にすぎませんが、言語で大規模なボディ作業コードを入手した後は回避できないことの1つです。

3
Ira Baxter

C#では、メソッドが値を返さないことを示すためにvoidキーワードを使用します。

public void DoSomeWork()
{
//some work
}
2
Charlie

あなたが概念を初心者に説明しているならば、それはアナロジーを使うのが役に立つかもしれません。これらすべての場合にvoidを使用することは、「このページは意図的に空白のままにされていました」という単語が含まれている本の中のページと同じ意味です。それはあなたが望んでいる振る舞いだから故意に空白のままにされるべきタイプに対して、エラーとしてフラグを立てるべきである何かをコンパイラに区別することです。

通常、戻り型やポインタ型など、通常は型が表示されると予想される場所にコードで表示されます。 C#ではvoidが実際のCLR型System.Voidにマッピングされるのはそのためです。それ自体は型です。

一部のプログラミング言語は、一部の人間の文化が数ゼロの概念を発明したことがないように、無効の概念を開発したことがありません。 Voidは、ゼロという概念が人間の言語に表すのと同じプログラミング言語の進歩を表します。

2
TimF

Voidの3つの使用例

  1. 関数シグネチャvoid foo(int bar)は値を返しません。 int bar(void)はパラメータを取りませんが、これは通常空の引数リストint bar()で表されます。ここでのvoidキーワードの使用は、英語の意味と対応しています。

  2. 未指定のデータを指し、間接参照できない汎用の最上位ポインターvoid *。ここで、voidの意味は他のvoidの意味とは異なります。つまり、ユニバーサルタイプとタイプなしです。

  3. (void) new Foo(this)などのキャストでは、戻り値が意図的に破棄されていることを示します。ここではキーワードの使用法も英語の意味と一致しています。

ケース1とケース2はすでに@Geraldでカバーされていますが、ケース3はまだ対処されていません。

2
laalto

それは「値なし」を意味します。関数が値を返さないこと、またはパラメータがないこと、またはその両方があることを示すには、voidを使用します。これは、英語におけるWordの典型的なvoidの使用法とほぼ一致しています。

Voidをnullと混同しないでください。 Nullは、アドレスがスタック上にある変数の場合、そのアドレスのヒープ上の値は空です。

1
AVI

Voidは不完全型であり、定義上、左辺値にはなり得ません。つまり、値が割り当てられないということです。

だからそれはまた価値を持つことができません。

0
dhein

Voidはメソッドシグネチャでのみ使用されます。戻り値の型の場合、メソッドは呼び出し元のコードには何も返しません。つまり、パラメータの場合、パラメータはメソッドに渡されません。

例えば.

void MethodThatReturnsAndTakesVoid(void)
{
// Method body
}

C#では、パラメータのvoidを省略して上記のコードを次のように書くことができます。

void MethodThatReturnsAndTakesVoid()
{
// Method body
}

Voidをnullと混同しないでください。 Nullは、アドレスがスタック上にある変数の場合、そのアドレスのヒープ上の値は空です。

0
Rashmi Pandit