C言語の配列
C言語の配列についての解説です。C言語の配列は、長さが固定の静的な配列です。
# 配列の宣言 型 変数名[要素数];
長さ3のint32_t型の配列を宣言するサンプルです。
#include <stdint.h> #include <stdio.h> int main(void) { // 配列の宣言 int32_t nums[3]; }
配列の要素は、初期化されていません。0で初期化されるわけではないので注意しましょう。
配列の初期化
宣言と同時に配列を初期化することができます。要素数は省略できます。
# 配列の宣言と初期化 型 変数名[] = {要素0の初期値, 要素1の初期値, 要素2の初期値};
int32_t型の配列を宣言と同時に初期化するサンプルです。
#include <stdint.h> #include <stdio.h> int main(void) { // 配列の宣言 int32_t nums[] = {3, 5, 9}; }
配列を0で初期化
配列を0で初期化するための簡単な構文があるので紹介します。これは、初期化の構文で、初期値が指定されなかった場合は、0(すべてのビットが0)が初期値として使われるというC言語仕様を利用したものです。
#include <stdint.h> #include <stdio.h> int main(void) { // 配列の宣言と0初期化 - int32_t int32_t nums[3] = {0}; printf("%d\n", nums[2]); // 配列の宣言と0初期化 - double double dnums[3] = {0}; printf("%f\n", nums[2]); }
出力結果。
0 0.000000
配列の長さを管理する
C言語では、配列の長さを取得することはできません。自分で管理する必要があります。C言語の配列は、メモリ上へのポインタであり、長さ情報を持たないからです。
ですので、自分で記述して管理します。
#include <stdint.h> #include <stdio.h> int main(void) { // 配列の宣言 int32_t nums[] = {3, 5, 9}; // 配列の長さ int32_t nums_length = 3; }
配列の要素への取得と設定
配列の要素への取得と設定は以下の構文で行います。要素番号は0から始まります。
# 配列の要素の取得 配列[要素番号] # 配列の要素の設定 配列[要素番号] = 値
配列の要素の取得の設定のサンプルです。間違って、要素番号が、配列の最後の要素番号を超えた場合は、本来アクセスしてはいけないメモリ領域にアクセスしていることになりますので、注意しましょう。
#include <stdint.h> #include <stdio.h> int main(void) { // 配列の宣言 int32_t nums[] = {3, 5, 9}; // 配列の要素の取得 int32_t num1 = nums[1]; printf("%d\n", num1); // 配列の要素の設定 nums[1] = 12; printf("%d\n", nums[1]); }
配列の要素をすべて処理する
for文を使って配列の要素をすべて出力してみましょう。
#include <stdint.h> #include <stdio.h> int main(void) { // 配列 int32_t nums[] = {3, 5, 9}; // 配列の長さ int32_t nums_length = 3; // 配列の要素をすべて出力 for (int32_t i = 0; i < nums_length; i++) { printf("%d\n", nums[i]); } }
出力結果。
3 5 9
配列のデータは関数のコールスタック上に保存される
配列のデータは、関数のコールスタック上に保存されます。関数呼び出しを行ったときに、ローカル変数のためにコールスタックが確保されますが、この領域が使われます。mallocを使って、ヒープを確保するのと対照的です。
コールスタック上のメモリアクセスは、局所性が高いので、ヒープよりも、パフォーマンスが良いです。
Perlの配列との違い
C言語の配列は、静的な配列であり、関数のコールスタック上にメモリが確保されます。配列の要素のサイズは、要素の型のサイズ(構造体の場合はパディングを含むサイズ)です。
一方、Perlの配列は、動的な配列であり、ヒープ上にメモリが確保されます。配列の要素のサイズは、SV型のサイズです。