C言語でのポインタとは、変数のアドレスを格納する変数のことです。C言語ではよく使われます。ポインタを使用すると、特定のメモリ領域へ直接、値を書き込めます。便利ですが、使い方を間違えるとメモリ破壊を引き起こすという危険性もあります。
また、ポインタを利用すればコンパクトで効率的なプログラムを記述できますが、書き方を間違えると理解しにくいプログラムになってしまうので注意が必要です。
C言語でのポインタとは、変数のアドレスを格納する変数のことです。このページではC言語でのポインタについて例を挙げて説明しています。
C言語でのポインタとは、変数のアドレスを格納する変数のことです。C言語ではよく使われます。ポインタを使用すると、特定のメモリ領域へ直接、値を書き込めます。便利ですが、使い方を間違えるとメモリ破壊を引き起こすという危険性もあります。
また、ポインタを利用すればコンパクトで効率的なプログラムを記述できますが、書き方を間違えると理解しにくいプログラムになってしまうので注意が必要です。
通常の変数への値の代入は次のように行われます。
int data; /* (1) */
data = 25; /* (2) */
この時のメモリ使用状況をイメージ化したものは、次のようになります。
同じことをポインタを使って行うと次のようになります。
int data; /* (1) */
int *buf; /* (2) */
buf = &data; /* (3) */
*buf = 25; /* (4) */
この時のメモリ使用状況をイメージ化したものは、次のようになります。
(1)が実行された時にint型の変数data用のメモリ領域が確保されます。
続いて(2)が実行されるとint型のポインタであるbuf変数用のメモリ領域が確保されます。この文は*bufがint型であることを表しています。
(3)でdata変数用のメモリ領域のアドレスがbuf変数に格納されます。単項演算子&はオブジェクトのアドレスを与えます。
そして(4)でbufポインタが指しているアドレスに対して25が書き込まれます。単項演算子*は間接演算子で、これをポインタに適用すると、そのポインタが指しているオブジェクトにアクセスできます。このようにしてdata変数に25が入ります。
ポインタの使用例としてswap関数を書いてみます。この関数はint型の2つの変数の値を入れ替えると言う関数です。
C言語では、関数に渡す引数は全て値で受渡しされます。値がコピーされて渡されるため、呼び出された関数側でパラメータの内容を変更しても、元の引数の内容を変えることはできません。
呼び出し元の引数の値を変えたい場合には、このswap関数の使用例のようにポインタを使用します。このような例はポインタ使用法の最もポピュラーなものです。
#include <stdio.h>
#include <stdlib.h>
void swap(int *x, int *y);
int main(int argc, char *argv[])
{
int a, b;
/* 引数のチェック */
if (argc != 3) {
printf("Usage: %s <number1> <number2>¥n", argv[0]);
return 0;
}
/* 引数を取得,atoi()でintに変換 */
a = atoi(argv[1]);
b = atoi(argv[2]);
/* 変数の内容を入れ替える */
swap(&a, &b);
/* 変数の内容を出力 */
printf("%d %d¥n", a, b);
return 0;
}
void swap(int *x, int *y)
{
int tmp;
tmp = *x;
*x = *y;
*y = tmp;
}
順番に説明します。
#include <stdio.h>
#include <stdlib.h>
この部分で、C言語の標準ライブラリを使用するためにヘッダをインクルードしています。
void swap(int *x, int *y);
swap関数のプロトタイプ宣言です。引数の型がint型ではなく、intのポインタであることに注目してください。
int main(int argc, char *argv[])
{
int a, b;
/* 引数のチェック */
if (argc != 3) {
printf("Usage: %s <number1> <number2>¥n", argv[0]);
return 0;
}
/* 引数を取得,atoi()でintに変換 */
a = atoi(argv[1]);
b = atoi(argv[2]);
main()の冒頭でint型の変数a,bを宣言し、その後、引数を取得、atoi()でint型に変換し、aとbに代入しています。
swap(&a, &b);
swap関数をコールします。この時引数に渡すものは変数a,b、それぞれのアドレスです。aとbの値ではないことに注意してください。swap関数本体を見てみましょう。
void swap(int *x, int *y)
{
int tmp;
tmp = *x;
*x = *y;
*y = tmp;
}
渡されたa,bのアドレスをintのポインタであるxとyで受け取ります。int型の変数tmpを宣言し、その中に*xを代入します。*xはポインタxが指し示しているところの内容(すなわち変数aの内容)です。次に*xに*yを代入。*yはポインタyが指し示しているところの内容(すなわち変数bの内容)ですので、これで変数aに変数bの値が代入されました。最後に*yにtmpを代入し、これで変数bに変数aの値が代入されたことになります。
printf("%d %d¥n", a, b);
return 0;
}
main()の最後で変数a,bの内容を出力しています。このプログラムを実行するとコマンドラインから渡した2つの引数の順番が入れ替わって表示されます。