そろそろC++やります
そろそろC++をやります。そろそろC++をやりたいからです。
何回やるかはわかりません。基礎を理解するまではやろうと思います。
という感じでやっています。
※ 初心者がメモレベルで記録するので、技術記事としてはお力になれないかもしれません。
内容
配列の初期化
初期値を与えて、初期化することができます。
int ar[2]{13, 17};
=
で繋いでも、初期化することができます。
int ar[2] = {13, 17};
初期化指定する要素が、配列の要素数を満たさない場合は、規定値となります。intの場合は0が規定値です。
int ar[2]{13}; // ar: {13, 0} int ar[2] = {13}; // ar: {13, 0} int ar[2]{}; // ar: {0, 0}
{ }
を書かない場合は、メモリの位置にあるランダムな値が入るので注意が必要です。
int ar[2]; // ar: {49036572, 1}
for文で回して、各要素に代入して初期化する場合もあります。
int ar[2]; for (int i = 0; i < 2; i++) { ar[i] = i * 3; }
関数に配列を渡す
配列は関数に渡される時、最初の要素へのポインターとして渡されます。
void ReceiveArray(int *arArg) { cout << "In ReceiveArray function" << endl; cout << &arArg << endl; cout << arArg << endl; } int main() { int ar[2]{13, 57}; cout << "In main function" << endl; cout << &ar << endl; ReceiveArray(ar); return 0; } // Output: // In main function // 0x16b5bedc0 // In ReceiveArray function // 0x16b5bed88 // 0x16b5bedc0
いろいろ試したのですが、配列の変数(ar
やarArg
)のアドレス(&ar
や&arArg
)はどこにあっても構わず、配列の変数の中身が、アドレスとなっており、それが配列の要素の最初のアドレスになっていることが大切ということが分かりました。
配列の要素へのアクセスを詳しく調べる必要がありそう
です。
関数で渡されたポインターには、その他のサイズや型情報を持たないので、別のパラメータで要素の数を渡す必要があります。
void process(double *p, const size_t len)
C++の他の記事をみると配列のサイズは、sizeof
を用いて計算できると書いてあることもあります。
int arrayLength = sizeof(arArg) / sizeof(int);
しかし、これを関数で渡された配列(ポインター)で行うと結果が異なります。sizeof(int);
は、同じコンピューターで不変ですが、sizeof(ar)
とsizeof(arArg)
の結果は異なります。
void ReceiveArray(int *arArg) { cout << "=====In ReceiveArray function" << endl; cout << sizeof(arArg) << endl; } int main() { int ar[4]{13, 57}; cout << "=====In main" << endl; cout << sizeof(ar) << endl; ReceiveArray(ar); return 0; } // Output: // =====In main // 16 // =====In ReceiveArray function // 8
sizeof(arArg)
は、ポインターのサイズである8を返していました。
また、ポインター渡しなので配列の中身を変更することができます。
void ReceiveArray(int *arArg) { arArg[0] = 321; } int main() { int ar[4]{13, 57}; cout << "=== Before call function" << endl; cout << ar[0] << endl; cout << ar[1] << endl; ReceiveArray(ar); cout << "=== After call function" << endl; cout << ar[0] << endl; cout << ar[1] << endl; return 0; } // Output: // === Before call function // 13 // 57 // === After call function // 321 // 57
const
キーワードをつけることで明示的に配列を変更不可能にすることができます。コンパイル時にエラーを吐くようになります。
void ReceiveArray(const int *arArg) { // error: read-only variable is not assignable arArg[0] = 321; }
また、配列の引数は以下の方法で宣言することもできます。
void ReceiveArray(int arArg[4]) { }
参考リンク
感想
初期化は慣れればその書き方ができそうで、読む分には困ることはなさそうです。関数渡しについては、基本的に参照渡し(ポインター渡し)が行われて、配列の型情報や大きさは別で伝える必要があることに注意をすればよさそうです。
次回は、多次元配列を行います。