111

私は最近、最終的に C/C++ を学ばなければならないと決心しました。ポインター、またはより正確にはその定義について、私が本当に理解していないことが 1 つあります。

これらの例はどうですか:

  1. int* test;
  2. int *test;
  3. int * test;
  4. int* test,test2;
  5. int *test,test2;
  6. int * test,test2;

さて、私の理解では、最初の 3 つのケースはすべて同じことを行っています。Test は int ではなく、int へのポインターです。

2 番目の例は、もう少しトリッキーです。ケース 4 では、test と test2 の両方が int へのポインターになりますが、ケース 5 では、test のみがポインターであり、test2 は「実際の」int です。ケース6はどうですか?ケース5と同じ?

4

13 に答える 13

140

4、5、6 は同じもので、testだけがポインタです。2 つのポインターが必要な場合は、次を使用する必要があります。

int *test, *test2;

または、さらに良い(すべてを明確にするために):

int* test;
int* test2;
于 2008-10-07T21:04:33.343 に答える
51

アスタリスクの周りの空白は意味がありません。3 つすべてが同じことを意味します。

int* test;
int *test;
int * test;

" int *var1, var2" は、単に人々を混乱させることを意図した邪悪な構文であり、避けるべきです。次のように展開されます。

int *var1;
int var2;
于 2008-10-07T21:05:52.827 に答える
38

多くのコーディング ガイドラインでは、1 行に 1 つの変数のみを宣言することを推奨しています。これにより、この質問をする前のような混乱を避けることができます。私が一緒に仕事をしたほとんどの C++ プログラマーは、これに固執しているようです。


少し余談ですが、私が便利だと思ったのは、宣言を逆方向に読むことです。

int* test;   // test is a pointer to an int

これは非常にうまく機能し始めます。特に、const ポインターの宣言を開始し、そのポインターが const であるかどうか、またはポインターが指しているものが const であるかどうかを判断するのが難しくなります。

int* const test; // test is a const pointer to an int

int const * test; // test is a pointer to a const int ... but many people write this as  
const int * test; // test is a pointer to an int that's const
于 2008-10-07T21:13:22.983 に答える
36

「Clockwise Spiral Rule」を使用してC/C++ 宣言を解析します。

次の 3 つの簡単な手順に従います。

  1. 未知の要素から始めて、らせん/時計回りの方向に移動します。次の要素に遭遇した場合は、それらを対応する英語のステートメントに置き換えます。

    [X]または[]: 配列 X サイズ ... または 配列未定義サイズ ...

    (type1, type2): type1 と type2 を渡す関数が返されます...

    *: へのポインタ

  2. すべてのトークンが覆われるまで、これをスパイラル/時計回りの方向に続けます。
  3. 括弧内は常に最初に解決してください。

また、宣言は可能な場合は別々のステートメントにする必要があります (これはほとんどの場合に当てはまります)。

于 2008-10-07T21:27:57.117 に答える
15

他の人が述べたように、4、5、および6は同じです。多くの場合、人々はこれらの例を使用して*、 が型ではなく変数に属するという引数を作成します。スタイルの問題ですが、次のように考えて書くべきかどうかについては、いくつかの議論があります。

int* x; // "x is a pointer to int"

またはこの方法:

int *x; // "*x is an int"

FWIW 私は最初のキャンプにいますが、他の人が 2 番目の形式を主張する理由は、(ほとんどの場合) この特定の問題を解決するためです。

int* x,y; // "x is a pointer to int, y is an int"

これは誤解を招く可能性があります。代わりに、次のいずれかを記述します

int *x,y; // it's a little clearer what is going on here

または、本当に 2 つのポインターが必要な場合は、

int *x, *y; // two pointers

個人的には、1 行に 1 つの変数を保持するようにします。そうすれば、好みのスタイルは関係ありません。

于 2011-12-31T00:46:38.210 に答える
11
#include <type_traits>

std::add_pointer<int>::type test, test2;
于 2012-09-15T16:27:35.927 に答える
5

4、5、および 6 では、test常にポインターであり、ポインターでtest2はありません。C++ では空白は (ほとんど) 重要ではありません。

于 2008-10-07T21:05:21.143 に答える
3

C の理論的根拠は、変数を使用する方法で変数を宣言することです。例えば

char *a[100];

*a[42]なりますchar。そしてa[42]charポインタ。したがってa、char ポインターの配列です。

これは、元のコンパイラ作成者が式と宣言に同じパーサーを使用したかったためです。(言語設計を選択するあまり賢明な理由ではありません)

于 2016-01-01T20:29:30.760 に答える
1

ポインターは型の修飾子です。アスタリスクがどのように型を変更するかをよりよく理解するために、右から左に読むのが最善です。'int *' は「int へのポインター」と読むことができます。複数の宣言では、各変数がポインターであることを指定する必要があります。そうしないと、標準変数として作成されます。

1、2、および 3) テストの型は (int *) です。空白は関係ありません。

4、5、および 6) テストの型は (int *) です。Test2 は int 型です。繰り返しますが、空白は重要ではありません。

于 2008-10-07T21:07:50.310 に答える
-2

経験則として、多くの人はこれらの概念を次のように理解しているようです。 C++ では、キーワードまたは識別子の左バインディングによって多くのセマンティックな意味が得られます。

たとえば、次のとおりです。

int const bla;

const は「int」ワードに適用されます。同じことがポインタのアスタリスクにも当てはまり、それらはそれらの左側のキーワードに適用されます。実際の変数名は?ええ、それは残っているものによって宣言されています。

于 2008-10-07T21:50:10.223 に答える