ページ 11

配列とポインタと関数の引数

Posted: 2011年6月12日(日) 20:56
by march3
今までつくってきたプログラムは、二次元配列を仮引数にそのまま渡せる仕様でしたが、
わけあって構造体のアドレス経由で渡す仕様に変更しようと思っています。
どうやればfunc1をそれほどいじらずにfunc2にように変更できますでしょうか。
func1はかなり複雑につくりこんであるため、引数と変数型宣言部分だけでごまかせる方法を探しています。
ご助力をお願いします。

コード:

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

typedef struct _hoge{
	int* array[10][10];
} Hoge;

void func1(int* array[10][10]){//仮引数であれば二次元配列に添字をつけられるため
	int* i = (int*)malloc(sizeof(int));
	*i = 1;
	array[0][0] = i;//添字で指定できる
}

void func2(Hoge* hoge){//
	//int* array[10][10] = hoge->array;//コンパイルエラー
	int*** array = (int***)hoge->array;//これだとコンパイルできるけど
	int* i = (int*)malloc(sizeof(int));
	*i = 2;
	array[0][0] = i;//セグメントエラー
}

int main(void){
	int i,j;

	Hoge* hoge = (Hoge*)malloc(sizeof(Hoge));
	func1(hoge->array);
	printf("%d\n",*(hoge->array[0][0]));//1が表示される
	func2(hoge);
	printf("%d",*(hoge->array[0][0]));//2が表示されない
	return(0);
}

Re: 配列とポインタと関数の引数

Posted: 2011年6月12日(日) 21:42
by a5ua
以下のプログラムでどうでしょう?

コード:

void func2(Hoge* hoge){
    int* (*array)[10] = hoge->array;
    int* i = (int*)malloc(sizeof(int));
    *i = 2;
    array[0][0] = i;
}
配列名は、配列の先頭要素へのポインタとなるのはいいでしょうか

hoge->arrayの型は、「int *[10][10]」です。
先頭要素の型は、「int *[10]」なので、
先頭要素へのポインタは、「int *(*)[10]」となります。
これに、変数名をつけたのが、上のプログラムです。

Re: 配列とポインタと関数の引数

Posted: 2011年6月12日(日) 22:11
by march3
なるほど。
int ***
にしてしまうと、添字によりポインタ演算ができなくなるのは
演算する単位(10ずつ足せ)の指定ができないためだと思っていたのですが、
どうやって記述すればいいのか分かりませんでした。
int* (*array)[10]
この書き方でできるんですね。
勉強になりました。