C / C ++でポインター変数を宣言する正しい方法[終了]


91

ポインタ変数の宣言に次の表記法を使用している人がいることに気づきました。

(a) char* p;

の代わりに

(b) char *p;

(b)を使用します。表記(a)の背後にある合理的なものは何ですか?文字ポインタはそれ自体が型ではないため、表記(b)は私にとってより意味があります。代わりに、タイプは文字であり、変数は文字へのポインターである場合があります。

char* c;

これはchar *型があり、変数cがその型であるように見えます。しかし、実際にはタイプはcharであり、* c(cが指すメモリ位置)はそのタイプ(char)です。複数の変数を一度に宣言すると、この違いが明らかになります。

char* c, *d;

これは奇妙に見えます。cとdはどちらも、文字を指す同じ種類のポインタです。これで次のものはより自然に見えます。

char *c, *d;

ありがとう。


7
charポインタが型ではないというのはどういう意味ですか?ポインタは型ではないと言っていますか?
ベンジャミンリンドレー

1
あなたが特定のスタイルガイドを見ていない限り、それは好みの問題だと私は信じています(つまり、あなたの会社はあなたが従わなければならない特定のコーディング標準を持っているかもしれません)。私は選択肢bと中間のいくつかを混同する傾向があります。時々私はchar *t適切に見えないので、char * t;代わりにそうするかもしれません。しかし、私もよく見char* t;ました。
RageD 2011

1
また、「型はcharであり、* c(cが指すメモリの場所)はその型(char)である」という推論は、実際にはないのに、宣言されているcharがあることを示しているようです。それが初心者によって時々そうであるようにそれがそのように扱われるならば、それは最も確実にメモリアクセス違反につながります。
ベンジャミンリンドリー2011

1
どちらもまだ十分に説明的です。(b)* pがタイプであることcharを示し、(a)pがaであることを示しますpointer to a char
人物

1
10年以上の業界での経験から、これが初めて出てきたのは今日であり、他の業界の専門家からの記事を読んだときだけでした。明らかに、タブvスペース、defまたはdecによるコメント、またはその他の「議論する必要のある重要なことは何もない」というトピックのように、これらについて宗教的な会話をしたことがありません。 。それが私の見方であるので、私のキャリアのゲームの後半では、「char * p」を使用することが多いように思いました。はい、前にスペース、後にスペース。ほとんどの場合、ポインタの明快さをより明確にするため、バグを減らします。
キット

回答:


102

Bjarne Stroustrupは言った:

「int * p;」からの選択 そして「int * p;」正誤についてではなく、スタイルと強調についてです。C強調表現; 宣言はしばしば必要以上の悪と見なされていました。一方、C ++は型に重点を置いています。

「典型的なCプログラマ」は「int * p;」と書きます。「* pはintとは何か」を強調する構文を説明し、スタイルの正確さを主張するためにC(およびC ++)宣言の文法を指す場合があります。実際、*は文法の名前pにバインドします。

「典型的なC ++プログラマ」は「int * p;」と書きます。「pはintへのポインタ」強調タイプを説明しています。実際、pの型はint *です。私はその強調をはっきりと好み、C ++のより高度な部分をうまく使用するために重要であると考えています。

出典:http : //www.stroustrup.com/bs_faq2.html#whitespace

後者のスタイルをお勧めします。1行で複数のポインターを宣言する状況(4番目の例)では、変数にアスタリスクを付けるのが慣れているからです。


34
同じ宣言で複数のオブジェクトを宣言しないことを推奨する人もいます。:-)
Bo Persson、

5
私は構文の背後にあるロジックを強調しているので、以下を好みます:int *p、つまり、p逆参照されると、を取得しintます。次に、で区切られた複数の宣言,が意味を成します:(または逆参照されたint *p, *q, rときにを取得し、参照されたときにを取得します)。また、関数ポインターの構文は意味があります:(逆参照されて呼び出されたとき、を取得します)。そして、これは理にかなっています。pqintrintint (*f)()fintint *p, (*f)()
Druesukker 2014年

2
これは私が議論の反対側に正当性があることを理解するのに役立ちました。私は主に、高レベルのプログラマーである私はタイプを強調します。そして好むint*。私にint *p, (*f)()はあまり意味がありませんが、状況によってはそれが一部の人々にどのように影響するかをある程度理解できます。
Assimilater 2015年

1
@Druesukker、あなたの発言は上記のどれよりも理にかなっていると思います。
Muntashir Akon 2017

1
@Druesukkerしかし、ロジックは正確には機能しませんvoid*(C ++参照ではまったく機能しません)。
jamesdlin

57

個人的に*は、残りのタイプと一緒に配置することを好みます

char* p;  // p is a pointer to a char.

人々は「しかし、それからchar* p, q;誤解を招くようになる」と主張しますが、私は、「それをしないでください」と言います。


char * pの非常に良い議論。選択:)あなたが示した例のように読みにくくならない限り、それらを気にしないでください。
ジーザスラモス

1
そして、値を出力したいときは?あなたがしますcout << *p;。宣言の pに星を付けてみません*pか?私の意見では、混乱が少ないと思います。
user1170330 2013年

13
@ user1170330、これは一度に型定義の一部になり、もう一方では逆参照演算子になるためです。関係ありません。どちらかといえば、異なるものは異なるように見えるはずなので、それらが異なるように見えることは良いことです。
池上2013年

32

書き方に違いはありません。しかし、2行以上のポインタを1行で宣言したい場合は、(b)バリアントを使用した方がよいでしょう。何をしたいのかが明確だからです。以下を見てください:

int *a;
int* b;      // All is OK. `a` is pointer to int ant `b` is pointer to int
char *c, *d; // We declare two pointers to char. And we clearly see it.
char* e, f;  // We declare pointer `e` and variable `f` of char type.
             // Maybe here it is mistake, maybe not. 
// Better way of course is use typedef:
typedef char* PCHAR;
PCHAR g, h;  // Now `g` and `h` both are pointers.
// If we used define construction for PCHAR we'd get into problem too.

5
typedef「もちろん」より良い方法ではありません。一部の人々はそれを好むかもしれませんが、あなたのコードで作業している複数の人々がいる場合には問題があります。私はに慣れていない場合はPCHAR、私のような何かを書くかもしれないPCHAR *p;だろうこれは、char**私が意図するものではなく。一般的に、が必要な場合は、新しいタイプchar**を作成PCHAR*または定義する必要がありますが、その後、それは愚かになり始めます。
ブラックジャック2011

3
関数へのポインターなどの複雑なポインター型が必要な場合は、typedefを作成することをお勧めします。この場合、コードがはるかに簡単になります。一方、PCHARの使用は、日常的な実践よりも総合的な例です。しかし、それは明らかにあなたが望むものを作ります。そしてそれはちょうど愚かになってきて始まり :-) Stroustrup氏へのすべての苦情直接お問い合わせください
ジョージガアルを

PCHAR * pを作成してcharへのポインタを定義した場合、何をしているのかがわからず、def型を読み取らなかったことは明らかです。答えは彼の意見です。typedefには別の利点があります。Cでは、物事を不透明にする簡単な方法があります。公にシンボルをVOID ptrとして定義しますが、個人的には型定義は別のものです...型の定義を時々調整してから、型のいずれかについて何かを変更するときにコード全体を調整します... C ++ 11はauto'sでその多くに対処しています
UpAndAdam

大学卒業から5年後にC ++でおもちゃに戻ってみたい人にとって、これは最良の答えの1つです。
Panzercrisis 2014

10

妥協は

char * p;

K&Rの用途

char *p;

コーディング標準に従っていない限り、それはあなた次第です。その場合、他の誰もが行うことに従う必要があります。


4
char * x、yがyがchar *であることを意味しないという難しい方法を学びました。K&Rがこのスタイルに従っている理由がわかります。
Rahul Kadukar 2015

K&Rとは何ですか、なぜ単一のコードソースが何を使用することが重要なのですか?使用しますchar* p;。それは慣習やルールではなく、スタイルの問題です。私にとっては、pがtypeであることはより理にかなっているchar*ので、明らかに*はtypeと一緒でなければなりません。
FalcoGer

@FalcoGer K&Rへのリンクを追加しました。単一のコードソースが何を使用するかは関係ありません。あなたのチームがあなたのコードを理解するのをより難しくするので、彼らの標準に従わない場合、あなたのチームはあなたに苛立つかもしれません。最近、チームがclang-formatとにかく使っていることを願っています。
jnnnnn

2

個人的にプロジェクトで個別に複数のポインターを宣言する傾向があるchar *を見るのは、好みの問題です。これを実行するための実際の「正しい」方法はなく、すべてが優先されます。(a)を読むほうが簡単だと言う人もいれば、(b)が同じ行で同じ型のより多くの変数を宣言する方が簡単だと言う人もいます。

(b)の方が一般的であり、場合によっては見たことがある

char * a;

またはこのようなもの。再び好み。私が取り組んでいるプロジェクトであなたが快適であるもの、または私が使用するものは何でも使用します(私が自分で書いた場合を除いて、私は(a)を使用します)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.