• ベストアンサー

C言語でのコンパイルエラー

初心者です。 非常に基本的な質問かもしれませんが、 ご回答いただけたらうれしいです。 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]を 他の関数の引数とする場合は どうすればよろしいのでしょうか? 宜しくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.2

ポインタ参照と配列参照を混同しているから、エラーの原因が理解出来ないのだと思います。 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次元配列だろうが、次元数が幾つであっても、配列名のみを書いた時は、「配列要素へのポインタ」つまり「<データ型> *」になると言う事を忘れないで下さい。

win0000
質問者

お礼

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

その他の回答 (2)

  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.3

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

  • ranx
  • ベストアンサー率24% (357/1463)
回答No.1

void test2(unsigned char data[6][6]) または void test2(unsigned char (*data)[6]) として下さい。

win0000
質問者

お礼

ありがとうございます

関連するQ&A