• ベストアンサー

配列のポインタに渡す引数

2次元配列に値をつめて、char*[]に渡すための 引数XXXは、どう設定すれば、よいのでしょうか? a(work);で、問題ないのでしょうか? いまいちchar*とchar*[]の違いがよくわかりません。 void main { char work[3][5]; sprintf(work[0], %s, "abc"); sprintf(work[1], %s, "def"); sprintf(work[2], %s, "ghi"); a( XXX );←ここの引数 } int a( char* [] ){ }

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

  • ベストアンサー
回答No.3

 ポインタ変数を char *x と宣言すると、変数 x にアドレス値を保存でき、そのアドレスの記憶場所を char型の変数として使うことができます。その記憶場所は間接参照演算子*を変数名の前につけて *x で参照できます。 char **y と宣言すると、変数 y にアドレス値を保存でき、そのアドレスの記憶場所を char*型(ポインタ型)として使うことができます。 その記憶場所は *y で参照できます。*yで参照される記憶場所にアドレスが保存されていれば、そのアドレスの記憶場所をchar型として使うことができます。char型の記憶場所は **y で参照できます。  ところで、C言語では、仮引数の char* z[] は char** z と同じです。ポインタ変数 z に渡されたアドレスが指している記憶場所 *z は、char* のポインタ値(char型の記憶場所のアドレス)でなければなりません。zを配列として使うのであれば、z[0]の次の記憶場所であるz[1](*(z+1)と同じ)以降にもchar*型のポインタが保存されていなければなりません。関数の実引数はポインタの配列でなければならないことになります。  一方、2次元配列 char w[3][5] の配列名 w の型は、char** とも、char*[]ともおなじではありません。(ポインタの配列ではありません。)この2次元配列を宣言した関数の中では w を1次元配列として使うこともできます。w[0] は &w[0][0]と同じ、w[1] は &w[1][0] すなわち &w[0][0]+5 と同じです。 1次元配列として使った時の w の添字を1増やしたとき、アドレスを5だけ進めるというのは配列の宣言を見ればわかります。  ここで、2次元配列を実引数として関数 int a( char** z ) {} あるいは int a( char* z[] ) {} に渡したいとき、強引にキャストを使って a((char**)w); とすれば文法上のエラーはなくなります。ただし、関数の中でzを配列として使うことはできません。zには char*へのポインタが渡って、z[0]は文字列として使えますが、実引数は配列ではないので、配列要素 z[1] はどこにもありません。 ということで、#1を回答された方が示されたように、ポインタの配列を作ってそれを引数として渡すことになります。  #2の回答ですが、 > char *work[2]ではwork[0]とwork[1]のデータが必ずしも連続するとは限りません。 厳密にいうなら、workはポインタの配列ですから、 work[0]とwork[1]の記憶場所は連続しています。work[0]の値をたどって参照される文字列と、work[1]の値をたどって参照される文字列とは記憶場所が連続しているとは限らないということでしょう。

その他の回答 (2)

  • hashioogi
  • ベストアンサー率25% (102/404)
回答No.2

char work [n][m]とchar *work[n]ではデータのメモリ上での配置が違う場合があります。 例えば、char work[2][3] = {{'A','B','C'},{'D','E','F'}} ;はメモリ上では'A'から'F'の値が連続して並んでいますが、char *work[2]ではwork[0]とwork[1]のデータが必ずしも連続するとは限りません。 ですから、データがchar work[3][5]となっているなら、関数aの形式はint a (char w[3][5]) ;としないと、うまく渡せません。どうしても関数aの形式を変更できないなら、No.1氏のようにするしかありません。

回答No.1

#include <stdio.h> void a( char* args[] ){ printf("%s:%s:%s\n", args[0], args[1], args[2]); } int main() { char work[3][5]; char* args[3]; sprintf(work[0], "%s", "abc"); sprintf(work[1], "%s", "def"); sprintf(work[2], "%s", "ghi"); args[0] = work[0]; args[1] = work[1]; args[2] = work[2]; a( args ); return 0; }

関連するQ&A

専門家に質問してみよう