C言語関係掲示板

過去ログ

No830 関数に大きさが可変の2次元配列を渡す

[戻る] [ホームページ]
No.10474

関数に配列を渡すときどうすればいいのでしょうか?
投稿者---南風(2003/11/13 16:46:46)


たとえばモノクロBitmapを読み込む関数で

#define XSIZE 512
#define YSIZE 512

unsigned char Header[1078],Image[YSIZE][XSIZE];

void IMAGE_READ (unsigned char IMAGE[YSIZE][XSIZE],char *FILENAME)
{
        int xa,ya;
        unsigned char buffer[YSIZE][XSIZE];
        FILE *fp;

        if((fp=fopen(FILENAME,"rb")) == NULL){
                printf("Image Read Error. [%s] \n",FILENAME); exit(1);
        }else{
                fread(Header,1,1078,fp); fread(buffer,YSIZE,XSIZE,fp);
                fclose(fp);
        }

        for(ya=0; ya<YSIZE; ya++){
                for(xa=0; xa<XSIZE; xa++){
                     IMAGE[ya][xa] = buffer[YSIZE-1 - ya][xa];
                }
        }
}

ていうのを使っていますが,Bitmapのサイズを色々読み込みたいのですが
関数をどのようにかえればいいのでしょうか?


No.10476

Re:関数に配列を渡すときどうすればいいのでしょうか?
投稿者---たか(2003/11/13 17:36:12)


>Bitmapのサイズを色々読み込みたいのですが
>関数をどのようにかえればいいのでしょうか?


void IMAGE_READ (unsigned char IMAGE[YSIZE][XSIZE],char *FILENAME);

とYSIZE、XSIZEが固定になっているのを可変にしたいのですね。

そうしたら、配列を動的にこの関数の外側で確保し、それを渡せばいいと
思います。

xもyも可変の例をここでは扱います。xだけ固定なら別の方法があります。

  unsigned char **IMAGE;
  int x, y, i, j;
  
  x = 1024; y = 512; /* 例えば */

  if ((IMAGE = (unsigned char **)malloc(sizeof(unsigned char) * y)) == NULL) exit(1);
  for (i = 0; i < y; i++)
    if ((IMAGE[i] = (unsigned char *)malloc(sizeof(unsigned char) * x)) == NULL) exit(1);
  
  IMAGE_READ(IMAGE, y, x, char *FILENAME);

  
  for (i = 0; i < x; i++) free(IMAGE[i]);
  free(IMAGE);


No.10478

Re:関数に配列を渡すときどうすればいいのでしょうか?
投稿者---たか(2003/11/13 17:39:44)


おっとっと、関数IMAGE_READ()のプロトタイプ宣言が変わります。

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

void IMAGE_READ(unsigned char **IMAGE, int y, int x, char *FILENAME);

int main(void)
{
  unsigned char **IMAGE;
  int x, y, i;
  char *FILENAME = "abc.bmp";
  
  x = 1024; y = 512; /* 例えば */

  if ((IMAGE = (unsigned char **)malloc(sizeof(unsigned char) * y)) == NULL) exit(1);
  for (i = 0; i < y; i++)
    if ((IMAGE[i] = (unsigned char *)malloc(sizeof(unsigned char) * x)) == NULL) exit(1);
  
  IMAGE_READ(IMAGE, y, x, FILENAME);
  
  for (i = 0; i < x; i++) free(IMAGE[i]);
  free(IMAGE);
  
  return 0;
}


No.10477

Re:関数に配列を渡すときどうすればいいのでしょうか?
投稿者---YuO(2003/11/13 17:37:36)


> ていうのを使っていますが,Bitmapのサイズを色々読み込みたいのですが
> 関数をどのようにかえればいいのでしょうか?

標準Cによると,
void image_read (int xsize, int ysize, unsigned char image[ysize][xsize], const char * filename)
{
/* ... */
}

でできることになっています。

ただし,C99をサポートしていないコンパイラではこれはできないので,
void image_read (int xsize, int ysize, unsigned char ** image, const char * filename)
{
/* ... */
}

となります。

bufferも,
unsigned char ** buffer;

と宣言して,
int i;
buffer = malloc(ysize * sizeof(unsigned char *));
if (!buffer) abort(1); /* 異常終了処理 */
buffer[0] = malloc(xsize * ysize);
if (!buffer[0]) abort(1); /* 異常終了処理 */
for (i = 1; i < ysize; ++i) {
    buffer[i] = buffer[i - 1] + xsize;
}

とやる必要があります。
#要解放処理。

さらに,呼び出し側も
unsigned char image[100][100];

のようなものは渡せず,先ほどと同じようなルーチンで記憶領域を確保してやる必要があります。


個人的には,読み込むときにメモリも確保する形,即ち
unsigned char ** image_read (int * xsize, int * ysize, const char * filename)
{
/* ... */
}

という形の方が使い勝手がよい気がします。