はじめに
備忘録として、メモしました。
配列の定義
1. 配列サイズは定数のみ
エラーなし
- 配列宣言時に要素数を指定
int array[5]; // 要素数 5 の配列を宣言
- const(定数)で要素数を定義
const int n=5; // まずは配列の要素数を定数として定める
int array[n]; // 要素数 n の配列を宣言 (これなら n は定数なのでコンパイルは通る)
エラーあり
- nは定数でなく、変数なのでコンパイルエラー
int n=5; // まずは配列の要素数を決める
int array[n]; // 要素数 n の配列を宣言 (しかしコンパイルエラー!!)
2. 配列サイズをコンパイル時に確定しなければならない
これを確かめるために、
プログラム実行中に、配列サイズを決められるかどうかを考える。
エラーあり
- nは定数でなく、変数なのでコンパイルエラー
int n; // 配列の要素数として用いる
std::cout << "配列の要素数を入力してください : ";
std::cin >> n; // この行は初めて登場するが、「コンソールから入力された値を n に代入する」という意味である
std::cout << "読み込まれた n の値は" << n << "です\n";
int array[n]; // 要素数 n の配列を宣言 (n は定数ではないのでコンパイルエラー!!)
- 定数constは宣言時に初期化しなければならず、値を変更しようとするとコンパイルエラー
const int n; // 配列の要素数として用いる
std::cout << "配列の要素数を入力してください : ";
std::cin >> n; // 今度は定数 n を変更しようとしてコンパイルエラー!
std::cout << "読み込まれた n の値は" << n << "です\n";
int array[n]; // ここまで到達しない)
以上のことから、配列サイズはコンパイル時に確定している必要があることがわかる。
→
では、プログラム実行中に配列サイズを決めたい場合、どうするか?
→
new演算子によるメモリの動的確保(ポインタの利用)
new演算子によるメモリの動的確保(ポインタの利用)
配列の動的確保 = プログラム実行中に配列サイズを決定
#include <bits/stdc++.h>
using namespace std;
int main()
{
int n; // 配列の要素数
int *a_heap; // int型のポインタ(後に配列として利用)
cout << "配列の要素数を入力してください: ";
cin >> n; // 配列の要素数をキーボードから打ち込む
// new演算子で整数n個分のメモリを確保
// 要素数n個の配列として使用可能
a_heap = new int[n];
// 以降、利用法は普通の配列と同じ(最後にdeleteでメモリ解放忘れずに)
for (int i = 0; i < n; i++)
{
a_heap[i] = 2 * i;
}
for (int i = 0; i < n; i++)
{
cout << a_heap[i] << endl;
}
// new演算子で確保したメモリ領域は、deleteで必ず解放する!(しないと、メモリリーク発生)
delete[] a_heap;
}
ポイント
- ポインタ(*a_heap)をあらかじめに宣言
- 配列の要素数nをキーボードから入力 ( = プログラム実行中に配列サイズを決定)
- 要素数n個の配列のメモリを
a_heap = new int[n];
- new演算子で確保したメモリ領域は、deleteで必ず解放する!← メモリリークを防ぐ
ヒープ領域とスタック領域
- スタック領域:自動変数である、ポインタ変数 a_heap が格納される
- ヒープ領域:new演算子により確保されるメモリが配置される。
- new演算子で確保された配列 a_heap を使い終えたら、delete[] a_heap によってヒープ領域のメモリを解放 ← メモリリークを防ぐ