16進数
16進数は画像やファイルを扱うときに使用される。HEX(hexadecimal number)と呼ばれる。0からFまでの記号を使う。
プログラミングではメモリのバイト数を16進数で数えることが多い。データを4ビット単位で扱いたい場合に便利。
01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C, 0D, 0E, 0F, 10, 11, 12
ちなみに10, 11, 12の部分は10進数と混合しやすい為、16進数では"0 ✖️ 10"と表示される。
1番大きい数字 -> FF
16 * F + 1 * F
16 * 15 + 1 * 15
240 + 15
255
128 64 32 16 8 4 2 1
・ ・ ・ ・ ・・・・
138 10進数
10001010 2進数
8A 16進数
1桁の16進数は4ビットの2進数に対応する。2進数を以下のように4ビットずつ計算する
1000 1010
↓ ↓
8 8 + 2 -> 10は16進数でA
↓
8A
ポインタ
ある値のアドレス、アドレスの位置。変数やデータのメモリ上の位置(アドレス)を格納するための特殊な変数のこと。
& → アドレス演算子。被演算子のアドレス、&nとすることで変数nのアドレスを取得する。
* → 間接参照演算子。&nとするとアドレスが示すメモリの値にアクセスする。
#include <stdio.h>
int main(void)
{
int n = 50; // 変数nを用意
int *p = &n; // &nでアドレスを取得し*pに代入
printf("%p\n", p); // 変数を出力
printf("%i\n", *p); // 変数が格納されているアドレスを出力
}
以下出力結果
0x7ffd686c99ec
50
動的メモリ割り当て
malloc・・・メモリ割り当てを行う関数。数値を入力としてオペレーティングシステムに何バイトのメモリを見つけるか決定する。メモリ割り当てに失敗した場合NULLを返す。
free・・・メモリの解放を行う関数。mallocが与えたメモリの塊を使い終わった後に行う。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
// メモリ割り当て
int *ptr; // *ptrとすることで値ではなく、int型の値へのポインタ(アドレス)が格納されることを宣言。
ptr = malloc(sizeof(int)); // int型のサイズ分のメモリを割り当てる。一般的にint型は4バイトなのでmalloc(4);と同じ意味になる。
if (ptr == NULL)
{
printf("メモリ割り当て失敗\n");
}
*ptr = 11; // 値11が格納されているメモリのアドレスをptrに格納
printf("メモリに格納された値%d\n", *ptr);
printf("メモリに格納された値のアドレス%p\n", ptr);
free(ptr);
printf("メモリの解放\n");
}
以下出力結果
メモリに格納された値11
メモリに格納された値のアドレス0x558f5e0fd2a0
メモリの解放
mallocとfreeは組み合わせて使用する。そうでないとエラーの原因になる。
値渡し・・・関数に引数として渡された値がそのまま関数内でコピーされます。関数内で引数の値を変更しても、呼び出し元の変数には影響しない。
#include <stdio.h>
// 値渡しの関数
void increment(int x) {
x++; // xを1増やす
printf("Inside function: %d\n", x);
}
int main() {
int num = 5;
printf("Before function: %d\n", num);
increment(num); // 関数呼び出し
printf("After function: %d\n", num);
return 0;
}
出力
Before function: 5
Inside function: 6
After function: 5
参照渡し・・・関数に引数として渡された変数のアドレスが渡される。そのアドレスを通じて変更を行う。
#include <stdio.h>
// 参照渡しの関数
void increment(int *x) {
(*x)++; // xを1増やす
printf("Inside function: %i\n", *x);
}
int main() {
int num = 5;
printf("Before function: %d\n", num);
increment(&num); // 関数呼び出し
printf("After function: %d\n", num);
return 0;
}
出力
Before function: 5
Inside function: 6
After function: 6
コンピュータのメモリ内でのプログラム実行時の動作
コンピュータのメモリ内で起こっていること
————————————-
machine code
globals
heap
↓
↑
stack
————————————-
machine code・・・コンピュータが直接実行するバイナリコード。プログラムがメモリにロードされると、マシンコードが実行される。
globals・・・グローバル変数や静的変数など、プログラムのどこからでもアクセス可能な領域。プログラムの開始時にこの領域が確保され、プログラムの終了まで存在する。
heap・・・動的に確保されたメモリ領域で、malloc
や new
などの関数によって割り当てられる。プログラム実行中にメモリの割り当てと解放が行われるため、動的なデータ構造が格納される。
stack・・・関数の呼び出しと戻りに関連した情報(ローカル変数、関数の引数など)が格納される領域。関数が呼び出されるたびに新しいスタックフレームが作成され、関数の実行が終了するとスタックフレームが削除される。
heapとstackの部分でメモリ不足になり、異常終了やクラッシュを引き起こす。