LoginSignup
0
2

More than 3 years have passed since last update.

C言語で1次元配列を2次元風に使いたいときの#defineマクロ@追記あり

Last updated at Posted at 2019-08-06

例えばx*yのサイズの2次元配列を扱いたいが事情があって1次元配列で扱わないと行けないシーンがあるとする(例えば特定のメモリ配列方向にのみ値を入れたいがデーター構造は2次元である場合やCUDAみたいな積極的に多次元配列をサポートしていないデバイスが存在する場合など)

割と知られてる手法だと思うんですが調べても出てこなかった(調べ方が悪いだけだと思う)ので

追記

マクロ変数を括弧でくくるべきと言う話があったので訂正

test[i*x+j] = hoge(i,j)

みたいな若干めんどくさい
ならばこうしてはどうだろうか


#define test(i,j) test[(i)*x+(j)]

これならば若干記法はfortranの配列じみた書き方になり微妙ですがデーター構造の表現は2次元配列になりますね。

N次元配列とかにももちろん応用できるとは思います。

実装例としては

#define size_x 3
#define size_y 4
#define  test( i,j )  test[size_y*(i)+(j)]

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


int main (){

int  *test;

test =(int*)malloc(sizeof(int)*size_x*size_y);

for (int i=0;i < size_x;i++){
     for(int j=0;j < size_y;j++){
      test(i,j)=i*size_y+j;
    }
}

for (int i=0;i < size_x;i++){
         for(int j=0;j < size_y;j++){
        printf("%d ",test(i,j));
        }
        printf("\n");
}

free(test);


return 0;
}

output

0 1 2 3 
4 5 6 7 
8 9 10 11 

こんな感じになるのでしょうか

割と知られてる手法だと思うんですが調べても出てこなかった(調べ方が悪いだけだと思う)ので

なんでこの記事を書いたかと言うとこの書き方を毎回忘れそうになるのと今度これを使ってN次元配列で書かれたコードを全部直してあげようみたいなムーブをすることになったからです。

なんかご提案ご意見ございましたらお気軽にコメントください。

@8月22日追記
1次元配列のメモリ構造で多次元配列を実現する方法として#defineマクロを使用せずtypedefで実現する方法のほうが良いという指摘があったのでこちらも掲載します。


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

int main(void)
{
    int size_x = 3;
    int size_y = 4;
    typedef int Array[size_x][size_y];
    Array* test = malloc(sizeof(int) * size_x * size_y);

    for (int i = 0; i < size_x; i++) {
        for ( int j = 0; j < size_y; j++) {
            (*test)[i][j] = i * size_y + j;
        }
    }

    for (int i = 0; i < size_x; i++) {
        for (int j = 0; j < size_y; j++) {
            printf("%d ", (*test)[i][j]);
        }
        printf("\n");
    }

    free(test);
}
0
2
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2