【6日でできるC言語入門】ポインタと配列

C言語では、ポインタと配列は非常に密接な関係を持っています。
ポインタを利用することで、配列の各要素に効率よくアクセスできたり、柔軟なプログラム設計が可能となります。
ここでは、「ポインタと配列」の関係性や使い方について、図や表を交えてわかりやすく解説します。

1.配列とポインタの基礎

1.1. 配列の宣言と利用

まず、配列とその各要素について確認しましょう。

#define LENGTH 4

int nums[LENGTH];  // 整数型の配列
char letters[LENGTH]; // 文字型の配列

この場合、numsは4つの整数、lettersは4つの文字を格納できる配列です。
配列の各要素はnums[0]letters[1]のようにインデックスでアクセスします。

1.2. ポインタ変数の宣言と配列アドレス

配列の各要素のアドレスは、ポインタ変数に格納できます。
たとえば、

int* ptr_nums = NULL;
char* ptr_letters = NULL;

ptr_nums = &nums[0];
ptr_letters = &letters[0];

このように、配列の先頭アドレスをポインタに代入できます。

宣言意味
int* ptr_nums;整数型へのポインタ変数
ptr_nums = &nums[0];配列の先頭アドレスを代入

2.ポインタと配列の連携

2.1. ポインタによる配列要素へのアクセス

 ポインタに配列の先頭アドレスをセットした場合、*(ptr_nums + i)のように記述すれば、nums[i]と同じように値を取得できます。

プロジェクト/ファイル名: Lesson53_1/main.c

#include <stdio.h>
#define LENGTH 4

int main(void) {
    int nums[LENGTH] = {10, 20, 30, 40};
    char letters[LENGTH] = {'a', 'b', 'c', 'd'};
    int* p_num = NULL;
    char* p_let = NULL;

    p_num = &nums[0];
    p_let = &letters[0];

    for (int i = 0; i < LENGTH; i++) {
        printf("nums[%d]=%d *(p_num+%d)=%d ", i, nums[i], i, *(p_num + i));
        printf("letters[%d]=%c *(p_let+%d)=%c\n", i, letters[i], i, *(p_let + i));
    }
    return 0;
}

実行結果

nums[0]=10 *(p_num+0)=10 letters[0]=a *(p_let+0)=a
nums[1]=20 *(p_num+1)=20 letters[1]=b *(p_let+1)=b
nums[2]=30 *(p_num+2)=30 letters[2]=c *(p_let+2)=c
nums[3]=40 *(p_num+3)=40 letters[3]=d *(p_let+3)=d

2.2. ポインタ演算と配列アクセス

ポインタに整数を加算すると、その型のサイズ分だけ後ろのアドレスを指します。
つまり、p_num + 1&nums[1]と同じ場所を指します。

配列インデックス配列アドレスポインタ演算参照値
nums[0]&nums[0]p_num*p_num
nums[1]&nums[1]p_num + 1*(p_num+1)
nums[2]&nums[2]p_num + 2*(p_num+2)
nums[3]&nums[3]p_num + 3*(p_num+3)

3.配列名とポインタの違いと共通点

3.1. 配列名の正体

配列変数名は、実は「配列の先頭アドレス」そのものです。
つまり、nums&nums[0]と同じ意味となります。
ですが、配列名そのものに「別のアドレスを代入する」ことはできません(読み取り専用)。

項目配列名ポインタ変数
先頭アドレスnumsp_num
代入不可可能
演算×(直接不可)加減算可能

3.2. ポインタと配列の使い分け

  • 配列名は「宣言した配列」のみを指す
  • ポインタ変数は任意の配列や変数を指すことができる(再代入OK)

4.配列とポインタを使った関数利用

4.1. 配列を関数の引数として渡す

配列を関数に渡すときは、実際には「配列の先頭アドレス」が渡されます。

プロジェクト/ファイル名: Lesson53_2/main.c

void print_array(int* arr, int len) {
    for (int i = 0; i < len; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main(void) {
    int scores[3] = {88, 77, 66};
    print_array(scores, 3);
    return 0;
}

実行結果

88 77 66

まとめ

  • 配列とポインタは密接に関連している
  • ポインタ変数は配列の各要素に柔軟にアクセスできる
  • ポインタ演算を使うことで、配列の要素を簡単に操作できる

ポインタと配列を正しく理解し活用することで、C言語プログラミングの幅が大きく広がります!