C言語の基礎(アドレスとポインタ)

スポンサーリンク
C言語

メモリとは

メモリは、コンピュータ内部で情報の記憶を担当するICチップである。メモリは、一つのマス目に1バイトの情報が書き込むことができる巨大な方眼紙のようなものである。

このようなメモリ内の場所、ある情報が格納されている位置を一意に示す数値をアドレスという。単位として「番地」を使う。

メモリは巨大な方眼紙
変数宣言・・ メモリのある領域を確保すること。
代入・・・・ メモリ領域の指定番地に情報を書き込むこと
取得・・・・ メモリ領域の指定番地から情報を読み出すこと

アドレス

変数の宣言と値の代入は、次の通りである。

int i = 8;

これで、int型の入れ物が準備され、その中に8という値が格納される。この変数iのための領域が、メモリのどこに割り当てられたかは、次の通り確認できる。

#include <stdio.h>

int main(void)
{
	int i = 8;
    printf("変数iのアドレスは%p",&i);
}

実行結果は次の通りである。

変数iのアドレスは0x7ffe92fc4434

「&i」のように、変数名の前にをつけると、その変数のアドレスを知ることができる。変数指定「%p」で、メモリ上の位置を16進数表現したものが出力される。

ポインタ

変数名に&記号をつけると、その変数のアドレスを知ることができる。このアドレスは、次のようにしてポインタ変数という変数に代入できる。

int i = 8;
int *p = &i;

変数pの型は「int *型」という。「int *p = &i;」と記述すると、変数iのアドレスが変数pに代入される。

ポインタ変数にアドレスを格納するイメージ

変数pに入るものは数値でなく、アドレスである。アドレスは特定の場所を指し示す(ポイントする)ので、pをポインタ変数(ポインタ)という。

ポインタのサイズ(変数pに割り当てられた箱の大きさ)は実行環境によって異なるが、次の通り確認できる。ここでは、4バイトの領域を使ってメモリ上に格納されるものとする。

#include <stdio.h>

int main(void)
{
	int i = 8;
	double j = 10;
	
    printf("int *型ポインタのサイズは%d\n",sizeof(int *));
    printf("double *型ポインタのサイズは%d\n",sizeof(double *));
    
}

例えば、実行結果は次の通りとなる。

int *型ポインタのサイズは4
double *型ポインタのサイズは4

ポインタを使った値の参照

これまで変数の値が格納されたメモリ上の位置(アドレス)を確認してきた。これは、変数名を使わずに、ポインタから値にアクセスできるようになるということにほかならない。

ポインタ変数による値の参照

「p」という箱に入っているのは、「100番地」というアドレスである。(先頭のアドレスが100番地ということ)また、pは「int *型」のポインタなので、そのアドレスにはint型の箱があるということである。そこで、100番地を見てみると、そこには、int型の値を入れる箱があり、中には「8」という値が入っている。

このように、変数名iを使って表記した場合と、*pと表記した場合の両方とも、メモリ上の同じ値を参照している。

ここで、これまでに説明した内容を確認しよう。

#include <stdio.h>

int main(void)
{
	int i = 8;
	int *p = &i;
	
	printf("変数iのアドレスは%p\n",&i);
	printf("pの値は%p\n",p);
	printf("iの値は%d\n",i);
    printf("*pの値は%d\n",*p);
    
}

筆者の環境では、実行結果は以下の通りである。

変数iのアドレスは0x7ffe07cc2afc
pの値は0x7ffe07cc2afc
iの値は8
*pの値は8

値とアドレスの参照方法を再度まとめておく。

宣言int型の値を参照するときの表記アドレスを参照するときの表記
int i;i&i
int *p*pp
int型の変数とint *型のポインタ変数の関係

(参考文献)C言語 新版: ゼロからはじめるプログラミング(三谷純著・翔泳社 (2022/9/1))、スッキリわかるC言語入門 第2版(中山 清喬  (著)・ インプレス; 第2版 (2021/12/14))

コメント

タイトルとURLをコピーしました