はじめに
- これまでの学習に続いて、今回はポインタなどについて学んだ結果をまとめてみました。
学習環境
- 今回はpaiza.ioのC言語のエディタを使いました。
ポインタとは
ポインタの必要性
- こちらのサイトにはポインタの必要なシーンが以下のように説明されています。
- 私のようなC言語の初学者にはこの説明だけだと理解が難しいですが、ここは軽く読み飛ばして先に進んでみます。
- 関数に「参照渡し」という形で引数を渡す場合
- ヒープ領域を使う場合
- 関数自体をデータとして扱う場合
変数とアドレス
- メモリ上のデータは8ビットを1まとめにした1バイト単位で扱われます。
- メモリ上のデータにアクセスするには、バイト単位で付与されたアドレスを指定します。
- ビット単位ではデータにアクセスできません。
- メモリ上のアドレスは通常16進数で表されます。
- 例えば「0x7ffe3f1afd5c」などの形で表されます。
- 変数には様々なデータ型があり、それらは全てバイトの整数倍のメモリサイズで表されます。
- int型:4バイト
- float型:4バイト
- double型:8バイト
変数とポインタ
- 変数名の前に「&」という記号を付けると、その変数に割り当てられたメモリ上の領域を「ポインタ」という形で得られます。
- 「&」はアドレス演算子と呼ぶそうです。
- 「*&a」のように、ポインタ値の前に「*」を付けることで、そのポインタが指している変数を参照できます。
- 実際の変数を直接参照するのではなく、ポインタを介して参照しているので「間接参照」と呼ぶそうです。
- 「*」は間接参照演算子と呼ぶそうです。
- ポインタ値を格納するポインタ変数は、
int* a_ptr
もしくはint *a_ptr
というように宣言することが出来ます。-
int *a_ptr
を使うと紛らわしいので、ここではint* a_ptr
を使っています。
-
サンプルコード
- 以下のコードを作ってみましたが、まだポインタの利点などを理解できていない状態です。
- 今後学習を進めれば少しずつ理解できるのでしょうか?
main.c
#include <stdio.h>
int main(void){
int a=3;
printf("aの値は%dです。\n", a);
// 変数の前に「&」を付けるとアドレスを取得できる。
printf("aのアドレス(&a)は%pです。\n", &a);
// アドレスの前に「*」を付けると、そのアドレスにある値を取得できる。
printf("&aの値は%dです。\n", *&a);
// ポインタ型変数(int型)の利用
int* a_ptr;
/*
int *a_ptr; // こちらは紛らわしいので使わない
*/
a_ptr = &a; // アドレスをポインタ型変数に代入
printf("a_ptrのアドレスは%pです。\n", a_ptr); // ポインタ型変数のアドレスを表示
printf("a_ptrの値は%dです。\n", *a_ptr); // ポインタ型変数のアドレスが指す場所にある値を表示
*a_ptr = 5; // ポインタ型変数を「通常変数モード」にして値を代入
printf("a_ptrのアドレスは%pです。\n", a_ptr); // ポインタ型変数のアドレスを表示
printf("a_ptrの値は%dです。\n", *a_ptr); // ポインタ型変数のアドレスが指す場所にある値を表示
return 0;
}
実行結果
aの値は3です。
aのアドレス(&a)は0x7ffe3acc6dbcです。
&aの値は3です。
a_ptrのアドレスは0x7ffe3acc6dbcです。
a_ptrの値は3です。
a_ptrのアドレスは0x7ffe3acc6dbcです。
a_ptrの値は5です。