アドレスとは アドレスはコンピュータ内のメモリ,1バイトごとにつけられた番号のことです  

101010101010010111


アレサ 「00101010101・・・


再び、お話は変数の型charにもどります。」


ソーラー 「アレサは変数の型charが好きなんだね。」


アレサ 「!0000000000000011111・・・・・・・・・


は、はずかしい・・・」


ソーラー 「僕も変数の型charは大好きだよ。


このチャーって発音するところといい、

(実際はキャラです)


数値だけでなく、文字を格納できるところといい、


魅力的な変数の型だと思うんだ。」


アレサ 「ソーラーさんも そう思われますか?」


ソーラー 

「もちろん!」


アレサ「では、よろこんで変数の型charのお話のつづきを・・・


#include <stdio.h>


int main(void)

{

char a;

a=111;


printf("あなたの預金額はただいま%d円です。\n",a);

return 0;

}


コンパイル結果


あなたの預金額はただいま111円です。


次はこのプログラムの%d出力変換指定子を%c出力変換指定子に置き換えた場合


#include <stdio.h>


int main(void)

{

char a;

a=111;


printf("あなたの預金額はただいま%c円です。\n",a);

return 0;

}


コンパイル結果


あなたの預金額はただいまo円です。


アレサ「数字の0でなくアルファベットのoが表示されました



char型の変数は-128から127の範囲にある数値



シングルクオーテーション' 'で囲まれた半角英数字や記号の1文字を


メモリーに格納することができます。



そして%c出力変換指定子は


char型の変数aに格納されているものが


文字ならば その文字を


(char型の変数には-128から127の範囲にある数値を格納できます)


ならば


コンパイル結果


あなたの預金額はただいまo円です。


のように


その数値に対応する


半角英数字記号1文字をprintf出力表示します。


このプログラムの場合


char型の変数に格納されている111を


%c出力変換指定子をつかってprintf出力表示


しています。


この場合の数値111はアスキーコードとよばれ


%c出力変換指定子は


アスキーコード111に対応する文字oを出力しています。」


ソーラー「今度は


数値111でなく


数値118をchar型の変数aに格納し


%c出力変換指定子をつかって


printf出力表示するプログラムを実行してみると→」


#include <stdio.h>


int main(void)

{

char a;

a =118;


printf("あなたの預金額はただいま%c円です。\n", a);

return 0;

}


コンパイル結果

(EAZY IDECの場合)

(Visual Studioの場合)


あなたの預金額はv円です


が表示されます。


ソーラー「→


アスキーコード118に対応するvがprintf出力表示されています。



ソーラー「試しに今度は


アスキーコードでない


数値-128を変数の型charに格納し


%c出力変換指定子をつかって


printf出力表示するプログラムを実行してみると


#include <stdio.h>


int main(void)

{

char a;

a = -128;


printf("あなたの預金額はただいま%c円です。\n", a);

return 0;

}


コンパイル結果

(EAZY IDECの場合)

(Visual Studioの場合)


あなたの預金額は・円です


が表示されます。


つまり

-128はアスキーコードでないので

-128に対応する専用の半角英数字あるいは記号がないので


・が表示されるのですね」



ソーラー 「アレサ、だいたい変数の型charの仕組みはわかってきたね。


よかったね。(^^)」


ほっとした感じのソーラー。


アレサ 「そうですね。


今まで見てきたように


char型の変数に文字を格納して


%c出力変換指定子をもちいて


そのままその文字をprintf出力表示


することができますし


また


char型の変数に数値を格納して


%d出力変換指定子をもちいて


そのままその数値をprintf出力表示


することもできます。


さらに


変数の型charに数値を格納して


%c出力変換指定子をもちいて数値(アスキーコード)に対応する


半角英数字をprintf出力表示


することができます。


このように


変数の型charは文字と数値を格納でき


さらに数値の場合は


%d出力変換指定子を用いて


そのまま数値としてprintf出力表示することも


%c出力変換指定子を用いて


数値(アスキーコード)に対応する


半角英数字をprintf出力表示


することができるのです。


 01101010100・・


そこで・・・


今日は別の話題・・・・


アドレスについてみていきましょう。 ね、ソーラーさん」


ソーラー 「アドレス・・・・???」


アレサ 「アドレスとは


コンピュータにはメモリと呼ばれるデータの記憶装置があります。


その記憶装置は1か0のどちらかの数値を収める部屋がたくさん集まって


構成されています


その1か0のどちらかの数値を収める部屋1つを1ビットといいます。


そして


1ビットが8つ集まったものを1バイトといいます。


アドレスとは


0と1を格納する1バイト(8ビットになります、1ビットではありません)のお部屋の集まりごとに


割り振られた番号のことです。


天国にいけるC言語入門シーズン1でも見てきたように


1バイトがデータをおさめる基準の単位になっています。


そして


int a;


とaの変数宣言をした場合


intは4バイトのメモリ容量をもつ変数の型なので


1バイトのお部屋


4つが変数aが格納する整数値データ保存用に


あてられることになります。


その1バイトのお部屋4つにはそれぞれ


アドレスという番号がつけられています。


そして

その4つのお部屋には


41981543

41981544

41981545

41981546


のように


連続したアドレスがつけられています。。」


ソーラー 

「アドレス・・・1バイト単位に順番につけられた番号・・・


前にもお話したけどデータをコンピュータが呼び出すときは


データの収められている場所の名前がないと


呼び出すことができないという


不思議な自然の仕組みがあります。


なんとか 僕もアドレスをメモリにつけないで


コンピュータがデータをメモリから呼び出す方法を


かんがえたけど


どうしても記憶する場所、メモリに名前(アドレス)を


つけないと無理っぽい・・・


つまり なぜ 


アドレスというものがメモリにつけられているの?


と思われるかもしれないけど、


自然の構造上


必然的にアドレスというものがどうしても


必要となってくる。・・・


だから


メモリにはアドレスがつけられてるというわけなんです(*´▽`*)」


アレサ 「000001111 そうですね。不思議ですね・・・」


ソーラー 「それにしても


int型の変数a(4バイト)は4つの1バイトのお部屋をもっているから


そのアドレスも


41981543

41981544

41981545

41981546と4つあるんだね。」


アレサ 「そうですね。そして


その変数aのアドレスを知る方法があります。」


ソーラー 「な~に~~~~~ぃぃぃ~


                やっちまったなあ~~~~~」


アレサ 「はうぅっ 01111000・・


???  0101111111・・・・・・


???なぜ、その反応が・・・?


と、とりあえず



このようなプログラムを構成することにより」


#include <stdio.h>


int main(void)

{

int a;

printf("%p\n",&a);

return 0;

}


コンパイル結果(EAZY IDECの場合)

0019FF54


ビルド結果(Visual Studioの場合)

00F8F830


(このように変数aのアドレスの値は

お使いの統合開発環境によって異なってきます

さらにメモリの使用状況によっても異なってきます

あるメモリが使用されていると別のメモリにデータが格納されるというわけです)


アレサ「


変数aの格納されているメモリのアドレスを知ることができます。


変数aのアドレスはアンパサンド&を変数aにつけた&aであらわされます


そして変数aのアドレス&aをコマンドプロンプト画面に表示するのに


メモリに格納された数値データを


16進数で表示する%p出力変換指定子が


もちいられます


なぜならアドレスは16進数で


表示するというのがルールとなっているからなのですの」



ソーラー「あはは わかった


このプログラムでは


よくみると


変数aが初期化されていないよね


つまり


変数aのメモリには数値が格納されていないけど


変数aのメモリのアドレスを


表示してみたというわけなんだね。


でも


変数aは連続した4バイト、4つのお部屋をもっているわけだから


4つアドレスが表示されないと


いけないような気がするような・・・?」


アレサ「実は変数aは連続した4バイト、4つのお部屋をもち


その4つのお部屋には順番に連続したアドレスが付けられているのですが


変数aのアドレス&aをprintf出力表示するときは


データを格納したときの先頭のお部屋のアドレスだけが


表示される仕組みとなっています


たとえば数値データ1を


int型の変数aに格納した場合を考えてみます。


数値データ1は


メモリに


00000000 00000000 00000000 00000001(4バイト、32ビット)


と格納されます。


そのとき


同じ統合開発環境をつかっていても



41981543  00000001

41981544  00000000

41981545  00000000

41981546  00000000


という順番で小さな数値から順に


メモリにデータが格納されている場合もあれば


41981546  00000001

41981545  00000000

41981544  00000000

41981543  00000000


という順番でおおきな数値から順に


メモリにデータが格納されている場合もあるというわけです。」




ソーラー「へえ~そうか~そんな仕組みなんだ」


アレサ「はい、そうなんですの


次は


変数aを

a=1;と

初期化した次のプログラムを実行した場合


変数aのアドレスはどうなっているかしらべてみますか?😊


#include <stdio.h>


int main(void)

{

int a;

a=1;

printf("%p\n",&a);

return 0;

}


コンパイル結果(EAZY IDECの場合)

0019FF54


ビルド結果(Visual Studioの場合)

0036FCE8


ソーラー「あれ?


EAZY IDECの場合は


初期化してもしなくても


変数aのアドレスは

0019FF54


だけど


Visual Studioの場合は


変数aのアドレスは変化しているね」


アレサ「


はいっ😊さらにもう1回


今のプログラムを実行してみると

👇

#include <stdio.h>


int main(void)

{

int a;

a=1;

printf("%p\n",&a);

return 0;

}


コンパイル結果(EAZY IDECの場合)

0019FF54


ビルド結果(Visual Studioの場合)

012FF98C


となります。」


ソーラー「なんだか よくわからないけど


(Visual Studioの場合)

どんどん


数値1を格納している変数aのアドレスが変化しているね。


つまり


1を格納しているメモリの場所が


プログラムの実行ごとに変化しているんだね」


アレサ「このようなところにも


統合開発環境の違いがみられますね」



  • Twitterで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます