2012-03-26 27 views
0

私はこのトピックに関する他の回答をいくつか見てきましたが、私の問題に適合するのに十分理解していません。私は、関数に渡したいcharへのポインタの2次元配列を持っています。Cのポインターの2D配列へのポインターを渡します

配列が宣言されている場合:

(50だけで任意に選択されます)char *params[50][50];と関数のプロトタイプは次のとおりです。void test (char ***results);

私は関数を呼び出すだろうか?私が試したものは、互換性のないポインタの警告で終わる

また、関数内で配列のメンバーを参照する最も正しい方法は何ですか?それは単にですか?results[x][y];?あなたがすることはできません

おかげ

+0

ポインタの配列を割り当てる必要があります。しかし、 'test'を再設計することを検討してください。トリプルポインターは、コード臭のビットです。 –

答えて

4

は、配列へのポインタとポインタへのポインタは異なるものです。

void test (char *results[50][50]); 
void test (char *results[][50]); 
void test (char *(*results)[50]); 

は、お探しの関数と同等のプロトタイプです。

Suplement:ディメンションのためな長さを変化させてアレイ用の同じ機能を使用する場合は、関数の引数としてVLA(可変長配列)を使用する必要があるだろう:

void test (size_t n, char *results[n][n]); 
void test (size_t n, char *results[][n]); 
void test (size_t n, char *(*results)[n]); 

これだけ作品あなたがC99に準拠しているコンパイラを持っているならば。

サイズのパラメータがの前に来て、アレイがであることがわかります。

また、この機能を関数パラメータに使用するために、配列自体を可変長で宣言する必要はありません。しかし、スタックに大きな行列を割り当てないように注意しなければ、簡単にスタックオーバーフローが発生する可能性があります。

+0

だから私は配列の寸法を知っているか、代わりにダイナミックメモリの割り当てを使用する必要がありますか? – Toby

+0

@ Toby、* suplement *をご覧ください。 –

0

マイCは少しさびあるが:

char *params[][]; 

は、char *ポインタではなく、文字の2次元アレイです。あなたは、2D char配列を望んでいた場合、それは次のように定義されます

char params[valuex][valuey]; 

IITスタティックメモリ割り当て、定義スコープでのみ利用でき、私はそれはあなたが行動ではない場合、あなたは、配列を失うスコープを残す意味になります動的割り当てを試してみてください)。

あなたはその後、として関数のプロトタイプを定義することによって、関数にこの配列を渡すことができます:あなたは

char *array[N][M]; 

として配列を宣言し、それを渡すと

void foo(char param[valuex][valuey]); 

よろしく

0

機能としては、

test(array) 

次に関数プロトタイプはarr「はcharへのポインタのM要素の配列へのポインタ」型を持つ、いずれの場合のいずれか

void test(char *(*arr)[M]) 

又は

void test(char *arr[][M]) 

する必要があります。これはchar ***と同じタイプではなく、2つの間で変換するための実際には良い方法もクリーンな方法もありません。

char ***array = malloc(sizeof *array * N); 
if (array) 
{ 
    size_t i; 
    for (i = 0; i < N; i++) 
    { 
    array[i] = malloc(sizeof *array[i] * M); 
    if (array[i]) 
    { 
     size_t j; 
     for (j = 0; j < M; j++) 
     { 
     array[i][j] = some_initial_pointer_value(); 
     } 
    } 
    } 
} 

(注)この場合には、arrayの種類がchar ***であること:

あなたはdynamcallyその後、プロトタイプが正しいだろう、次のようにarrayを割り当てられて割り当てられていました。

T a[M][N]と宣言されている配列で作業していて、サイズの異なる配列を受け入れる関数を作成する場合は、Jensの示唆に基づくVLA構文を使用するか、 :

void test(char **a, size_t rows, size_t cols) 
{ 
    size_t i, j; 
    ... 
    some_pointer_value = a[i * rows + j]; 
    ... 
    a[i * rows + j] = some_pointer_value; 
} 

... 
test(&array[0][0], 50, 50); 

この場合、配列の最初の要素のアドレスと配列の次元を別々のパラメータとして明示的に渡します。 testの体内では、配列を1次元(char *a[rows * cols])として扱い、手動でオフセットを計算します。これは、連続して割り当てられた配列に対してのみ機能することに注意してください。これは、上記の配列の各行に対して断片的な割り当てを行うバージョンでは機能しません。

関連する問題