1. ホーム
  2. c++

[解決済み] パラメータと組み合わせる各種記号(*,&など)の区別は?[重複しています]。

2022-03-02 09:32:39

質問

<ブロッククオート

重複の可能性があります。
c++ * vs & in function declaration

これはおそらく多くの人にとって信じられないほど初歩的な質問に見えると思いますが、私は純粋に、どんなにググっても、良い、徹底的な説明を見つけることができないでいます。しかし、このような場合、私の検索条件が悪いのでしょうか?

C++では、パラメータ(およびパラメータの引数)をマークするために、さまざまな記号とその組み合わせが使用されます。これらの意味は何でしょうか?

例) void func(int *var)void func(int **var) ? はどうでしょうか? int &var ?

同じ疑問は、引数だけでなく、戻り値の型にも当てはまります。この場合 int& func(int var) とは異なり int* func(int var) ? また、引数で、どのように y = func(*x) とは異なり y = func(&x) ?

正しい方向を示してくれるなら、このテーマに関する膨大な量の本を読むのは大歓迎です。また、私は一般的なプログラミングの概念には非常に精通しています。OO、ジェネリックス/テンプレートなど、C/C++で使用される表記法ではないものの、一般的なプログラミングの概念には非常に詳しいです。

EDITです。 ポインタが何なのかわからないという印象を与えてしまったようです。 どうなんでしょうねぇ......。)

だから、明確にするために。ポインターの仕組みは完璧に理解しています。 私がしていることは ではなく 例えば、「void func(int &var) 」のようなものの意味がよくわからず、不思議と答えが見つからない。 代入文の場合、'int* x = &y;' のように '&' 演算子は右側になりますが、上記の場合、 '&' 演算子は事実上左側にあります。 つまり、r値ではなく、l値に対して操作している。 これは明らかに同じ意味を持つことはできない。

これで少しは理解できたでしょうか?

どのように解決するのですか?

これを理解するためには、まずポインタと参照について理解する必要があります。ここでは、ポインタと参照がどういうものかをすでに知っていることを前提に、質問されている型宣言の構文を簡単に説明します。

C言語では、「宣言は使用に従う」と言われています。つまり、変数を宣言する構文は、その変数を使用する構文に似ているということです。 int または float の後に式のようなものが続きます。例えば int *y の場合、基本型は int であり、式に類似したものは *y . その後、その式は与えられた基本型を持つ値として評価される。

そこで int *y というのは、後で式 *yint . このことは、次のことを意味します。 y はint型へのポインタでなければなりません。関数のパラメータについても同様で、実際には関数宣言全体についても同様です。

int *foo(int **bar);

上記で int **bar 曰く **bar はint型であることを意味し *bar はint型へのポインタであり bar は、int型へのポインタへのポインタです。また、次のように宣言しています。 *foo(arg) はint型になります(与えられた arg が適切な型であることを意味します。 foo(arg) したがって,関数宣言全体は "foo is a function taking a pointer to a pointer to an int, and return a pointer to an int." と記述されます.

C++は参照という概念を追加し、その過程でCスタイルの宣言を少し混乱させました。なぜなら、Address-of 演算子を使って変数のアドレスを取得することは & はポインタでなければならないので、C言語では & を宣言します。 int &x という意味です。 &x がintであることを意味する。 x は、その型のアドレスを取るとintになるような型です。² つまり、この構文は使われていないので、C++は全く別の目的のためにこれを流用しているのです。

C++の場合 int &x というのは x はint型への参照です。この変数を使うことは、参照を「参照解除」する演算子を伴わないので、参照宣言記号がAddress-of演算子と衝突しても問題ないのです。同じシンボルが2つの文脈で全く異なることを意味し、他方が許される文脈で一方の意味を使う必要は決してないのです。

そこで char &foo(int &a) は、int 型への参照を取り、char 型への参照を返す関数を宣言しています。 func(&x) のアドレスを取る式です。 x に渡し、それを func .


<サブ 1. 実は、関数を宣言するためのオリジナルのC言語の構文では、「宣言は使用に従う」はさらに厳格に守られていました。例えば、ある関数を次のように宣言します。 int foo(a,b) そして、パラメータの型は別の場所で宣言され、余分な型名がない、まさにuseのような宣言になるのです。

<サブ 2. もちろん int *&x; は、その中で意味をなすかもしれません。 *&x はintである可能性がありますが、Cは実際にはそのようなことはしません。