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

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

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

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

Q&A

解決済

3回答

18491閲覧

二次元配列を関数に引き渡して、内部で各要素を参照したい

akamakku

総合スコア191

C

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

0グッド

1クリップ

投稿2015/07/10 00:31

Google先生にお伺いを立てたところ、
2次元配列の各要素(配列)の先頭アドレスを格納した配列を用意し、
その配列の先頭アドレスを関数に渡すことで実現できるらしいのですが。

lang

1void show(int **A){ 2 int i,j; 3 for(i=0;i<5;i++){ 4 for(j=0;j<5;j++){ 5 printf("%d ",A[i][j]);/*←ここ*/ 6 } 7 printf("\n"); 8 } 9} 10 11int main(void){ 12 int A[5][5] = {0}; 13 int i; 14 int *pA[5]; 15 16 for(i=0;i<5;i++) pA[i] = A[i]; 17 18 show(pA); 19 20 return 0; 21}

5行目の部分がいまいちピンときません。
なぜA[i][j]の形で要素を参照できるんでしょう。

あと、二次元配列を関数に渡す方法でいいものがあれば教えてください。

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

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

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

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

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

guest

回答3

0

lang

1void show(int A[][5]){ 2 int i,j; 3 for(i=0;i<5;i++){ 4 for(j=0;j<5;j++){ 5 printf("%d ",A[i][j]);/*←ここ*/ 6 } 7 printf("\n"); 8 } 9} 10 11int main(void){ 12 int A[5][5] = {0}; 13 show(A); 14 return 0; 15}

シンプルに書くならこんな感じで。

投稿2015/07/10 01:19

naga3

総合スコア1293

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

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

akamakku

2015/07/10 01:31

ふつーにそういう感じで引数として渡せるんですね!
guest

0

ベストアンサー

main から show を呼び出すときに、2次元配列 A をそのまま渡しているのでないことに注意してください。
ポインタの配列 pA を渡していますね。

多次元配列とポインタの関係を説明するために、わざとこういう書き方をしているのだと思います。
(ただし、あまりよい説明の仕方だとは思いませんが)
通常は naga3 さんの回答にあるように書きます。

多次元配列を引数にする場合、最高次元(配列名の直後)のサイズは省略できますが、低次元のサイズは省略できません。
int A[10][5] [5] の配列が10個ある
int A[][5] [5] の配列がいくつかある
では、渡された関数の側でも処理ができますが
int A[10][] サイズのわからない配列が10個ある
int A[][] サイズのわからない配列がいくつかある
では、”どう処理していいのかわからない”ことになります。

投稿2015/07/17 02:11

mie

総合スコア229

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

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

akamakku

2015/07/17 02:16

参考書かなにかで、関数に配列を渡す際に配列の要素数は渡されないので、a[]と渡しても、a[5]と渡しても変わらないというのを読んだ気がするんです 混乱しています(笑)
mie

2015/07/17 10:19

そうですね。 >int A[10][5] __ [5] の配列が10個ある >int A[][5] ____ [5] の配列がいくつかある と書きましたが、プログラムの処理としてはどちらでも同じことになります。 下位次元の要素数[5]は渡されますが、上位の[10]は無視されちゃう感じです。 ただ、可読性(プログラムの解りやすさ)の点で、明示的に int A[10][5] とするほうがはっきりします。 もう一つ言うと、プログラムの安全性の点からは関数 show の側で for(i=0;i<5;i++){ とするのは危険です。 A[0][*] から A[4][*] まで定義されているのは、コーディングした”人”・プログラムを読んだ”人”とmain 関数は知っていますが、★関数show は知らない★ですよね。 定数を使用するか、別の引数としてサイズも渡すかするほうが安全です。
guest

0

なぜA[i][j]の形で要素を参照できるんでしょう。

int *A ならば A[i]
int **A ならば A[i][j]
int ***A ならば A[i][j][k]
int ****A ならば A[i][j][k][l]

という形で参照することができます。
これは単に便宜上配列表現でアクセスできるというだけなので
そういうものとして覚えていただいた方が良いと思います。
通常の一般的プログラム記述言語として使用する分にはそれで差支えはありません。

もしあなたがC言語をメモリイメージを操作できる言語として熟達したいのであれば
基本に立ち返り、

int *A , AA[2]
int **B , BB[3][2]
int ***C , CC[4][3][2]

と宣言された時に各々の変数の実体(intの値が格納される場所)がメモリーの
どこに配置されるのかを考えてみましょう。
もちろん *(ポインター)宣言されているものはポインター(メモリーアドレス)が
格納されている配置イメージも考える必要があります。

例えば変数配置メモリー領域が 0x4000h からとして具体的に考えるとやりやすいと思います。

ここでこの答えまで書くのは容易ですが、先ずは自分で調べて見るのも重要なことですので
頑張ってみてください。

実際この部分がC言語の一番カギになる部分の一つです。

投稿2015/07/16 06:58

Fritha

総合スコア33

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問