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

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

ただいまの
回答率

90.48%

  • C

    3830questions

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

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

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 1,138

Teppay

score 173

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

void show(int **A){
    int i,j;
    for(i=0;i<5;i++){
        for(j=0;j<5;j++){
            printf("%d ",A[i][j]);/*←ここ*/
        }
        printf("\n");
    }
}

int main(void){
    int A[5][5] = {0};
    int i;
    int *pA[5];

    for(i=0;i<5;i++) pA[i] = A[i];

    show(pA);

    return 0;
}

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

あと、二次元配列を関数に渡す方法でいいものがあれば教えてください。
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+3

void show(int A[][5]){
    int i,j;
    for(i=0;i<5;i++){
        for(j=0;j<5;j++){
            printf("%d ",A[i][j]);/*←ここ*/
        }
        printf("\n");
    }
}

int main(void){
    int A[5][5] = {0};
    show(A);
    return 0;
}

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/07/10 10:31

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

    キャンセル

checkベストアンサー

+1

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 11:16

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

    キャンセル

  • 2015/07/17 19: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 は知らない★ですよね。
    定数を使用するか、別の引数としてサイズも渡すかするほうが安全です。

    キャンセル

-2

>なぜ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言語の一番カギになる部分の一つです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.48%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    C言語 スレッドについて

    ご質問いたします。 C言語でスレッドを使用して入力した文字列を10秒毎にそのまま表示か、逆から表示かを切り替えるプログラムを下記条件の元、作成したいのですがスレッドの使い方が解り

  • 解決済

    1からNまでの二乗和を求める

    1からNまでの二乗和を求めるプログラムを作れ、という課題をやっているのですが、完成したと思いコンパイルし実行してみると、=0 という答えが返ってきました。 コンパイルした時、警

  • 解決済

    素数判定[C言語]

    ある整数を与えて、素数かどうか判定するというプログラムを作ったのですが、コンパイル出来て実行してみたところ、プログラムが停止してしまいました。 ミスの場所を教えてください。解説もあ

  • 解決済

    文字を出力する関数の改行

    入力nの数の分だけ文字を出力する関数があったとして、それを複数のnについて出力するとき、nの値が異なるごとに改行するにはどうしたらいいのでしょうか?コードvoid print_a(

  • 受付中

    点数別分布グラフ

    点数分布のグラフですが、少し長いように感じました。もう少し短くすることはできますか? またこのコードに対して何かご意見がありましたらお願いします。 #inc

  • 解決済

    これは何故エラーになるのでしょうか?

    int *h = {1, 2, 3, 4, 5, 6};     printf("%d", *(h));          int h_2[] = {1, 2, 3, 4, 5, 

  • 解決済

    【C言語】スタックをリストで実現するプログラム

    毎度お世話になっております。 高橋麻奈さんの「やさしいC アルゴリズム」をみて勉強しているのですが、リストを使ったスタックのコードで、がコンパイルエラーになってしまいました。 コ

  • 解決済

    コードを見てダメ出しや指摘などお願いします。

    #include <stdio.h> int main(void){     double a;     double b;        char o;  //演算子    

同じタグがついた質問を見る

  • C

    3830questions

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