ぷるぷるの雑記

低レイヤーがんばるぞいなブログ. 記事のご利用は自己責任で.

C言語で多次元配列をポインタで扱う

多次元配列をポインタで扱う方法です.

多次元配列は結局のところ一次元配列と同じようにメモリが確保されています. 例えば、char型の2次元配列とchar型へのポインタについて、次のことが言えます

2次元配列とポインタの関係

実用上は次のようにキャストしてあげるとベターです.

#include<stdio.h>

#define NUM_X (10)
#define NUM_Y (20)

void func(char* ptr);

int main()
{
    char map[NUM_Y][NUM_X];
    for(int y=0;y<NUM_Y;y++){
        for(int x=0;x<NUM_X;++x){
            map[y][x]= y>x?'a':'b';
        }
    }

    char* ptr;
    ptr = (char*)map;   // キャストしないとwarningが出る

    func(ptr);

    return 0;
}

void func(char* ptr){

    for(int y=0;y<NUM_Y;y++){
        for(int x=0;x<NUM_X;++x){
            printf("%c",*(ptr + y*NUM_X + x));
        }
        printf("\n");
    }

}


ちなみに、ある処理系でのキャストしないと表示されるwarningは次の通りです.

warning: assignment to ‘char *’ from incompatible pointer type ‘char (*)[10]’  -Wincompatible-pointer-types]

C言語は配列名とポインタを区別できないと言われますが、それはコール先の関数内での話で、配列を定義したスコープ内ではちゃんと配列の型を認識しています. 今回の場合は要素が10個あるchar型の配列へのポインタであるとコンパイラが認識しているため、単なるchar型へのポインタptrに代入しようとするとwarningが生じるわけです. 動作には問題ないですが、キャストしてあげるのがお作法な気がします.


最後に、3次元配列の時は次のことが言えます. 4次元以上の配列も同じようにポインタで扱うことが出来ます.

3次元配列とポインタの関係