ポインター宣言
ポインター宣言はポインター変数に名前を付け、変数が指すオブジェクトの型を指定します。 ポインターとして宣言された変数は、メモリ アドレスを保持します。
構文
declarator
:
pointer
opt direct-declarator
direct-declarator
:
identifier
(
declarator
)
direct-declarator
[
constant-expression
opt ]
direct-declarator
(
parameter-type-list
)
direct-declarator
(
identifier-list
opt )
pointer
:
*
type-qualifier-list
opt
*
opttype-qualifier-list
pointer
type-qualifier-list
:
type-qualifier
type-qualifier-list
type-qualifier
type-specifier
は、オブジェクトの型を指定します。指定できる型は、任意の基本型、構造体型、または共用体型です。 ポインター変数は、関数、配列、および他のポインターを指すこともできます (より複雑なポインター型の宣言および解釈については、「さらに複雑な宣言子の解釈」を参照)。
type-specifier
を void
にすると、ポインターが参照する型を後で指定できます。 このような項目は、" void
へのポインター" と呼ばれ、void *
と記述します。 void
へのポインターとして宣言された変数は、任意の型のオブジェクトを指すために使用できます。 ただし、ポインターに対する操作やポインターが指すオブジェクトに対する操作のほとんどは、それが指す型を操作ごとに明示的に指定して実行する必要があります (char *
型と void *
型の変数は代入互換性があり、型キャストは不要です)。このような変換は型キャストによって実現できます。 詳しくは、「型キャスト変換」を参照してください。
type-qualifier
には、 const
か volatile
のいずれか、または両方を指定できます。 これらのキーワードは、ポインターがプログラム自体によっては変更できないこと (const
)、またはポインターがプログラムの制御範囲以外のプロセスによって正当に変更できること (volatile
) をそれぞれ指定します。 const
および volatile
の詳細については、「型修飾子」を参照してください。
declarator
は変数に名前を付けます。これには、型修飾子を含めることができます。 たとえば、declarator
が配列を表す場合、ポインターの型は配列へのポインターに変更されます。
構造体型、共用体型、または列挙型へのポインターは、構造体型、共用体型、または列挙型を定義する前に宣言できます。 ポインターの宣言には、例に示すように、構造体タグまたは共用体タグを使用します。 このような宣言ができるのは、コンパイラがポインター変数用の領域を割り当てるのに、構造体や共用体のサイズを知る必要がないためです。
使用例
ポインター宣言の例を次に示します。
char *message; /* Declares a pointer variable named message */
message
ポインターは、char
型の変数を指しています。
int *pointers[10]; /* Declares an array of pointers */
pointers
配列には 10 個の要素があり、各要素は int
型の変数へのポインターです。
int (*pointer)[10]; /* Declares a pointer to an array of 10 elements */
このpointer
変数は、10 個の要素を持つ配列を指します。 この配列の各要素は int
型です。
int const *x; /* Declares a pointer variable, x,
to a constant value */
ポインター x
が別の int
値を指すように変更することはできますが、指す値自体を変更することはできません。
const int some_object = 5 ;
int other_object = 37;
int *const y = &fixed_object;
int volatile *const z = &some_object;
int *const volatile w = &some_object;
これらの宣言の中で、変数 y
は、int
値への定数ポインターとして宣言されています。 それが指す値を変更することはできますが、ポインター自体は常に同じ場所、つまり fixed_object
のアドレスを指す必要があります。 同様に、z
は定数ポインターですが、プログラムによって値を変更できない int
を指すことが併せて宣言されています。 volatile
指定子により、z
が指す const int
の値はプログラムによって変更できませんが、プログラムと同時に実行されているプロセスによって正当に変更できることが指定されます。 w
の宣言は、指す値がプログラムによって変更できず、ポインターもプログラムによって変更できないことを指定しています。
struct list *next, *previous; /* Uses the tag for list */
この例では、構造体型 list
を指す 2 つのポインター変数 (next
と previous
) が宣言されています。 この宣言は list
構造体型の定義の前に配置できます (次の例を参照)。ただしその場合、list
型定義は宣言と同じ可視性を持っている必要があります。
struct list
{
char *token;
int count;
struct list *next;
} line;
変数 line
は、list
という名前の構造体型を持ちます。 この list
構造体型には、char
値へのポインター、int
値、別の list
構造体へのポインター、という 3 つのメンバーが含まれています。
struct id
{
unsigned int id_no;
struct name *pname;
} record;
変数 record
は id
という構造体型を持ちます。 pname
は、name
という名前の別の構造体型へのポインターとして宣言されています。 この宣言は、name
型を定義する前に指定できます。