Linux講座にようこそ。このページは「C言語プログラミング入門 - 第8章.データをアドレスで操作するためのポインタ」です。

C言語プログラミング入門

8. データをアドレスで操作するためのポインタ(1/3)

8.1 ポインタとは

ポインタとは
【図8-1】ポインタとは

C言語でのポインタとは、データが格納されている場所の位置情報です。通常、データは変数や配列に格納されていて、それらはメモリに有りますので、メモリ上のアドレス(番地)ということになります。

ポインタを扱う場合、ポインタの値を記憶しておくための変数が必要になります。この変数を当講座では「ポインタ変数」と呼ぶことにします。ポインタ変数には変数や配列の先頭アドレスを格納します。このことにより、ポインタ変数が変数や配列を指し示すことが出来るようになり、ポインタ変数を使って変数や配列の操作を行うことができます。

図8-1の例ではポインタ変数pとint型変数aが有り、変数pには変数aの先頭アドレスを設定(代入)します。この操作により、変数pの値は変数aの先頭アドレスになります。(変数aの値は100のままです)以降、ポインタ変数pを使って、int型変数aの値を操作することが出来るようになります。(もちろん、変数aの名前で値を操作することも出来ます)

ポインタを使うメリットとしてはプログラム実行の高速化が有ると思います。ポインタ変数を使ってデータを操作するということはアドレスを指定してデータを操作することになりますので、余計な命令を実行することなく直接的にデータの操作を行うことになります。一方、デメリットとしてはプログラムが複雑になりがちですので、不良が入り込む確率が高くなりますし、理解しにくいプログラムになる可能性があります。

8.2 ポインタ変数の宣言

ポインタ変数も変数の一種ですので、使用するには宣言が必要ですし、宣言をするには型名が必要になります。C言語ではポインタ用の型名が用意されているわけではなく、ポインタ変数が値として持つアドレスにある変数や配列の型名を型名とします。図8-1の例では変数aはint型ですので、ポインタ変数pの型名はint型になります。

8.2.1 形式

ポインタ変数の宣言をするときには変数名の前に*(アステリスク)を付けます。他の変数の宣言と大きく異なりますので注意してください。

ポインタ変数の設定は変数のアドレスを求めるためのアドレス演算子(&)を変数名の前に付けて先頭アドレスを取得して、それを代入します。ただし、配列の場合は内部的に配列名自体がポインタとして定義されているため、アドレス演算子を付けません。

※ 宣言
型名 *ポインタ変数名;

※ ポインタ値の設定(代入)
ポインタ変数名 = &変数名;
ポインタ変数名 = 配列名;
型名
ポインタ変数が指し示す先の変数や配列の型名を指定します。
*ポインタ変数名
ポインタ変数であることを示すために、変数名の前に*を付けますので注意してください。命名規則は変数や配列と同じです。
&変数名
変数名の前にアドレス演算子を付けることにより、変数の先頭アドレスを値として取得することができますので、これをポインタ変数に代入します。
配列名
配列名は内部的にはポインタとして定義されているため、配列名を指定すれば配列の先頭アドレスをポインタ変数に代入できます。

scanf関数で変数に入力する場合、変数名の前に&を指定しますが、これはアドレス演算子を指定して、変数の先頭アドレスを指定したことになります。また、配列に入力する場合は、配列名の前に&を指定しませんが、配列名を指定すれば配列の先頭アドレスを指定したことになるためです。

8.2.2 例題

この例題は宣言と代入しか行っていませんので、実行しても何も表示しません。

  1. int main()
  2. {
  3.     short   number = 1;
  4.     int     age;
  5.     float   weight;
  6.     double  bmi;
  7.     char    blood_type = 'A';
  8.     char    message[] = "Hello.";
  9.  
  10.     /* ポインタ変数の宣言 */
  11.     short    *p_number;← ポインタ変数の宣言ですので、変数名の前に*を付けます
  12.     int      *p_age;
  13.     float    *p_weight;
  14.     double   *p_bmi;
  15.     char     *p_blood_type;
  16.     char     *p_message;
  17.  
  18.     /* ポインタ変数への設定(代入) */
  19.     p_number = &number;← ポインタ変数への代入ですので、ポインタ変数名の前に*を付けません
  20.     p_age = &age;
  21.     p_weight = &weight;
  22.     p_bmi = &bmi;
  23.     p_blood_type = &blood_type;
  24.     p_message = message;← messageは配列ですので&は不要です
  25.  
  26.     return 0;
  27. }
11〜16行目
ポインタ変数の宣言を行います。
19〜23行目
ポインタ変数にアドレス演算子を使って取得した変数の先頭アドレスを代入します。
24行目
ポインタ変数p_messageに文字列配列messageの先頭アドレスを代入します。配列の場合はアドレス演算子は不要です。