ポインターを宣言するためのお気に入りの方法は何ですか?
int* i;
または
int *i;
または
int * i;
または
int*i;
理由を説明してください。
あなたが書く場合:
int* i, j, k;
誤解を招くように、i、j、kのすべてがint
へのポインターであると提案します。
したがって、*を変数名に付加する方が優れていると私は思います。
int* i
は、i
の型が「intへのポインター」であるため、これにより、型システムとの統一が可能になると感じています。もちろん、1行に複数のポインターを定義しようとすると(つまり、ポインターを宣言するには、各変数名の前にアスタリスクを付ける必要があります)、よく知られた動作が発生しますが、この方法ではポインターを宣言しません。また、Cスタイル言語の重大な欠陥だと思います。
Cの場合、型に重点を置いていないので、次のようにします。
int *i;
ポインタではなくint
に重点を置いているためです。 int
とは何ですか? *i
はintです。
私は何年もint* i
を好みました。ただし、int *i
には強力な引数があります。これは、前のスタイルを使用する場合でも、複数宣言の規則を覚えておく必要があるためです。
int* a, *b; // not int* a, b;
このルールを覚えておかなければならないので、単純に得られるわけではありませんが、それがもっと複雑であるとは言えません。 1つの行で複数の宣言を回避することは、このルールを覚えていることを示すもう1つの方法です。 2つのスタイルの違いは意味がありません。
ただし、私がそれを使用している場合でも、構文的にバインドされている変数ではなく型の横にアスタリスクを配置することにより、C宣言構文が実際の動作とは異なるふりをするのは少しばかげた感じです。
強調 ポインタ型(i
の場合)を購入しませんが、int型(*i
の場合)を強調しますが、それは後である可能性があります15年間のCおよびC++の使用、それを見ると、isと考える必要はありません。———これを尋ねるほとんどの初心者が何か質問はまだできません。
また、私の好みを考えても、他のスタイルでコードを読み書きするのは面倒ではありません。一貫性、何とか何とか。
int * i
について言及する必要さえありません。
私は最初のものを好みます。ポインタであることは型の一部であるため、当然のことです。
私はC#を使用しているため、Cよりも直感的な方法で型を処理するため、同じステートメントで複数のポインターを宣言しても問題はありません。
int* a, b, c; // three pointers
int* i
(C++スタイル)。
結果として生じる視覚的な曖昧さのために、1つのステートメントで複数の変数を宣言することは避けます(int* i, j
)。
根拠については Bjarne StroustrupのC++スタイルとテクニックに関するFAQ も参照してください。
複数の変数を宣言したいがアスタリスクを繰り返したくない場合:
template <typename T>
struct pointer_to
{
typedef T* type;
};
pointer_to<int>::type p1, p2, p3;
(構造体テンプレートの内部を見るとわかるように、私はint* i
スタイル。)
そして、これはより一般的な解決策です:
template <typename T>
struct identity
{
typedef T type;
};
identity<int*>::type p1, p2, p3;
これは、配列や参照など、任意の「問題のある型」で機能します。
identity<int[10]>::type a1, a2, a3;
identity<int&>::type r1(*p1), r2(*p2), r3(*p3);
最初の部分は変数の型(intへのポインター)を示し、2番目の部分は名前(i
)を示すため、int* i;
を使用します。タイプがint
で名前が*i
であることは私には意味がありません。また、int * i;
は乗算のように見えます。
私がint * i;
を使用している宣言では、i is a pointer to an integer
と読みます。
ポインタは型と変数の両方に影響するため、中央に配置する必要があります。
同じ行で複数のものを宣言しないようにすることをお勧めします:int * i, j;
私は実際、特定の状況で3つの規則すべてを使用します。一見矛盾しているようですが...
int *
識別子が存在しない場合、名前が存在しないことを視覚的に補強します。int* intptr
on typedef
sおよび同様の宣言により、型の一部であることを視覚的に補強します。同様に、関数ポインタ宣言の場合:(int* (*foo)(int))
int *identifier
およびclass &identifier
関数のパラメーターをオンにして、パラメーターがいわゆる「出力」パラメーターである可能性があることを視覚的に補強します。const int * const * const
c-v修飾子を使用するときはいつでも。int * foo;
ローカル宣言。私は少し視覚指向だと思います。
Cにはポインタ型はありません。したがって、「int *」は何も意味しません。アスタリスクは常にその右側に書かれた要素にバインドされ、それはそれの右側の要素に属します。 「* i」はintです。また、* iはintであるため、iはintへのポインターになります。それが背後にある論理であり、それが「int * i」が唯一の可能な解決策である理由です。その他はすべて錯覚です(ほとんどの場合、コンパイラによって自動的に修正されます)。 C++とC#では、これは少し異なります。しかし、Cの場合、聖書は「デニスM.リッチー:Cプログラミング言語」だけです。デニス(R.I.P.!)が「int * i」と書いた。これを疑う必要はありません。