回答:
基本的には「何もない」または「タイプなし」を意味します
voidが使用される3つの基本的な方法があります。
関数の引数:int myFunc(void)
-関数は何も取りません。
関数の戻り値:void myFunc(int)
-関数は何も返しません
ジェネリックデータポインター:void* data
-'data'は不明なタイプのデータへのポインターであり、逆参照できません
注:void
in関数の引数はC ++ではオプションであるため、int myFunc()
とまったく同じでint myFunc(void)
、C#では完全に省略されます。戻り値には常に必要です。
私はいつもそれが不在を意味すると考えてきました。この不在の使用に一致するC言語の4つのケースを次に示します。
R f(void)
-関数パラメーターがありませんvoid f(P)
-戻り値がありませんvoid *p
-指されているもののタイプはありません(void) p
-値の使用はありません他のCの子孫はそれを他のものに使用します。D
プログラミング言語は初期化子がある場合に使用します欠席
T t = void;
-初期化値がありません(void)p
ますか?「価値の使い方はない」というあなたの意味がよくわかりませんでした。
(void) var;
声明、私はで詳細な回答を見つけたstackoverflow.com/q/21045615。
voidを使用するには2つの方法があります。
void foo(void);
または
void *bar(void*);
1つ目は、引数が渡されていないか、引数が返されていないことを示しています。
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 */;
}
voidを「空の構造」と考えてください。説明させてください。
すべての関数は一連のパラメーターを受け取り、各パラメーターにはタイプがあります。実際、パラメータに対応する構造スロットを使用して、パラメータを構造にパッケージ化できます。これにより、すべての関数が引数を1つだけ持つようになります。同様に、関数はタイプを持つ結果を生成します。これはブール値でも、浮動小数点数でも、他の型付き値の任意のセットを含む構造でもかまいません。複数の戻り値を持つ言語が必要な場合は、それらが構造体にパッケージ化されていると主張するのは簡単です。実際、関数が構造体を返すことを常に主張することができました。これで、すべての関数が1つの引数を取り、1つの値を生成します。
さて、 "no"値を生成する関数が必要な場合はどうなりますか?ええと、3つのスロットを持つ構造体を形成したときに何が得られるかを考えてみましょう。2つのスロットがある場合、2つの値を保持します。スロットが1つの場合、値は1つです。そして、それがスロットを持たないとき、それは保持します...ええと、ゼロの値、または「no」の値です。したがって、voidを返す関数は、値を含まない構造体を返すものと考えることができます。言語のキーワードではなく、空の構造体で表される型の同義語です(おそらく事前定義された型だけかもしれません)。
同様に、値を必要としない関数は、「void」などの空の構造を受け入れるものと考えることができます。
この方法でプログラミング言語を実装することもできます。void値を渡すことは0バイトを占めるため、void値を渡すことは、任意のサイズの他の値を渡す特別な場合にすぎません。これにより、コンパイラは「void」の結果または引数を簡単に処理できます。おそらく、関数の結果を破棄できる言語機能が必要です。Cでは、次のステートメントで非void結果関数fooを呼び出す場合:foo(...); コンパイラーは、fooが結果を生成することを認識し、単にそれを無視します。voidが値である場合、これは完全に機能し、「手続き」(これはvoid結果を伴う関数の単なる形容詞です)は、一般的な関数のほんのささいな特殊ケースです。
Void *は少しおかしいです。Cの設計者が上記の方法で無効を考えたとは思いません。彼らはちょうどキーワードを作成しました。そのキーワードは、誰かが任意の型へのポイントを必要とするときに使用できたため、Cのイディオムとしてvoid *になります。voidを空の構造体として解釈すると、実際には非常にうまく機能します。void *ポインターは、その空の構造が置かれた場所のアドレスです。
他の型Tのvoid *からT *へのキャストも、この観点で機能します。ポインターキャストは完全なチートであり、複合型TにサブタイプSの要素がストレージレイアウトのTの先頭に物理的に配置されている場合、S *をT *にキャストし、ほとんどのマシンポインターは単一の表現を持っているため、同じ物理マシンアドレスを使用すると、逆にうまくいく傾向があります。タイプSをタイプvoidに置き換えると、まったく同じ効果が得られるため、void *とのキャストが機能します。
PARLANSEプログラミング言語は、上記のアイデアをかなり密接に実装しています。私たちはその設計に失敗し、戻り型としての「void」に細心の注意を払わなかったため、プロシージャの言語キーワードがありました。そのほとんどは単純な構文の変更ですが、言語で大きな本体動作コードを取得すると、回避できないことの1つです。
C#では、メソッドが値を返さないことを示すためにvoidキーワードを使用します。
public void DoSomeWork()
{
//some work
}
voidの3つの使用例:
関数のシグネチャ。void foo(int bar)
値を返しません。int bar(void)
はパラメータを取りませんが、通常は空の引数リストで表現されます:int bar()
。ここでのvoidキーワードの使用は、英語でのその意味に対応しています。
void *
未指定のデータを指し、逆参照できない汎用トップタイプポインター。ここで、voidの意味は、他のvoidの意味とは異なります。ユニバーサルタイプとタイプなし。
などのキャスト(void) new Foo(this)
では、戻り値が意図的に破棄されていることを示します。ここで、キーワードの使用法は英語での意味にも一致します。
ケース1と2はすでに@Geraldでカバーされていますが、ケース3はまだ対処されていません。
概念を初心者に説明する場合は、類推を使用すると役立つ場合があります。これらすべてのケースでvoidを使用することは、「このページは意図的に空白にされています」という単語が含まれている本のページと同じ意味です。これは、エラーとしてフラグを立てるべきものと、意図的に空白のままにしておくべき型とをコンパイラが区別するためのものです。
これは常に、戻り型やポインタ型など、通常は型が表示されると予想されるコードに表示されます。これがC#では、voidがそれ自体が型であるため、実際のCLR型であるSystem.Voidにマップされる理由です。
一部のプログラミング言語は、いくつかの人間の文化がゼロという概念を発明したことがないように、ボイドの概念を開発しませんでした。Voidは、ゼロの概念が人間の言語を表すのと同じ、プログラミング言語の進歩を表します。
Voidはメソッドシグネチャでのみ使用されます。戻り値の型の場合、メソッドが呼び出しコードに何も返さないことを意味します。パラメータの場合、メソッドにパラメータが渡されないことを意味します
例えば
void MethodThatReturnsAndTakesVoid(void)
{
// Method body
}
C#では、パラメーターのvoidを省略して、上記のコードを次のように記述できます。
void MethodThatReturnsAndTakesVoid()
{
// Method body
}
Voidをnullと混同しないでください。Nullは、アドレスがスタックにある変数の場合、そのアドレスのヒープ上の値が空であることを意味します。
Voidは、3つの言語すべての関数からの戻り値の型に値が不要であることを意味します。
VoidはVisual BasicのSubに相当します。