質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

1回答

2501閲覧

関数名(char **配列名A[添字]) の関数内で、配列名A[添字][添字]を使うにはどうすればいいのでしょうか。

norm

総合スコア21

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

1クリップ

投稿2016/02/16 12:33

編集2016/02/17 04:40

はじめまして。どうぞよろしくお願いいたします。
C言語を学習中の者ですが、質問があります。

コードは平成24年秋季 基本情報技術者の午後にあるC言語問題なのですが、
そのプログラムの動きをVisualStudioExpressで再現しようとした際に、タイトルの疑問に当りました。
https://www.jitec.ipa.go.jp/1_04hanni_sukiru/mondai_kaitou_2012h24_2/2012h24a_fe_pm_qs.pdf

問題内に、以下の関数があります。
void check_winning_lot(char *lots[],char **win_list[LOT_GNUM],int winner[LOT_GNUM]) {
int i, j, k;

for (i = 0; i < LOT_GNUM; i++) { winner[i] = 0; for (j = 0; lots[j] != NULL; j++) { for (k = 0; win_list[i][k] != NULL; k++) { winner[i] += check_lot(lots[j], win_list[i][k]); } } }

}

この関数内で win_list[i][k] が使われている為、win_list[][] の形になるような配列を自作したシンプルなmain関数から投げて試しているのですが、上手く受取ってくれません。

check_winning_lot(char *win_list[6]){
printf("win_list[0][0] = %s \n", win_list[0][0]); /
エラーで読み込めない */
printf("win_list[1][0] = %s \n", win_list[1][0]);
printf("win_list[1][1] = %s \n", win_list[1][1]);
}

void main(){
char *list1[2] = { "123456", };
char *list2[3] = { "102030", "987654" };
char **win_list[6][4];

/* 間違いがありましたので修正しました 2/17 */ win_list[0][0] = &list1[0]; win_list[1][0] = &list2[0]; win_list[1][1] = &list2[1]; check_winning_lot(win_list);

}

そもそも、問題文の関数が受け取れるのはchar **win_list[LOT_GNUM]の形になっており、添字の数が足りてないように見えました。
ポインタが2つ指定されていることはそれに関係あるのかもしれないという気はするのですが、どう考えて組んでいけばいいのか分かりませんでした。

ご回答のほど、よろしくお願いいたします。

2/17 kozuchiさんご指摘により以前のコードを修正しました。plistはこちらで実験をしていた時の配列名でしたのでwin_listに変更しました。
list1とlist2は受取り先の**win_listがポインタを2つ使用していたため、
ポインタのポインタを指摘するよう、一度list1とlist2でポインタの文字列を作成した後に、**win_listの配列へそれらを入れたイメージです。

また、Chironianさんの回答を参考にして、自作した方の関数を修正し、受取った先での関数が動作することを確認することができました。

#include <stdio.h>

check_winning_lot(char **win_list[]){
printf("win_list[0][0] = %s \n", win_list[0][0]);
printf("win_list[1][0] = %s \n", win_list[1][0]);
printf("win_list[1][1] = %s \n", win_list[1][1]);
}

void main(){
char *list1[] = { "123456", NULL };
char *list2[] = { "102030", "987654" , NULL };
char **win_list[] = { list1, list2 };

check_winning_lot(win_list);

}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kozuchi

2016/02/16 13:17 編集

plist はどこでどう宣言されていますか?そして、どう使われますか?list1,list2 は何に使いますか?
norm

2016/02/17 04:42

plistとlist1,list2について修正などいたしました。
guest

回答1

0

ベストアンサー

こんにちは。

すいません。問題見てきました。大外れでしたので、全面的に回答を変更させて下さい。(古い回答は忘れて欲しい...)

char *は良く文字列へのポインタで使われます。問題文でも文字列へのポインタとして使われてますね。
次に、型*は、「型」へのポインタ、もしくは、「型」の配列として使われます。「型」へのポインタはC言語の仕様から「型」の配列へのポインタとしても使えます。問題文より「型」の配列へのポインタですね。
つまり、「「文字列へのポインタ=char*」の配列へのポインタ=char* *」の配列=char* * []になってます。

構造は問題文に記載されているので、具体的な定義方法を記述してみます。
(コンパイル確認してないので、エラーがでたらごめんなさい。)

C

1char* win1[]={"223692", NULL}; 2char* win2[]={"141421", "314159", NULL}; 3 : 4char* win6[]={"03", "92", NULL}; 5char **win_list[LOT_GNUM]={win1, win2, ..., win6};

win1はchar*の配列です。そして「型」の配列は「型*」でもありますね。 従って、win1はchar* *でもあるので、win_list[0]へ設定できるのです。

なかなか歯ごたえが有る問題でした。orz

投稿2016/02/16 12:41

編集2016/02/16 15:42
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

norm

2016/02/17 04:51

ありがとうございます。無事に動作を確認することができました! また、実引数と仮引数の型と配列を宣言時にしっかり揃えておくことが必要だとも気づきました。 そのあたりが自分の中で曖昧だったために、なかなか上手くいかなかったのだと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問