アドレスとは - C言語
わかりやすいC 入門編の「17.1 アドレスとは」を読んでのメモみたいなもの
アドレスとは、メモリ内の位置のこと。
メモリは1バイトごとに区切られている。また、それぞれの区切りごとに0から順に番号が振られている。この番号をアドレスという。アドレスは16進数で表現される。
0x7ffee36fa9a8
みたいな感じ
変数のアドレスは使用しているアドレスの最初のアドレスとなる。
例:int型の変数aのアドレス
以下のように 変数a が複数のアドレスを使っていた場合、最初の0x7ffee36fa9a8
が変数aのアドレスとなる
0x7ffee36fa9a8 <- これが変数aのアドレス 0x7ffee36fa9a9 0x7ffee36fa9aa 0x7ffee36fa9ab
また、プログラムの中で&a
と書くことで、変数aのアドレス(0x7ffee36fa9a8
)表す。
&
はアドレス演算子といい、アドレスを求めることができる
配列のアドレスは少し特徴的
例えば、int型の配列nがあった場合、n
は
- 配列名
- 配列nのアドレスの定数
という2つの意味を持つ
配列の場合、&
をつけなくてもアドレスを表現できてしまう!
※それぞれの要素は変数と同じ扱いであるため、&
をつける
例:以下のような配列nの場合
0x7ffeecbb89b0 <- &n[0]のアドレス (nも同じアドレスを指す) 0x7ffeecbb89b4 <- &n[1]のアドレス 0x7ffeecbb89b8 <- &n[2]のアドレス
n == &n[0]
となっている!!
また、配列のアドレスはメモリ上の連続したアドレスになる。
#include <stdio.h> int main(void) { int a = 13; int n[] = {5, 12, 8, 21, 9}; printf("%p -- &a\n", &a); printf("%p -- n\n", n); printf("%p -- &n[0]\n", &n[0]); printf("%p -- &n[1]\n", &n[1]); printf("%p -- &n[2]\n", &n[2]); return 0; }
実行結果
0x7ffeecbb89a8 -- &a 0x7ffeecbb89b0 -- n 0x7ffeecbb89b0 -- &n[0] 0x7ffeecbb89b4 -- &n[1] 0x7ffeecbb89b8 -- &n[2]
n と n[0]のアドレスが全くおなじになっていることに注目
また、配列の各要素のアドレスが4バイトずつになっている。これは、この環境のコンパイラではintが4バイトだから。
「配列のアドレス」と「型」が分かれば、それぞれの要素のアドレスが分かるということ!!
これは、ここに書いたベースレジスタとインデックスレジスタに関係している
本当にn == &n[0]
なのか試してみた!
(2018/01/29 追記)
以下のプログラムを動かしてみた
#include <stdio.h> int main(int argc, char *argv[]){ int n[] = {3, 4, 7}; if (n == &n[0]) { printf("同じ!\n"); } else { printf("違う!\n"); } if (n == &n[1]) { printf("同じ!\n"); } else { printf("違う!\n"); } }
実行結果
同じ! 違う!
n == &n[0]
が一致していることがわかった!!
(追記ここまで)
&演算子と参照渡し
(2018/1/30 追記)
C言語では基本的にすべて値渡しになっている。値渡しでは、変数の値のコピーが渡される。
でも、ある関数で引数で渡された値ではなく、渡された変数の値を変えたい場合、値渡しでは実現できない。
そこで、参照渡しというものを使う。
&演算子を使うことで、変数のアドレスを求めることができる。参照渡しができる!
値渡しと参照渡しの違いを図で書いてみた
値渡しと参照渡しの違いをコードで表してみた
#include <stdio.h> int main(int argc, char *argv[]){ int a, b, *c; a = 25; // = 値渡しの場合 = b = a; b = 30; // bの値を変更 printf("a: %d\n", a); // = 参照渡しの場合 = c = &a; *c = 30; // c(aのアドレス)の値を変更 printf("a: %d\n", a); }
実行結果
a: 25 a: 30
参照渡しの場合の流れ
c = &a
で変数aのアドレスをポインタcへ格納*c = 30
でcに格納されているアドレスの変数(a)に30を設定する
(追記ここまで)
参考文献
- 作者: 川場隆
- 出版社/メーカー: 秀和システム
- 発売日: 2011/09/29
- メディア: 単行本
- クリック: 2回
- この商品を含むブログ (4件) を見る