ページ 1 / 1
動的確保した二次元配列を引数にして計算したいのですが
Posted: 2017年7月28日(金) 02:18
by ちくわん
main関数内で動的確保し適当な数値をいれて初期化した二次元配列を引数として、別の関数内でその2次元配列をつかって色々計算をしたいんですがどういう風にプロトタイプ宣言すればいいですか?下のコードを参考にして教えてください。わかりにくい説明ですがお願いします。
コード:
#include <stdio.h>
#include <stdlib.h>
#define N 100
typedef struct rgb_t {
unsigned char r;
unsigned char g;
unsigned char b;
} rgb_t;
int tesu(rgb_t **a); //この()内がわからない
int main(void){
rgb_t **color= (rgb_t **)malloc(sizeof(rgb_t *)*N);
if (color == NULL) {
printf("Cannot allocate memory.\n");
}
for (int i = 0; i < N; i++) {
color[i] = (rgb_t *)malloc(sizeof(rgb_t )*N);
if (color == NULL) {
printf("Cannot allocate memory.\n");
}
}
//2次元配列color[N][N]にファイルから読み込んだデータを代入(省略)
tesu(color);
return 0;
}
int tesu(rgb_t **a) {
//2次元配列aをつかった適当な計算処理
return 0;
}
Re: 動的確保した二次元配列を引数にして計算したいのですが
Posted: 2017年7月28日(金) 02:24
by みけCAT
「二次元配列」の先頭へのポインタはrgb_t**型の変数に格納しているので、このポインタを渡す引数もrgb_t**型、すなわち現状のコードでいいでしょう。
オフトピック
現状のコードは、16行目で半角の=の代わりに全角の=が使われているためにコンパイルが通りません。
また、今回のようにNがグローバルで固定なら不要かもしれませんが、一般には「二次元配列」の各次元の要素数も関数に(引数として)渡さないと計算ができないかもしれません。
Re: 動的確保した二次元配列を引数にして計算したいのですが
Posted: 2017年7月28日(金) 02:42
by ちくわん
では、配列の要素数Nをグローバル宣言ではなくmain関数内でscanf()を用いて数字を入力する場合だったらどのように変更したらよろしいですか?
Re: 動的確保した二次元配列を引数にして計算したいのですが
Posted: 2017年7月28日(金) 08:41
by Math
Cでは本当は「配列を引数として渡す」ことはできません。
しかし先頭要素へのポインターを渡すことであたかも配列を渡しているように扱えます。
呼び出し側で配列の要素数を知りようがないので配列のサイズNを引数として渡します。
int tesu(rgb_t **a, int N)
(array
は *(array + i)のシンタックスシュガーにすぎないから)
シンタックスシュガーはhttp://dixq.net/forum/viewtopic.php?f=3&t=19257
など過去ログで何度もかいてます。
Re: 動的確保した二次元配列を引数にして計算したいのですが
Posted: 2017年7月28日(金) 09:32
by かずま
a[0][n-1] の次に a[1][0] が連続している本当の 2次元配列に近いものです。
free も楽です。
コード:
#include <stdio.h> // printf, putchar, puts
#include <stdlib.h> // malloc, free
typedef struct rgb_t { unsigned char r, g, b; } rgb_t;
int init(rgb_t **a, int m, int n);
int tesu(rgb_t **a, int m, int n);
int main(void)
{
int m = 3, n = 4;
rgb_t **color = (rgb_t **)malloc(sizeof(rgb_t *) * m);
if (!color) { puts("Cannot allocate memory."); return 1; }
color[0] = (rgb_t *)malloc(sizeof(rgb_t) * m * n);
if (!color[0]) { puts("Cannot allocate memory."); return 1; }
for (int i = 1; i < n; i++) color[i] = color[i-1] + n;
init(color, m, n);
tesu(color, m, n);
free(color[0]), free(color);
return 0;
}
int init(rgb_t **a, int m, int n)
{
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++) {
a[i][j].r = i*10 + j;
a[i][j].g = i*10 + j + 100;
a[i][j].b = i*10 + j + 200;
}
return 0;
}
int tesu(rgb_t **a, int m, int n)
{
for (int i = 0; i < m; i++, putchar('\n'))
for (int j = 0; j < n; j++)
printf(" [%3d,%3d,%3d]", a[i][j].r, a[i][j].g, a[i][j].b);
return 0;
}
実行結果
コード:
C:\Users\sakamoto\tmp\C>a
[ 0,100,200] [ 1,101,201] [ 2,102,202] [ 3,103,203]
[ 10,110,210] [ 11,111,211] [ 12,112,212] [ 13,113,213]
[ 20,120,220] [ 21,121,221] [ 22,122,222] [ 23,123,223]
正方行列の場合、int m は要らないでしょう。
Re: 動的確保した二次元配列を引数にして計算したいのですが
Posted: 2017年7月28日(金) 09:43
by かずま
かずま さんが書きました:a[0][n-1] の次に a[1][0] が連続している本当の 2次元配列に近いものです。
free も楽です。
コード:
for (int i = 1; i < n; i++) color[i] = color[i-1] + n;
すみません。i < n を i < m に訂正します。
コード:
for (int i = 1; i < m; i++) color[i] = color[i-1] + n;