0

重複の可能性:
2 次元配列へのポインターを作成する

関数 func4() および func5() を呼び出すと、次のエラーが発生します。

func4() エラー: 引数 '1' から 'int func4(short int**)' の 'short int (*)[3]' を 'short int**' に変換できません | func5() エラー: 引数 '1' から 'int func5(short int**)' の 'short int (*)[3]' を 'short int**' に変換できません |

関数 func4() および func5() を呼び出す際のエラーを修正するにはどうすればよいですか? これが私のコードです:

#include <cstdio>

int func1(short mat[][3]);
int func2(short (*mat)[3]);
int func3(short *mat);
int func4(short **mat);
int func5(short *mat[3]);

int main()
{

short mat[3][3],i,j;

for(i = 0 ; i < 3 ; i++)
    for(j = 0 ; j < 3 ; j++)
    {
        mat[i][j] = i*10 + j;
    }

printf(" Initialized data to: ");
for(i = 0 ; i < 3 ; i++)
{
    printf("\n");
    for(j = 0 ; j < 3 ; j++)
    {
        printf("%5.2d", mat[i][j]);
    }
}

printf("\n");

func1(mat);
func2(mat);
func3(&mat[0][0]);
func4(mat); //error: cannot convert ‘short int (*)[3]’ to 
            //‘short int**’ for argument ‘1’ to       ‘int func4(short int**)’|
func5(mat); //error: cannot convert ‘short int (*)[3]’ to 
            //‘short int**’ for argument ‘1’ to ‘int func5(short int**)’|

return 0;
}



/*
Method #1 (No tricks, just an array with empty first dimension)
===============================================================
You don't have to specify the first dimension!
*/

int func1(short mat[][3])
{
register short i, j;

printf(" Declare as matrix, explicitly specify second dimension: ");
for(i = 0 ; i < 3 ; i++)
{
    printf("\n");
    for(j = 0 ; j < 3 ; j++)
    {
        printf("%5.2d", mat[i][j]);
    }
}
printf("\n");

return 0;
}

/*
Method #2 (pointer to array, second dimension is explicitly specified)
======================================================================
*/

int func2(short (*mat)[3])
{
register short i, j;

printf(" Declare as pointer to column, explicitly specify 2nd dim: ");
for(i = 0 ; i < 3 ; i++)
{
    printf("\n");
    for(j = 0 ; j < 3 ; j++)
    {
        printf("%5.2d", mat[i][j]);
    }
}
printf("\n");

return 0;
}

/*
Method #3 (Using a single pointer, the array is "flattened")
============================================================
With this method you can create general-purpose routines.
The dimensions doesn't appear in any declaration, so you
can add them to the formal argument list.

The manual array indexing will probably slow down execution.
*/

int func3(short *mat)
{
register short i, j;

printf(" Declare as single-pointer, manual offset computation: ");
for(i = 0 ; i < 3 ; i++)
{
    printf("\n");
    for(j = 0 ; j < 3 ; j++)
    {
        printf("%5.2d", *(mat + 3*i + j));
    }
}
printf("\n");

return 0;
}

/*
Method #4 (double pointer, using an auxiliary array of pointers)
================================================================
With this method you can create general-purpose routines,
if you allocate "index" at run-time.

Add the dimensions to the formal argument list.
*/

int func4(short **mat)
{
short    i, j, *index[3];

for (i = 0 ; i < 3 ; i++)
    index[i] = (short *)mat + 3*i;

printf(" Declare as double-pointer, use auxiliary pointer array: ");
for(i = 0 ; i < 3 ; i++)
{
    printf("\n");
    for(j = 0 ; j < 3 ; j++)
    {
        printf("%5.2d", index[i][j]);
    }
}
printf("\n");

return 0;
}

/*
Method #5 (single pointer, using an auxiliary array of pointers)
================================================================
*/

int func5(short *mat[3])
{
short i, j, *index[3];
for (i = 0 ; i < 3 ; i++)
    index[i] = (short *)mat + 3*i;

printf(" Declare as single-pointer, use auxiliary pointer array: ");
for(i = 0 ; i < 3 ; i++)
{
    printf("\n");
    for(j = 0 ; j < 3 ; j++)
    {
        printf("%5.2d", index[i][j]);
    }
}
printf("\n");
return 0;
}
4

3 に答える 3

1

1.それらは同じです:

int func(short **mat);
int func(short *mat[]);
int func(short *mat[3]);

andshort **は と互換性がありませんshort (*)[3]。それらが指す型が異なるためです。short **を指してshort *いる間、 をshort (*)[3]指していshort[3]ます。

2.多分あなたはこれを試すことができます:

int funcMy(void *mat)   // OK! -added by Justme0 2012/12/31
{
    short i, j, *index[3];
    for (i = 0 ; i < 3 ; i++)
        index[i] = (short *)mat + 3*i;

    printf(" Declare as (void *) pointer, use auxiliary pointer array: ");
    for(i = 0 ; i < 3 ; i++)
    {
        printf("\n");
        for(j = 0 ; j < 3 ; j++)
        {
            printf("%5.2d", index[i][j]);
        }
    }
    printf("\n");
    return 0;
}

3.3番目の機能が一番いいと思います!POINTERS ON Cで読んだ「配列のフラット化」という名前のトリックを使用します。

方法 #3 (単一のポインターを使用して、配列は「フラット化」されます) ================================= ========================== この方法で汎用ルーチンを作成できます。ディメンションはどの宣言にも表示されないため、仮引数リストに追加できます。

手動の配列インデックス付けは、おそらく実行を遅くします。

于 2012-12-31T11:40:32.563 に答える
1

can't配列の を指定せずに、関数に 2 次元配列を送信しますlength or size of second dimension。これがエラーの原因です。

これを試して:

int func4(short mat[][3])
{
short    i, j, *index[3];

for (i = 0 ; i < 3 ; i++)
index[i] = (short *)mat + 3*i;

printf(" Declare as double-pointer, use auxiliary pointer array: ");
for(i = 0 ; i < 3 ; i++)
{
printf("\n");
for(j = 0 ; j < 3 ; j++)
{
    printf("%5.2d", index[i][j]);
}
}
printf("\n");

return 0;
}


int func5(short mat[][3])
{
short i, j, *index[3];
for (i = 0 ; i < 3 ; i++)
index[i] = (short *)mat + 3*i;

printf(" Declare as single-pointer, use auxiliary pointer array: ");
for(i = 0 ; i < 3 ; i++)
{
printf("\n");
for(j = 0 ; j < 3 ; j++)
{
    printf("%5.2d", index[i][j]);
}
}
printf("\n");
return 0;

}

Rememberこれは、ある方法で何かを簡単かつきれいに実行できる場合は、後でコードを修正または更新するときに混乱するため、汚い難しい方法で実行しようとしないでください.

于 2012-12-31T10:31:59.090 に答える
0

問題は、 と の行列の定義が正しくないことにfunc4()ありfunc5()ます。

として定義しますshort mat[3][3]が、この場合、実際にはポインターの配列を行列の行に割り当てません。1 つの連続したメモリ ブロックに対して 1 つのポインタを取得しています。

引数行列を として渡したい場合はshort int**、次のように定義する必要があります。

#include <stdlib.h>

short int** mat;

for(int i = 0; i < 3; i++) {
    mat[i] = (short int*)malloc (3*sizeof(short int));
    for(int j = 0; j < 3; i++) {
         mat[i][j] = i*10 + j;
    }
}
于 2012-12-31T10:21:49.473 に答える