digirakuda ようこそ!  コンピュータの世界へ!

第9回 ポインタとは

このポインタの章まで理解できたら,C言語を70%理解できたといっていいでしょう.それほどポインタの理解は難しいものです.ポインタの操作はC言語の特徴の1つで,ポインタを用いることにより,計算機に密着したプログラム(アセンブラ以外の言語では書くのが困難なプログラム)が書けますし,よりコンパクトなプログラムが書けます.そこでこの章ではまず,ポインタとアドレスについての予備知識から入っていきます.

~アドレスについて~

アドレスとはメモリ上の記憶場所に付けられた住所のことです.通常のコンピュータ(マイコン,パソコン,ワークステーション,大型コンピュータ,他)をノイマン型コンピュータといいます.おおざっぱにいって,ノイマン型コンピュータは,プログラムとデータ(変数)をメモリ(記憶装置)にしまっておいて,必要なときにそれをメモリからCPU(中央演算装置)へ引き入れ,プログラムによりデータを処理していきます.

***********説明図**********

メモリは,パソコンでさえ1メガバイト以上の広大な記憶容量があります(1メガバイト=英文字で約100万文字,日本語で約50万文字=400字詰め原稿用紙約1250枚分).そこで,メモリにはどこにデータをしまったか判らなくならないように,住所が割り当ててあります.この住所のことをアドレスと呼びます.

アドレス(住所)があれば,たとえばアドレス02FF番地に文字'Q'を憶えさせておく,また呼び出してくる,ということが可能になります.実際にメモリ上のプログラム(機械語)は例えば,02FF番地のデータに240F番地のデータを足した答えを40CA番地に憶えさせる.というようなことを行っています.

*************説明図*********

しかしC言語でプログラムを書くときは,このようなことを気にする必要はなく,メモリ上で動くプログラム(機械語)への翻訳はコンパイラーがやってくれています.

~ポインタについて~

ポインタは,他の変数のアドレスを格納する変数です.言い換えれば,ポインタは,他の変数のアドレスをしまう(憶えておく)入れものです.変数も配列もメモリに記憶させておくものですから,全てにアドレスが割り当てられます.また,アドレスも何バイトかの(コンピュータの種類,コンパイラによって異なります)数値として表されています.ですからそれもint型やchar型と同じように変数としてプログラム上で扱うことができます.このアドレスを格納できる変数がポインタです.さらに,英和辞書で調べるとポインタ(pointer)とは「指すもの」という意味あいがあります.ポインタは何の型を指し示すか(何の型で宣言された変数のアドレスを格納できるか)によって異なり,「char型を指すポインタ」とか「int型を指すポインタ」などがあります.その他,全ての型にポインタ型があります.

*********説明図***********

[課題9-1]char型を指すポインタを宣言しよう.

[プログラム例9-1]


01: #include <stdio.h>
02: void main(void){
03:     char *p;
04:     char ch='A';
05:
06:     p = &c;
07:     printf( "%c\n", ch );
08:     printf( "%c\n", *p );
09:     printf( "%x\n", p  );
10:     getchar();
11: }

行説明
03行目→変数pをchar型を指すポインタとして宣言します.
04行目→変数chをchar型として宣言し,文字'A'で初期化します.
06行目→char型を指すポインタpに変数chのアドレスを代入します.
07行目→char型変数chを文字として出力します.
08行目→char型を指すポインタpの指すアドレスに格納されている値を文字として出力します.
09行目→char型を指すポインタpの指すアドレスを16進数として出力します.

[結果9-1]

コンパイル・実行すると次のよう表示されます.

A
A
FE3

リターンキーを押すとプログラムは終了します.

 演算子*は,以前は×(乗算)記号として使っていましたが,ポインタ演算子としても機能します.宣言文char *p;のように宣言することにより変数pは,「char型を指すポインタ」と宣言されます.これで変数pはchar型変数のアドレスを格納できるようになります.
 また,演算子&は変数の左に付けるとその変数のアドレスを表す演算子です.文p = &c;のように使い,この文は「変数cのアドレスをポインタpに代入する」という意味です.

***********説明図***********

さらに,演算子*は,宣言文以外に使われると「ポインタの内容が示しているアドレスの内容」という意味になります.ポインタを「指すもの」と考えれば「ポインタの指す内容」と言い換えても良いでしょう.文printf( "%c\n", *p );の中の*pは「ポインタpの指す内容」です.ここでポインタpには変数cのアドレスが代入されていますから,ポインタpは変数cを指しています.したがって,*pは変数cの内容'A'ということになります.

***********説明図**************

ここで,*pを「ポインタの指す内容」と考えれば宣言文char *p;も「ポインタpの指す内容がchar型であるように宣言する」と言い換えても良いでしょう.
 アドレスは実際には何バイトかの数値ですから,それを表示することもできます.文printf( "%x\n", p );中のポインタpはすでに,変数cのアドレスが代入されていますから,この関数printf()は変数cのアドレスを16進数で画面に出力します.

[文法9]

1.ポインタ宣言


①char *変数名;
②int *変数名;
(1)ポインタの宣言は,ポインタ名の前に*を付けます.
(2)ポインタの宣言は,①char型,②int型以外にも全ての型で行えます.
(3)ポインタは,他の変数のアドレスを格納する変数です.

2.ポインタ演算子


①演算子* → 変数のアドレスを取り出す.
②演算子& → ポインタが指す内容を取り出す.
(ポインタがが示すアドレスにある内容を取り出す.)


このドキュメントは http://icrus.org/c_language_beginers_course/ 上にあります.

2017,1 ssatoh@ 足立工科大学 工学部 情報通信工学科