ISLe さんが書きました: ↑6年前
オフトピック
前言時の*はポインタ宣言子。変数名(直接宣言子)には含まれない。
「前言時」は「宣言時」のタイポだとして、
* は、ポインタ宣言子ではありません。
* が変数名(直接宣言子)に含まれないのは当然です。
以下、JIS X 3010:2003 (ISO/IEC 9899:1999) からの抜粋です。
コード:
6.7 宣言
構文規則
宣言:
宣言指定子列 初期化宣言子並びopt ;
宣言指定子列:
記憶域クラス指定子 宣言指定子列opt
型指定子 宣言指定子列opt
型修飾子 宣言指定子列opt
関数指定子 宣言指定子列opt
初期化宣言子並び:
初期化宣言子
初期化宣言子並び , 初期化宣言子
初期化宣言子:
宣言子
宣言子 = 初期化子
コード:
6.7.5 宣言子
構文規則
宣言子:
ポインタopt 直接宣言子
直接宣言子:
識別子
( 宣言子 )
直接宣言子 [ 型修飾子並びopt 代入式opt ]
直接宣言子 [ static 型修飾子並びopt 代入式 ]
直接宣言子 [ 型修飾子並び static 代入式 ]
直接宣言子 [ 型修飾子並びopt * ]
直接宣言子 ( 仮引数型並び )
直接宣言子 ( 識別子並びopt )
ポインタ:
* 型修飾子並びopt
* 型修飾子並びopt ポインタ
コード:
6.7.5.1 ポインタ宣言子
6.7.5.2 配列宣言子
6.7.5.3 関数宣言子(関数原型を含む)
以上から、
int i, *p, **pp; という宣言があった時、
int は、宣言指定子であり、型指定子です。
i は、宣言子であり、直接宣言子であり、識別子(変数名)です。
*p は、宣言子であり、ポインタ宣言子です。
**pp は、宣言子であり、ポインタ宣言子です。
* や ** は、ポインタ宣言子ではありません。
*p の p や、**pp の pp は、直接宣言子であり、識別子(変数名)です。
int a[3]; という宣言があった時、
a[3] は、宣言子であり、配列宣言子です。
[3] は、配列宣言子ではありません。
a[3] の a は、直接宣言子であり、識別子(変数名)です。
ISLe さんが書きました: ↑6年前
オフトピック
変数の扱いに関しては、intとcharやdoubleの違いとかと大して変わらないのだけれど、ポインタ変数の読み書きという話題が出ると、「アドレスを格納してないポインタ変数を参照しちゃいかん」と脊髄反射的に騒ぎ出すひとがしばしば現れる。
だったら、iもpもppも未初期化の一時変数だとして
pp=&p;
p=&i;
に何の問題もないことをどう説明するの。
脊髄反射的に騒ぎ出す人は、「アドレスを格納してないポインタ変数を
使って、ポインタの指している先のオブジェクトを参照しちゃいかん」と
言っているつもりなんでしょう。
int i, *p, **pp; という宣言があった時、
p = &i; や pp = &p; は何も問題ないが、
*p = i; や i = *p; という使い方をしちゃいかん、
と言っているのでしょう。
代入演算子= の左オペランドや、単項演算子& のオペランドは、
未初期化の一時変数であっても何も問題ありません。