C 言語と HSP の多次元配列のメモリ上の並びについて

C言語を勉強して色々気づいたことの記事で、 C言語の多次元配列の並びが HSP のそれとは逆なのではないか、ということを書きました。それについて、詳しく調べてみました。

二次元配列の要素のメモリ上での並びを知るプログラム

このプログラムは、3x3 の二次元配列にメモリの並び順で各要素に連番の数値を代入します。そして、配列の中身を表示します。このプログラムによって、多次元配列の要素がメモリ上でどのように並んでいるかを知ります。

プログラム

HSP

#runtime "hsp3cl"
#const sizeof_int 4
dim array, 3, 3
i = 0
repeat 9
    lpoke array, i, cnt
    i += sizeof_int
loop

repeat 3
    i = cnt
    repeat 3
        j = cnt
        mes "array["+i+"]["+j+"] = " + array( i, j )
    loop
loop

C言語

#include <stdio.h>

int main( void ) {
    int array[3][3];
    int *array_p = (int *)array;
    for( int i = 0; i < ( sizeof( array ) / sizeof( array[0][0] ) ); i++ ) {
        *( array_p ++ ) = i;
    }
    
    for( int i = 0; i < 3; i++ ) {
        for( int j = 0; j < 3; j++ ) {
           printf( "array[%d][%d] = %d\n", i, j, array[i][j] );
        }
    }

    return 0;
}

実行結果

HSP

array[0][0] = 0
array[0][1] = 3
array[0][2] = 6
array[1][0] = 1
array[1][1] = 4
array[1][2] = 7
array[2][0] = 2
array[2][1] = 5
array[2][2] = 8

C言語

array[0][0] = 0
array[0][1] = 1
array[0][2] = 2
array[1][0] = 3
array[1][1] = 4
array[1][2] = 5
array[2][0] = 6
array[2][1] = 7
array[2][2] = 8

メモリ上の並び

この結果からメモリ上の並びは次のようになっていることが分かります。

HSP

  1. array[0][0]
  2. array[1][0]
  3. array[2][0]
  4. array[0][1]
  5. array[1][1]
  6. array[2][1]
  7. array[0][2]
  8. array[1][2]
  9. array[2][2]

C言語

  1. array[0][0]
  2. array[0][1]
  3. array[0][2]
  4. array[1][0]
  5. array[1][1]
  6. array[1][2]
  7. array[2][0]
  8. array[2][1]
  9. array[2][2]

カンマ区切りで配列の値を一度に複数指定した場合の挙動

カンマ区切りで、配列の値を一度に複数指定した場合、配列のどの要素に代入されるかを調べます。

HSP

dim a, 2, 2
a( 0, 0 ) = 123, 456

a[0][0] に 123 、a[1][0] に 456 が代入されます。

C言語

int a[2][2] = { 123, 456 };

a[0][0] に 123 、a[0][1] に 456 が代入されます。

実行結果から

これらは、メモリ上で並ぶように代入されていたというわけです。

三次元以上の場合

二次元配列の場合は、HSP は一次元目が、C言語は二次元目がメモリ上で連続していました。では、三次元以上の場合はどうなるのでしょうか。二次元配列でのプログラムを、三次元のものに編集して実行してみます。ただし、一次元の要素の数を 3 から 2 へ減らしています。

プログラム

HSP

#runtime "hsp3cl"
#const sizeof_int 4
dim array, 2, 2, 2
i = 0
repeat 2 * 2 * 2
    lpoke array, i, cnt
    i += sizeof_int
loop

repeat 2
    i = cnt
    repeat 2
        j = cnt
        repeat 2
            k = cnt
            mes "array["+i+"]["+j+"]["+k+"] = " + array( i, j, k )
        loop
    loop
loop

C言語

#include <stdio.h>

int main( void ) {


    int array[2][2][2];
    int *array_p = (int *)array;
    for( int i = 0; i < ( sizeof( array ) / sizeof( array[0][0][0] ) ); i++ ) {
        *( array_p ++ ) = i;
    }
    
    for( int i = 0; i < 2; i++ ) {
        for( int j = 0; j < 2; j++ ) {
            for( int k = 0; k < 2; k++ ) {
                printf( "array[%d][%d][%d] = %d\n", i, j, k, array[i][j][k] );
            }
        }
    }

    return 0;
}

実行結果

HSP

array[0][0][0] = 0
array[0][0][1] = 4
array[0][1][0] = 2
array[0][1][1] = 6
array[1][0][0] = 1
array[1][0][1] = 5
array[1][1][0] = 3
array[1][1][1] = 7

C言語

array[0][0][0] = 0
array[0][0][1] = 1
array[0][1][0] = 2
array[0][1][1] = 3
array[1][0][0] = 4
array[1][0][1] = 5
array[1][1][0] = 6
array[1][1][1] = 7

メモリ上の並び

HSP

  1. array[0][0][0]
  2. array[1][0][0]
  3. array[0][1][0]
  4. array[1][1][0]
  5. array[0][0][1]
  6. array[1][0][1]
  7. array[0][1][1]
  8. array[1][1][1]

C言語

  1. array[0][0][0]
  2. array[0][0][1]
  3. array[0][1][0]
  4. array[0][1][1]
  5. array[1][0][0]
  6. array[1][0][1]
  7. array[1][1][0]
  8. array[1][1][1]

実行結果から

説明しづらいですが、感覚としては n次元配列でHSP は「n次元目>...>2次元目>1次元目」ってな感じに並んでいて、C言語は「1次元目>2次元目>...>n次元目」のような感じに並んでいる、という感じです。

インフォメーション

公開日時
2007年8月7日 午後6時24分23秒
最終更新日時
2008年1月3日 午後10時30分40秒
カテゴリ
HSP