[c言語] さっと復習(12) 配列とポインタ

配列とポインタ

ポインタ変数を使うことで、配列のそれぞれの値にアクセスできる。

#include <stdio.h>

#define SIZE 9

int main(void) {
    int array1[SIZE];
    char array2[SIZE];
    int i;
    int *p1 = NULL;
    char *p2 = NULL;

    for (i=0; i<SIZE; i++) {
        array1[i] = i;
        array2[i] = (char)((int)'A' + i);
    }

    p1 = &array1[0];
    p2 = &array2[0];

    // ポインタ変数に1を足すと、その型のサイズひとつ分だけアドレスが移動する。
    // つまり、配列の添字と一致する。
    for (i=0; i<SIZE; i++) {
        printf("array1[%d]=%d *(p1+%d)=%d  ", i, array1[i], i, *(p1+i));
        printf("array2[%d]=%c *(p2+%d)=%c\n", i, array2[i], i, *(p2+i));
    }

    // array1[0]=0 *(p1+0)=0  array2[0]=A *(p2+0)=A
    // array1[1]=1 *(p1+1)=1  array2[1]=B *(p2+1)=B
    // array1[2]=2 *(p1+2)=2  array2[2]=C *(p2+2)=C
    // array1[3]=3 *(p1+3)=3  array2[3]=D *(p2+3)=D
    // array1[4]=4 *(p1+4)=4  array2[4]=E *(p2+4)=E

    return 0;
}

添字の無い配列は、その配列の先頭のアドレスである。

よって、int array[5] という配列があれば、array でその配列のアドレスになるので、*arrayarray[0]*(array+1)array[1] とそれぞれ同じ意味になる。

#include <stdio.h>

#define SIZE 5

int main(void) {
    double array_d[SIZE] = {0.1, 0.2, 0.3, 0.4, 0.5};
    double *p1 = NULL;
    double *p2 = NULL;
    int i;

    // 配列名は、実は、配列の先頭のアドレスである。
    // つまり、&array_d[0] と array_d は同じ。
    p1 = array_d;
    p2 = array_d;

    for (i=0; i<SIZE; i++) {
        printf("%lf %lf %lf\n", *(array_d + i), p1[i], *p2);
        p2++;
    }

    // *(array_d + i), p1[i], *p2 は同じアドレスを参照する。
    // 0.100000 0.100000 0.100000
    // 0.200000 0.200000 0.200000
    // 0.300000 0.300000 0.300000
    // 0.400000 0.400000 0.400000
    // 0.500000 0.500000 0.500000

    return 0;

}

配列の動的生成

malloc 指定したバイト分だけ、ヒープ領域にメモリを確保する。

malloc

p1 = (int *)malloc(sizeof(int)*SIZE); のように、目的の型でキャストする。

ヒープ領域にメモリが確保されているので、使用後は、free でメモリを開放しなければならない。

ヒープとスタック

#include <stdio.h>
#include <stdlib.h>

#define SIZE 5

int main(void) {
    int *p1 = NULL;
    double *p2 = NULL;
    int i;

    // メモリを確保して、配列を生成
    p1 = (int *)malloc(sizeof(int)*SIZE);
    p2 = (double *)malloc(sizeof(double)*SIZE);

    for (i=0; i<SIZE; i++) {
        p1[i] = i;
        p2[i] = (double)i;
    }

    for (i=0; i<SIZE; i++) {
        printf("p1[%d]=%d p2[%d]=%lf\n", i, p1[i], i, p2[i]);
    }
    // p1[0]=0 p2[0]=0.000000
    // p1[1]=1 p2[1]=1.000000
    // p1[2]=2 p2[2]=2.000000
    // p1[3]=3 p2[3]=3.000000
    // p1[4]=4 p2[4]=4.000000

    // メモリ開放
    free(p1);
    free(p2);

    for (i=0; i<SIZE; i++) {
        printf("p1[%d]=%d p2[%d]=%lf\n", i, p1[i], i, p2[i]);
    }
    // メモリを開放したので、意味のわからない値になる。
    // p1[0]=0 p2[0]=0.000000
    // p1[1]=0 p2[1]=0.000000
    // p1[2]=-1476812784 p2[2]=2.000000
    // p1[3]=21892 p2[3]=3.000000
    // p1[4]=4 p2[4]=4.000000

    return 0;
}