zeek さんが書きました:正確には
int i; // i は宣言子(宣言子識別子)です。
int a[8]; // a[8] は 宣言子(a は宣言子識別子、[8] は配列宣言子)です。
int *p; // *p は宣言子(* はポインタ宣言子、p は宣言子識別子)です。
int f(); // f() は宣言子(f は宣言子識別子、() は関数宣言子)です。
ですね。
いいえ。
[8] は配列宣言子ではありません。
* はポインタ宣言子ではありません。
() は関数宣言子ではありません。
規格書に従って説明してみますが、C および C++ の規格は、
更新されるたびに記述が複雑になっているので、
JIS X3010:2003(ISO/IEC 9899:1999) いわゆる C99 に基づき、
JIS X3014:2003(ISO/IEC 14882:2003) いわゆる C++03 で
補足していきます。
コード:
6.7 宣言
構文規則
宣言:
宣言指定子列 初期化宣言子並びopt;
宣言指定子列:
記憶域クラス指定子 宣言指定子列opt
型指定子 宣言指定子列opt
型修飾子 宣言指定子列opt
関数指定子 宣言指定子列opt
初期化宣言子並び:
初期化宣言子
初期化宣言子並び , 初期化宣言子
初期化宣言子:
宣言子
宣言子 = 初期化子
制約 宣言では,少なくとも一つの宣言子 (関数の仮引数又は構造体若しくは
共用体のメンバ以外のもの),タグ又は列挙体のメンバを宣言しなければならない。
識別子が無結合である場合,その識別子の宣言(宣言子又は型指定子の中の)が
同じ有効範囲及び同じ名前空間の中で,二つ以上あってはならない。
ただし,タグの宣言は除く(6.7.2.3 参照)。
同じオブジェクト又は同じ関数についての同じ有効範囲の中のすべての宣言は,
適合する型を指定しなければならない。
int a[8]; という宣言は、「宣言指定子列 初期化宣言子並び ;」である。
int は、宣言指定子列であり、型指定子である。
a[8] は、初期化宣言子並びであり、初期化宣言子であり、宣言子である。
コード:
6.7.2 型指定子
構文規則
型指定子:
void
char
short
int
long
(以下略)
const int a[3] = { 1, 2, 3 }, b[2] = { 4, 5 };
const は、型修飾子であり、宣言指定子であり、
int は、型指定子であり、宣言指定子であるから
const int は、宣言指定子列である。
a[3] は宣言子であり、{ 1, 2, 3 } は初期化子であるから
a[3] = { 1, 2, 3 } は、初期化宣言子である。
b[2] は宣言子であり、{ 4, 5 } は初期化子であるから
b[2] = { 4, 5 }; は、初期化宣言子である。
よって、a[3] = { 1, 2, 3 }, b[2] = { 4, 5 }; は、初期化宣言子並びである。
コード:
6.7.5 宣言子
構文規則
宣言子:
ポインタopt 直接宣言子
直接宣言子:
識別子
( 宣言子 )
直接宣言子 [ 型修飾子並びopt 代入式opt ]
直接宣言子 [ static 型修飾子並びopt 代入式 ]
直接宣言子 [ 型修飾子並び static 代入式 ]
直接宣言子 [ 型修飾子並びopt * ]
直接宣言子 ( 仮引数型並び )
直接宣言子 ( 識別子並びopt )
ポインタ:
* 型修飾子並びopt
* 型修飾子並びopt ポインタ
型修飾子並び:
型修飾子
型修飾子並び 型修飾子
仮引数型並び:
仮引数並び
仮引数並び , ...
仮引数並び:
仮引数宣言
仮引数並び , 仮引数宣言
仮引数宣言:
宣言指定子列 宣言子
宣言指定子列 抽象宣言子opt
識別子並び:
識別子
識別子並び , 識別子
意味規則 各宣言子は一つの識別子を宣言する。式の中にその宣言子と同じ形式の
オペランドが現れた場合,そのオペランドは,宣言指定子列が指示する有効範囲,
記憶域期間及び型をもつ関数又はオブジェクトを指し示す。
a[8] という宣言子は、「 直接宣言子 [ 代入式 ] 」である。
すなわち、「 直接宣言子 [ 型修飾子並びopt 代入式opt ] 」である。
a は、直接宣言子であり、識別子である。
8 は、代入式であり、条件式であり、論理OR式であり、論理AND式であり、
排他OR式であり、AND式であり、等価式であり、関係式であり、シフト式であり、
加減式であり、乗除式であり、キャスト式であり、単項式であり、後置式であり、
一次式であり、定数である。
各宣言子は一つの識別子を宣言するという意味規則から、
[8] も * も () も宣言子ではありません。
コード:
6.7.5.1 ポインタ宣言子
意味規則
宣言“T D1”において,D1 が形式
* 型修飾子並びopt D
をもつ場合,次のとおりとする。
ここには、構文規則がありませんが、それは「6.7.5 宣言子」の
コード:
宣言子:
ポインタopt 直接宣言子
ポインタ:
* 型修飾子並びopt
* 型修飾子並びopt ポインタ
に書かれています。
コード:
6.7.5.2 配列宣言子
制約 [ 及び ] の間には,省略可能な型修飾子及びキーワード static に加え,
式又は * を置くことができる。[ 及び ] が(配列の大きさを指定する)式を
囲む場合,その式の型は整数型でなければならない。式が定数式の場合,その値は
0 より大きくなければならない。要素の型が不完全型又は関数型であってはなら
ない。省略可能な型修飾子及びキーワード static は,配列型をもつ関数仮引数の
宣言中だけで使用できる。そして,一番外側の配列型派生だけで使用できる。
ここには、構文規則がありませんが、それは「6.7.5 宣言子」の
コード:
直接宣言子:
直接宣言子 [ 型修飾子並びopt 代入式opt ]
直接宣言子 [ static 型修飾子並びopt 代入式 ]
直接宣言子 [ 型修飾子並び static 代入式 ]
直接宣言子 [ 型修飾子並びopt * ]
に書かれています。
コード:
6.7.5.3 関数宣言子(関数原型を含む)
制約 関数宣言子は,関数型又は配列型を返却値の型として指定してはならない。
仮引数宣言に記憶域クラス指定子として,register 以外のものを指定しては
ならない。関数定義の一部でない関数宣言子における識別子並びは,空でなければ
ならない。関数定義の一部である関数宣言子の仮引数型並びにある仮引数は,
型調整後に不完全型をもってはならない。
ここには、構文規則がありませんが、それは「6.7.5 宣言子」の
コード:
直接宣言子:
直接宣言子 ( 仮引数型並び )
直接宣言子 ( 識別子並びopt )
に書かれています。