電子書籍の厳選無料作品が豊富!

二次元配列による文字列の配列の受渡しについての質問です。

#include <stdio.h>

void print_pname(char str[][5], int n)
{
int i, j;
for (i = 0; i < n; i++)
{
printf("str[%d] = \"", i);
for (j = 0; str[i][j] != '\0'; j++)
putchar(str[i][j]);
printf("\"\n");
}
}

int main(void)
{
char ary[][5] = {"Lisp", "C", "Ada"};

print_pname(ary, sizeof(ary) / sizeof(ary[0]));
return 0;
}

上のプログラム中の関数print_pnameの引数char str[][5]についてですが
char (*str)[5](配列のポインタ)と変更した場合にwarningが多数発生します。
これはどうしてでしょうか?
また、上のプログラムを配列のポインタを使って変更することは可能でしょうか?

以上、よろしくお願いします。

A 回答 (8件)

いや, 確かにそこはおかしいけど (注: どっちにしても未定義動作ですがそこはスルーしてた), while の条件が変です>#6. このまままわると *ary[3] を参照しちゃいます.


で本題に戻ると,
char (*ary)[5] = {"Lisp", "C", "Ada"};
は ary を「『大きさ 5 の配列』へのポインタ」として定義しています. ポインタはスカラーですから, このように複数の値を使って初期化することはできません.
なお, GCC (や ISO C に従っている処理系) なら
char (*ary)[5] = (char [][5]){"Lisp", "C", "Ada"};
で初期化できるかもしれません. でも, そのあとがどうせダメか.
    • good
    • 0
この回答へのお礼

Tacosanさん、回答有難うございます。

なんとなくですが理解できました。
まだまだ修行が足りないということです。
どうもすみませんでした。

お礼日時:2010/01/25 16:33

ああそうそう, #7 では言い忘れてたけど, これは「print_pname の引数を char str[][5] から char

(*str)[5] に変えたことによっておきる」警告ではありません. 行番号を見ればわかるけど, 警告が出てるのはそこじゃないよね.

この回答への補足

警告は30行目の
char (*ary)[5] = {"Lisp", "C", "Ada"};

の部分だけです。

補足日時:2010/01/25 16:38
    • good
    • 0

失礼 m(_ _)m >#5さん


右から左に実行してるんですよね。


printf("str[%d]= \"%s\"\n", i, ary[i++]);

  ↓↓↓ 訂正 ↓↓↓

printf("str[%d]= \"%s\"\n", i++, ary[i]);

この回答への補足

返事が遅くなり申し訳ありませんでした。
質問内容に不備がありました。

補足日時:2010/01/25 11:01
    • good
    • 0

while がおかしいですよ~>#4.

この回答への補足

返事が遅くなり申し訳ありませんでした。
質問内容に間違いがあり、
みなさんにご迷惑をおかけしました。
すいませんでした。

補足日時:2010/01/25 10:59
    • good
    • 0

当方、Mac OSX の gcc コンパイラです。

正常にwarningを発することなく動いています。


#include <stdio.h>

void print_pname(char (*str)[5], int n) {
int i, j;
for (i = 0; i < n; i++) {
printf("str[%d] = \"", i);
for (j = 0; str[i][j] != '\0'; j++)
putchar(str[i][j]);
printf("\"\n");
}
}

int main(void) {
char ary[][5] = {"Lisp", "C", "Ada"};
print_pname(ary, sizeof(ary) / sizeof(ary[0]));
return 0;
}


そんなことより、たかが文字列配列内容を表示するのに
  str[1]= "Lisp"
  str[2]= "C"
  str[3]= "Ada"
なぜ静的配列あるいはグローバル配列として簡単に表示する方法を採用されないのですか?


#include <stdio.h>

int main(void) {
static char ary[][5] = {"Lisp", "C", "Ada"};
int i = 0;
while (*ary[i])
printf("str[%d]= \"%s\"\n", i, ary[i++]);
return 0;
}

この回答への補足

返事が遅くなり申し訳ありませんでした。
質問内容が不適当でした。
申し訳ありませんでした。

補足日時:2010/01/25 10:57
    • good
    • 0

Tacosanさんの回答のとおり、


ソースコードとエラーメッセージとが
対応していなければ、投稿している意味がありません。

この回答への補足

返事が遅くなり申し訳ありませんでした。
こちらに不手際がありました。

補足日時:2010/01/25 10:56
    • good
    • 0

その警告だと, List5_2x.c って名前のソースの 30行目が怪しいっていってるね.


30行目って, どこ?

この回答への補足

返事が大変遅くなり申し訳ありませんでした。

List5_2x.c のソースコード30行目は
char ary[][5] = {"Lisp", "C", "Ada"};
になります。

他の方が指摘されているように、このコードだと
warningなくコンパイル出来ていました。

私の質問内容が不適当でした。

<元のコード>
#include <stdio.h>


void print_pname(char str[][5], int n)
{
int i, j;

for (i = 0; i < n; i++)
{
printf("str[%d] = \"", i);
for (j = 0; str[i][j] != '\0'; j++)
putchar(str[i][j]);
printf("\"\n");
}
}

int main(void)
{
char ary[][5] = {"Lisp", "C", "Ada"};

print_pname(ary, sizeof(ary) / sizeof(ary[0]));

return 0;
}

<変更後のコード>
#include <stdio.h>


void print_pname(char (*str)[5], int n)
{
int i, j;

for (i = 0; i < n; i++)
{
printf("str[%d] = \"", i);
for (j = 0; str[i][j] != '\0'; j++)
putchar(str[i][j]);
printf("\"\n");
}
}

int main(void)
{
char (*ary)[5] = {"Lisp", "C", "Ada"};

print_pname(ary, sizeof(ary) / sizeof(ary[0]));

return 0;
}

元のコードから変更後のコードに変更するとwarningが発生するということでした。

みなさん、申し訳ありませんでした。

補足日時:2010/01/25 10:54
    • good
    • 0

どのようなコンパイラで, どのような警告が出るんでしょうか?

この回答への補足

回答有難うございます。
コンパイラはgccです。
warningの内容は以下の通りです。

List5_2x.c: In function `main':
List5_2x.c:30: warning: initialization from incompatible pointer type
List5_2x.c:30: warning: excess elements in scalar initializer
List5_2x.c:30: warning: (near initialization for `ary')
List5_2x.c:30: warning: excess elements in scalar initializer
List5_2x.c:30: warning: (near initialization for `ary')

以上です。

補足日時:2010/01/22 18:26
    • good
    • 0

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