プロが教えるわが家の防犯対策術!

初心者です。
非常に基本的な質問かもしれませんが、
ご回答いただけたらうれしいです。

void test1(unsigned char* data)
{
}

void test2(unsigned char** data)
{
}

int main(void)
{
unsigned char data1[6];
unsigned char data2[6][6];

test1(data1);
test2(data2);
}

としてtest1はうまくいくのに、
test2はコンパイルエラーになります。
どっちもポインタになると思うのですが…。

また、unsigned char data2[6][6]を
他の関数の引数とする場合は
どうすればよろしいのでしょうか?

宜しくお願いいたします。

A 回答 (3件)

ポインタ参照と配列参照を混同しているから、エラーの原因が理解出来ないのだと思います。



test1(data1);
と書いた場合、これは、
test1(&data1[0]);
と書いているのと同じです。同様に
test2(data2);
と書くと
test2(&data2[0][0]);
と同じです。

「&data2[0][0]」は「unsigned charへのポインタ(unsigned char *)」ですから、関数の宣言部の「unsigned char **」と一致せず、エラーになります。

なお、関数test2の引数「unsigned char **data」は、unsigned charのポインタへのポインタですので、unsigned charの2次元配列であるdata2は受け取れません。

unsigned charの2次元配列であるdata2を引数に渡す場合は、受け取り関数の引数をunsigned char *にして、関数内で配列要素にアクセスする場合は、自分で要素番号を計算する必要があります。

void test2(unsigned char *data)
{
  unsigned char c;
  c = data[3 * 6 + 1]; /* data2[3][1]にアクセス */
}

void main(void)
{
  unsigned char data2[6][6];
  test2(data2);
}

1次元配列だろうが2次元配列だろうが3次元配列だろうが、次元数が幾つであっても、配列名のみを書いた時は、「配列要素へのポインタ」つまり「<データ型> *」になると言う事を忘れないで下さい。
    • good
    • 0
この回答へのお礼

ご親切な説明。
非常に解りやすかったです。
意味もわかりました。
ありがとうございました。

お礼日時:2004/11/30 17:18

#2です。



補足です。

最近のCでは#1の回答の書き方も可ですが「古典的なCコンパイラ」では、この書き方を許さない場合があります。なので、#2の回答では「処理系に依存しない、殆どすべてのCコンパイラで許されている書き方」にしています。

まあ、たいていのCコンパイラで#1の回答の書き方で大丈夫だと思いますが。
    • good
    • 0

void test2(unsigned char data[6][6])


または
void test2(unsigned char (*data)[6])
として下さい。
    • good
    • 0
この回答へのお礼

ありがとうございます

お礼日時:2004/11/30 17:17

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!