C言語入門:ポインタとは

ポインタはC言語の最重要箇所であると言っても過言では無いと思われます。 ここでは、ポインタとは何であるかを簡単に説明したいと思います。

ポインタは難しい

C言語をはじめて習う人の多くがつまづくのがポインタであると思われます。 ポインタの概念は、一度わかってしまえば非常にわかりやすいのですが、わからないと何を言っているのかが理解不能であると思われます。 何故わかりにくいのかというと、ポインタは自分で実態を持つのではなく、実態を表す先を持っているからだと思われます。 (ポインタも変数なので実態はあるにはあるんですがね。。。もう既に意味不明になったかも知れませんが。。。)

ポインタの概念を覚えると、他の言語を理解するうえでも非常に役立ちます。 例えば、JavaScriptやPerlにもポインタと似たような考え方をする部分があります。

最初はわからなくても、色々なサンプルをいじってみて試しながら体で覚えていけば、誰でもポインタは理解できます。 くじけずに頑張りましょう。

ポインタとはアドレスを記憶する変数である

ポインタとはアドレスを記憶するための変数です。

コンピュータはメモリに情報を書き込んで使います。 例えば、char型で宣言した配列も、int型の変数も、関数でさえも、プログラム動作時には全てメモリに貼り付けられています。 そのメモリのうちのどこにあるかを示すためのものがポインタです。

恐らく、ここらへんでわからなくなりつつあると思うので、サンプルソースコードで説明をしたいと思います。

サンプル1


#include <stdio.h>

int
main()
{
 char a[8];
 char *ptr;

 a[0] = 'a';
 a[1] = 'b';
 a[2] = 'c';
 a[3] = 'd';
 a[4] = 'e';
 a[5] = 'f';
 a[6] = 'g';
 a[7] = '\0';

 ptr = a;
 printf("%c\n", *ptr);

 ptr = ptr + 3;
 printf("%c\n", *ptr);

 return 0;
}

上記例を実行すると「a」と「d」という文字が表示されます。

上記サンプルプログラムでは、最初に7文字と終端文字を含む長さ8の文字列を宣言しています。 その後、char型のポインタを宣言しています。 ポインタは型の後に「*」をつけることで宣言します。

上記サンプルでは、ptrというchar型のポインタに対して配列aの先頭アドレスを代入しています。 そして、最初のprintfは、ポインタptrが表すアドレスの先にあるデータ(文字)を表示しています。 ポインタ型の変数の前に「*」をつけると、ポインタが指すアドレスに含まれる内容を意味します。

次に、ptrに3を足しています。 ptrに3を足すということは、ptrが指していたアドレスを3つ先に進めるという意味を持ちます。 上記サンプルでは、最初に配列aのアドレスをptrに代入したので、ptrを3つ進めるとa[3]である「d」を指すことになります。

そのため、*ptrの内容を表示している2回目のprintfは「d」という結果を表示しています。

サンプル2

今度は、ptrが指す先の内容を変更してみます。


#include <stdio.h>

int
main()
{
 char a[8];
 char *ptr;
 int i;

 a[0] = 'a';
 a[1] = 'b';
 a[2] = 'c';
 a[3] = 'd';
 a[4] = 'e';
 a[5] = 'f';
 a[6] = 'g';
 a[7] = '\0';

 ptr = a;
 *ptr = 'Z';

 ptr += 3;
 *ptr = 'W';

 printf("%s\n", a);

 return 0;
}

さて、上記サンプルの出力結果はどうなるでしょうか?

上記サンプルを実行すると、文字列aの一文字目と四文字目が変更されてしまっているのがわかると思います。 文字列aの中身はポインタ変数ptrを通じて変更しています。 最初はptrはaの先頭を示しています。 ptrがaの先頭を示している時に「Z」という文字が*ptrに代入されています。 これによって、aの先頭の文字は「a」から「Z」へと変更されます。

同様に、4文字目も「d」から「W」へと変更されます。

このように、ポインタを利用してポインタが指す先のデータを変更することもできます。

最後に

恐らく、まだちょっとピンと来ない部分があるとは思いますが、色々なコードを書いて徐々に慣れて行きましょう。


次:int型ポインタ

- C言語入門 記事一覧

おまけ