

こんなお悩みにお答えします。
アドレスとはメインメモリ上の場所を示す番号


こう言われてもわけがわからないですよね。
それもそのはず、アドレスがわからない理由はメインメモリについて知らないからです。
アドレスを理解するにはメインメモリとは何かと、どう使われるのかの理解が必須です。
ということで簡単に解説しますと…
プログラムを動かすとパソコンの中に入ってるCPUとメインメモリが主に動きます。
CPUには計算をしたりメインメモリやディスプレイなどのパーツに命令を出したりする役割があります。
メインメモリとはその名の通り保存するためのパーツです。
メインメモリはCPUの動作について行けるほど動作速度が速いので、CPUの相棒として使われます。
プログラムを実行するとメインメモリにプログラムの中身が展開され、プログラムで使う変数などが一時的に保存されます。
詳しくはこちら
-
-
【初心者向け】コンピュータとプログラムの仕組みを図解でわかりやすく解説
コンピュータってどんな仕組みで動いてるの?CPUとかメモリとかって聞くけど、どんな働きをしてるの?わかりやすく教えてほしい。 プログラムってパソコン上でどうやって動いてるの?初心者でも理解できるように ...
続きを見る
メインメモリ内で変数が保存される場所は変数の性質によって異なります。
例えばローカル変数はスタック領域、グローバル変数やstatic変数は静的領域に保存されます。


詳しくはこちら
-
-
スタック領域・ヒープ領域・静的領域の仕組みと違いをわかりやすく解説
プログラムを実行するとメインメモリはどうやって使われるの? スタック領域・ヒープ領域・静的領域ってどんな仕組み?それぞれどう違うの? こんな疑問にお答えします。 おゆプログラマーにとってメインメモリの ...
続きを見る
メインメモリについて大まかに把握したところでアドレスについて解説していきます。
例えば以下のプログラムの動きを考えてみます。
例:
#include <stdio.h> void main() { int num=10; char chara='A'; printf("num=%d\n",num); }
実行結果
num=10
numとcharaはそれぞれメインメモリのスタック領域に以下のように格納されます。


図の1マスはメインメモリ内のスタック領域のメモリセル1つを表しています。
1行が32マスあるので、4バイト(32ビット)分のデータが保存できます。
整数型の変数numには図の1行分(4バイト分)、charaには8マス分(1バイト分)の領域が割り当てられます。


それ以外の領域には変数とは関係のない値が保存されます。
実際はCPUのレジスタが空いていればローカル変数はそこへ保存されます。しかしここではイメージを掴んでもらうことが目的なのでCPUのレジスタは埋まっているとして解説しています。
例ではprintfでnumの値を表示するよう書かれています。
これを実行するため、CPUはまずnumの値を保存先のメインメモリに問い合わせます。
ですがメインメモリはどこにどの変数が保存されているか知らないので、以下のように問い合わせるとメインメモリは困ってしまいます。
これを解決するのがアドレスです。
先ほどのメインメモリ領域を1バイトごとに分け、左上から順に番号を振っていきます。
この番号がアドレスです。
スタック領域のアドレスは大きい数字から順に振られていくので、例として100から順に番号を振ります。


実際のアドレス値はメインメモリのどの位置にスタック領域が作られるかによって変わります。ですがここでは想像しやすいよう、アドレスを100始まりで振っていきます。
このようにしてメインメモリ内にアドレスを振り、CPUのセリフを以下のように変えます。
アドレスとバイト数を指定すればちゃんと目的の値が得られるんです。
このようにコンピュータ内部ではアドレスを使って変数を管理しています。
ちなみにcharaの値が欲しければ「アドレス96から1バイト分の値を教えて!」と言います。
得られた値とASCIIコード表(2進数と文字の対応表)と照らし合わせれば変数charaにはAが入っているとわかります。
つまりアドレスとはメインメモリの場所を特定するために振られた番号のことです。
変数に&を付けるとアドレスの中身が見れる
実は変数の頭にアンパサンド(&)を付けると変数が保存されている場所の先頭アドレスが得られます。
例:
#include <stdio.h> void main() { int num=10; char chara='A'; printf("num address=%d\n",&num); printf("chara address=%d\n",&chara); }
実行結果
num address=96468236
chara address=96468235
出力されるのは先頭アドレスなので整数型変数numはアドレス96468236から96468239までの4バイト分に保存されています。
文字型変数は1バイト分なので、charaは96468235に保存されています。
ポインタとは変数のアドレスを保存する変数
コンピュータ内部ではアドレスを使って変数を管理しています。
ということはプログラマもアドレスを指定して変数を操れるはずです。
このときに使うのがポインタです。
ポインタは変数のアドレスを保存するための変数です。


ポインタの宣言方法
データ型 *変数名;
変数名の前にアスタリスク(*)を付ける。
ポインタと同じデータ型の変数のアドレスを格納できる。
ポインタの使い方
初期化方法:
変数名=&変数名;
値の取り出し方:
*変数名
アドレスの取り出し方:
変数名
例:
#include <stdio.h> void main() { int num=10; int *p; //ポインタの宣言 p=# //ポインタにnumのアドレスを代入(初期化) printf("num=%d\n",num); printf("*p=%d\n",*p); //ポインタが示すアドレスに格納されている値を取り出す printf("num address=%d\n",&num); printf("p=%d\n",p); //ポインタに保存されているアドレスを取り出す printf("p address=%d\n",&p); //ポインタが保存されているアドレスを取り出す }
実行結果
num=10
*p=10
num address=71301444
p=71301444
p address=71301432
ポインタ宣言の書き方は変数宣言と似ており、変数名の前にアスタリスク(*)を入れることでポインタの宣言になります。
例ではポインタpに変数numのアドレスを代入しています。
*pと書くとポインタpのアドレスに格納されている値、つまりnumの値を指します。
メインメモリ内の様子を図で表すとこのようになります。
メインメモリ内にはnumの領域とpの領域が確保され、それぞれにnumの値とnumのアドレスが2進数で格納されます。
別の図で表すと以下のようになります。
四角内の数字は保存されている値です。
aが保存されているのはアドレス71301444から始まる領域で、10という数字が保存されています。
pにはaのアドレス71301444が格納されています。
ポインタを使うメリット


と思う方もいらっしゃるかと思います。


例えば関数内で実引数(関数呼び出し時に引数として渡した変数)の値を変更したいときにはポインタを使う必要があります。
詳しくはこちら
-
-
【C/C++】関数の値渡し・ポインタ渡し(アドレス渡し)・参照渡し
C言語、C++の関数には値渡しとポインタ渡し(アドレス渡し)と参照渡しの3種類があります。 ここではその違いを解説します。 関数への値渡し 関数へ変数を渡すとき、特にアドレスやポインタを使わなければ値 ...
続きを見る
また配列や構造体を引数として関数に渡すときにもポインタがあると便利です。
詳しくはこちら
-
-
【C言語】配列を関数の引数として渡す!サイズは渡す?ポインタは使う?
配列を引数として渡す方法を解説します。 方法は複数あるのですが、ここでは「これを使っておけばOK」という方法を紹介します。 配列を引数として関数に渡す方法 配列で受け取る方法【通常はこれ】 配列で受け ...
続きを見る
malloc関数を用いたメモリ領域の動的確保にも使われます。
C言語で行き詰まったら…
-
-
C言語・C++がわからない時に質問できるサイト・サービス5選
C言語を独学で勉強しているけど内容がイマイチわからない。もはや何がわからないのかもわからない。 C++のエラーが解決できない。ググってもわからない。わかる人に解説してほしい。 こんなお悩みにお答えしま ...
続きを見る