掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.27954

夏休み宿題
投稿者---るぅ(2006/08/17 16:20:39)


前のが書き込み量多くなって他のが見づらくなりそうなので、もう1つ作らせてもらいました。

引き続き、アドバイスをお願いしますm(_ _)m

今度は、2行3列の2次元配列の合計値を返す関数を作れというものです。
エラーは、
c:\c_prog\shw_c_07\main.c(23) : warning C4047: '関数' : 間接参照のレベルが 'const int (*)[3]' と 'int' で異なっています。
c:\c_prog\shw_c_07\main.c(23) : warning C4700: 値が割り当てられていないローカルな変数 'list' に対して参照が行われました。
の二つが出てしまいました(^^;)
下のは上のせいで出ているのだと思うのですが(^^;)
ソースは以下の通りです。

#include<stdio.h>


/*--------------------------------------------------------
    プロトタイプ宣言
--------------------------------------------------------*/
int array_total( const int list[ 2 ][ 3 ] );


/*--------------------------------------------------------
    main関数
--------------------------------------------------------*/
int main( void )
{
    int list[ 2 ][ 3 ] =            /* 元配列 */
    {
        { 10, 20, 30 },
        { 40, 50, 60 }
    };
    int total;              /* 合計 */


    total = array_total( list[ 2 ][ 3 ] );
    printf( "%d\n", total );


    return 0;
}


/*--------------------------------------------------------
[内容]
    2行3列の二次元配列の合計値を返す。
    なお、int型専用とする
[仮引数]
    const int list[ 2 ][ 3 ]        :2行3列の二次元配列
[戻り値]
    合計値
--------------------------------------------------------*/
int array_total( const int list[ 2 ][ 3 ] )
{
    int i, j;         /* ループカウンタ */
    int total = 0;    /* 合計 */


    for( i = 0; i < 2; i++ ){
        for( j = 0; j < 3; j++ ){
            total += list[ i ][ j ];
        }
    }

    return total;
}
よろしくお願いします。


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:夏休み宿題 27955 near 2006/08/17 16:47:50
<子記事> Re:夏休み宿題 27961 るぅ 2006/08/18 14:50:19


No.27955

Re:夏休み宿題
投稿者---near(2006/08/17 16:47:50)


題名は具体的に書いてください。
このサイトの9,10章を読んでから、わからない所を質問してください。
すぐ掲示板に頼っていては力はつきませんよ。


この投稿にコメントする

削除パスワード

No.27956

Re:夏休み宿題
投稿者---るぅ(2006/08/17 17:19:13)


>このサイトの9,10章を読んでから、わからない所を質問してください。
11章の多次元配列を関数に渡す方法を見たら分かりました(^^;)
すみませんでした。
main関数から渡す時に
array_total( list[ 2 ][ 3 ] )
になっていたのが悪かったのですね(^^;)
正しくは、
array_total( list )
でした。

>すぐ掲示板に頼っていては力はつきませんよ。
そうですね。すみません。


この投稿にコメントする

削除パスワード

No.27961

Re:夏休み宿題
投稿者---るぅ(2006/08/18 14:50:19)


変数(p_list)で配列(list)の先頭ポインタを受け取り、h行w列の配列の合計値を戻り値で返すという関数で、
list[ 0 ][ 0 ]のポインタをを受け取って、list[ 0 ][ 1 ]にずらしたい場合はどのようにしたらよいですか?
自分が考えた間違ったソースは以下の通りです。
ソース中の配列の10から20にしたいです。

#include<stdio.h>


/*--------------------------------------------------------
    マクロ定義
--------------------------------------------------------*/
#define LINE1    2   /* 行 */
#define LINE2   3  /* 列 */

/*--------------------------------------------------------
    構造体・共用体
--------------------------------------------------------*/


/*--------------------------------------------------------
    グローバル変数
--------------------------------------------------------*/


/*--------------------------------------------------------
    プロトタイプ宣言
--------------------------------------------------------*/
int array_p_total( const int * p_list, int h, int w );


/*--------------------------------------------------------
    main関数
--------------------------------------------------------*/
int main( void )
{
    int list[ LINE1 ][ LINE2 ] = 
    {
        { 10, 20, 30 },
        { 40, 50, 60 }
    };

    printf( "%d\n", array_p_total( (const int*)list, LINE1, LINE2 ) );


    return 0;
}


/*--------------------------------------------------------
[内容]
    p_listで配列の先頭ポインタを受け取り、h行w列の配列の合計値を戻り値で返す
[仮引数]
    const int* p_list      :二次元配列の先頭ポインタ    注意:実引数にキャスト(const int*)が必要
    int h               :行
    int w               :列
[戻り値]
    合計値
--------------------------------------------------------*/
int array_p_total( const int * p_list, int h, int w )
{
    int total = 0;    /* 合計 */
    int i, j;         /* ループカウンタ */


    for( i = 0; i <= h; i++ ){
        for( j = 0; j <= w; j++ ){
            total += p_list[ i ][ j ];    /* p_listが変数なのを忘れて添字をつけてしまいました(^^;) */
        }
    }



}



この投稿にコメントする

削除パスワード

No.27962

題名は適切なものにしてください。
投稿者---Blue(2006/08/18 15:06:48)


11−2.関数間のデータ授受の方法
http://www9.plala.or.jp/sgwr-t/c/sec11-2.html


この投稿にコメントする

削除パスワード

No.27963

2次元配列を関数の引数に指定するには
投稿者---Blue(2006/08/18 15:15:09)


最初のコードを主体にすると

#include <stdio.h>

void show( const int* ary, const int row,  const int col )
{
    int i, j;

    for ( i = 0; i < row; i++ )
    {
        for ( j = 0; j < col; j++ )
        {
            printf( "( %d, %d ) : %d\n", i, j, *( ary + ( i * col ) + j ) );
        }
    }
}

int main( void )
{
    int ary[ 2 ][ 2 ] = { { 1, 2 }, { 3, 4 } };
    show( &ary[ 0 ][ 0 ], 2, 2 );

    return 0;
}


てな感じ。


この投稿にコメントする

削除パスワード

No.27967

いわゆる2次元配列を扱う例
投稿者---ruby(2006/08/18 16:01:43)


こういった例もあります。

#include <stdio.h>

#define ROW (2)
#define COL (3)

void show_array(const int (*p_list)[COL], int h, int w);

int main(void)
{
    int list[ROW][COL] = {
        { 10, 20, 30 },
        { 40, 50, 60 },
    };
    
    show_array(list, ROW, COL);
    return 0;
}

void show_array(const int (*p_list)[COL], int h, int w)
{
    int i, j;
    
    for (i = 0; i < h; i++) {
        for (j = 0; j < w; j++) {
            printf("[%d][%d] = %d\n", i, j, p_list[i][j]);
        }
    }
}



この投稿にコメントする

削除パスワード

No.27969

Re:いわゆる2次元配列を扱う例
投稿者---るぅ(2006/08/18 19:43:47)


>題名は適切なものにしてください。
すみません。変え忘れてました。

>11−2.関数間のデータ授受の方法
2次元配列の先頭ポインタを渡す場合、2次元配列で受け取らなければならないと書いてあるのですが変数で受け取らなくてはいけません(^^;)

Blueさんのソースを見てもrubyさんのソースを見ても、なぜこれで配列の次の値が読み込めるのか分かりません。
どこが重要なところですか?


この投稿にコメントする

削除パスワード

No.27970

Re:いわゆる2次元配列を扱う例
投稿者---ruby(2006/08/18 21:05:41)


>2次元配列の先頭ポインタを渡す場合、2次元配列で受け取らなければならないと書いてあるのですが変数で受け取らなくてはいけません(^^;)

意味がつかめません。
いわゆる2次元配列で受け取っているのですから、
ちゃんと変数で受け取っているではないですか。

>Blueさんのソースを見てもrubyさんのソースを見ても、なぜこれで配列の次の値が読み込めるのか分かりません。

次のサンプルソースを実行してみてください。
それと下図とを見比べて、中身を吟味してください。
なお、p_listは、『「要素がCOL個である配列」へのポインター』です。

#include <stdio.h>

#define ROW (2)
#define COL (3)

void show_array(const int (*p_list)[COL], int h, int w);

int main(void)
{
    int list[ROW][COL] = {
        { 10, 20, 30 },
        { 40, 50, 60 },
    };
    int i, j;
    
    for (i = 0; i < ROW; i++) {
        for (j = 0; j < COL; j++) {
            printf("list[%d][%d]のアドレス:%p\n", i, j, &list[i][j]);
        }
    }
    printf("\n");
    show_array(list, ROW, COL);
    return 0;
}

void show_array(const int (*p_list)[COL], int h, int w)
{
    int i, j;
    
    for (i = 0; i < h; i++) {
        printf("p_list[%d]の値:%p\n", i, p_list[i]);
        for (j = 0; j < w; j++) {
            printf("[%d][%d] = %d\n", i, j, p_list[i][j]);
        }
    }
}


【図】
p_list[0] ---> +------------+
               | list[0][0] |
               +------------+
               | list[0][1] |
               +------------+
               | list[0][2] |
p_list[1] ---> +------------+
               | list[1][0] |
               +------------+
               | list[1][1] |
               +------------+
               | list[1][2] |
               +------------+




この投稿にコメントする

削除パスワード

No.27971

Re:いわゆる2次元配列を扱う例
投稿者---ruby(2006/08/18 21:54:06)


せっかくですから、Blueさんのサンプルの分も反映させましょう。
#include <stdio.h>

#define ROW (2)
#define COL (3)

void show_array(const int (*p_list)[COL], int h, int w);
void show2_array(const int *p_list2, int h, int w);

int main(void)
{
    int list[ROW][COL] = {
        { 10, 20, 30 },
        { 40, 50, 60 },
    };
    int i, j;
    
    for (i = 0; i < ROW; i++) {
        for (j = 0; j < COL; j++) {
            printf("list[%d][%d]のアドレス:%p\n", i, j, &list[i][j]);
        }
    }
    printf("\n");
    show_array(list, ROW, COL);
    printf("\n");
    show2_array(&list[0][0], ROW, COL);
    return 0;
}

void show_array(const int (*p_list)[COL], int h, int w)
{
    int i, j;
    
    for (i = 0; i < h; i++) {
        printf("p_list[%d]の値:%p\n", i, p_list[i]);
        for (j = 0; j < w; j++) {
            printf("[%d][%d] = %d\n", i, j, p_list[i][j]);
        }
    }
}

void show2_array(const int *p_list2, int h, int w)
{
    int i, j;
    
    for (i = 0; i < h; i++) {
        for (j = 0; j < w; j++) {
            int k = i * COL + j;
            printf("p_list2[%d] = %d(アドレス:%p)\n",
                   k, p_list2[k], &p_list2[k]);
        }
    }
}

【図】
p_list[0] -----> +----------------+ <----- p_list2
   p_list[0][0]  | list[0][0]==10 |  p_list2[0*3+0]
                 +----------------+
   p_list[0][1]  | list[0][1]==20 |  p_list2[0*3+1]
                 +----------------+
   p_list[0][2]  | list[0][2]==30 |  p_list2[0*3+2]
p_list[1] -----> +----------------+
   p_list[1][0]  | list[1][0]==40 |  p_list2[1*3+0]
                 +----------------+
   p_list[1][1]  | list[1][1]==50 |  p_list2[1*3+1]
                 +----------------+
   p_list[1][2]  | list[1][2]==60 |  p_list2[1*3+2]
                 +----------------+




この投稿にコメントする

削除パスワード

No.27972

Re:いわゆる2次元配列を扱う例
投稿者---Blue(2006/08/18 21:56:57)


ポイントは2次元配列だろうが、メモリ上は連続しているというところでしょうか。

サンプル)
#include <stdio.h>

int main( void )
{
    int ary[ 2 ][ 3 ] = { { 1, 2, 3 }, { 4, 5, 6 } };
    int i, j;
    int* p = &ary[ 0 ][ 0 ];

    ary[ 0 ][ 3 ] = -1; /* ary[ 1 ][ 0 ] = -1; と同じ */

    for ( i = 0; i < 2; i++ )
    {
        for ( j = 0; j < 3; j++ )
        {
            printf( "ary[ %d ][ %d ] : %p : %d\n", i, j, ( void* )&ary[ i ][ j ], ary[ i ][ j ] );
        }
    }

    puts( "\n" );

    for ( i = 0; i < 2 * 3; i++ )
    {
        printf( "*( p + %d ) : %p : %d\n", i, ( void* )( p + i ), *( p + i ) );
    }

    return 0;
}



この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧