底辺大学の院生がプログラミングや機械学習を勉強するブログ

勉強していることを雑にまとめるブログ。当然、正しさの保証は一切しない。

「int *a」 vs. 「int* a」

f:id:telltales:20160630210954j:plain

どっちでもいいってことで決着はついてるけど暇だし蒸し返してみる。
ちなみに僕は「int* a」派。
教科書は「int *a」が多い気がする。僕がC++を勉強した独習C++も「int *a」だった。

独習C++ 第4版

独習C++ 第4版


とりあえず逆の、「int *a」派の意見から見てみる。

「int *a」派の主張

よく見るやつがこれ。

int* foo, bar;

こう書くと、fooはポインタ変数となるが、barは普通のint型変数になる。

本来、

型名 変数1, 変数2;

という形式になっていれば変数1と変数2の両方が同じ型になるはずである。
だから「int*」は型足り得ない。また、

int *foo, *bar;

こうすれば両方ポインタ変数になることから、アスタリスクは変数側につけるべきである、というもの。

あと、「int *a」の読み方は、「変数名の左に*演算子をつけるとint型になる変数a」だというのもあった。

「int* a」派の主張

上の例に対して、じゃあ関数のプロトタイプ宣言で型がポインタ型だったらなんて書くんだよ?という疑問がある。

int* func(int*);

この場合引数の方は変数がないから(実際は変数まで書いてもいいんだけど)、変数の左側に*をつけるというルールが適用できなくなる。

戻り値についても、関数がポインタになっていることを表しているわけではなく、戻り値がint型のポインタ変数であることを示したいのだからやっぱり型側に*をつける方が自然な気がする。

ただこれについてはソース見ると

int *func(int *);

って書いてあるのも見る。
引数の方は「int *a」って書いてあってaが省略されている、と読めなくもないけど、戻り値の方は果たしてどうなんだこれは……。


もう一つ。
「そもそも宣言する変数がポインタ型であることを示す*と、ポインタの先を指す間接参照演算子としての*は別物だ」という主張。

これが結構納得行く説明だと思ってる。
だって宣言の「int *a」の*はaの先を示しているわけではないから。

実際、

int *a = 1;

というコードは書けない。(実体が無いから当たり前だけど)

結局どっち?

f:id:telltales:20160630221422j:plain

書き方が一貫してさえいればそれでいいという結論。あとコーディング規約が決まっているならそれに従いましょう。
あとそもそも生のポインタなんて使ってないで、出来るだけスマートポインタを使うべきか。

うーん、書いてて思い出したけどスマートポインタの使い方についてイマイチちゃんと勉強してないから、今度はそれを勉強しようかな。


ちなみにCに慣れている人は「int *a」、C++に慣れている人は「int* a」で書くことが多いらしい。

www.naturalsoftware.jp


一応比較のためにソースコード検索しようと思ったんだけど、searchcodeもGitHubのコード検索も*とかの記号に対応されてないらしく検索出来んかった……。

GitHubの方は記号は使えんぞってはっきり書いてあった(Searching code - User Documentation)けど、探せばアスタリスク付けて検索できるサービスあるのかな。