1

次の警告が表示されます。

expected ‘float **’ but argument is of type ‘float (*)[6]’

これが私のコードです:

//state and error are output parameters
void func(float* state[6], float* err[6][6]);

int main()
{
  float state[6];
  float err[6][6];

  func(&state, &err);

  return 0;
}

stateとerrをouptutパラメーターにしたいので、stateは配列へのポインターであり、errは2次元配列へのポインターである必要があります。

4

5 に答える 5

5

コードを次のように変更します。

void func(float state[], float err[][6]);

int main()
{
  float state[6];
  float err[6][6];

  func(state, err);

  return 0;
}

float* err[6][6]理由を理解するには、それがフロートへのポインターの6x6配列であり、フロートの6x6配列へのポインターではないことを知る必要があります。

于 2012-07-20T15:15:46.370 に答える
3
#include <stdio.h>

void func(float (*state)[6], float (*err)[6][6]){
    printf("%f, %f\n", (*state)[2], (*err)[1][2]);//3.000000, 3.300000
}

int main()
{
  float state[6]={1.0f,2.0f,3.0f};
  float err[6][6]={{1.0f,2.0f,3.0f},{1.1f,2.2f,3.3f}};

  func(&state, &err);

  return 0;
}
于 2012-07-20T15:37:46.407 に答える
2

ほとんどの場合、配列型の式はポインタ型の式に変換されます。つまり、配列式をパラメーターとして関数に渡すと、関数が受け取るのはポインターです。この規則の例外は、配列式が単項演算子sizeofまたは単項演算子のオペランドである場合&、または宣言で配列を初期化するために使用される文字列リテラルである場合です。

関数パラメーター宣言のコンテキストでは、は;T a[]T a[N]同じように扱われます。3つすべてが、の配列としてではなく、へのポインタとしてT *a宣言します。aTT

だから、あなたの宣言に従ってください

float state[6];
float err[6][6];

式の型stateは「6要素配列float」であり、ほとんどの場合、「ポインタからfloat」またはに変換されますfloat *。同様に、式の型errは「の6要素配列の6要素配列float」であり、「の6要素配列へのポインタfloat」またはに変換されますfloat (*)[6]

式の型は&state「、またはの6float要素配列へのポインタ」float (*)[6]であり、の型は「、または&errの6要素配列の6要素配列へのポインタ」です。 floatfloat (*)[6][6]

したがって、への呼び出しfunc

func(&state, &err);

次に、プロトタイプは

void func(float (*state)[6], float (*err)[6][6])

また、添え字を適用する前にstate、明示的に逆参照する必要があります。err

(*state)[i] = ...;
(*err)[i][j] = ...;

呼び出しが

func(state, err);

次に、プロトタイプは

void func (float *state, float (*err)[6])

また、明示的に逆参照する必要はありませstateerr

state[i] = ...;
err[i][j] = ...;

それで、あなたはどちらを使いますか?個人的には、2番目のオプションを選択します。少しきれいです。

于 2012-07-20T17:33:43.537 に答える
1

関数内では、T [][]とT**はほとんど同じ意味で使用できますが、引数として渡される場合は注意が必要です。'pointer-to-pointer'パターンは、変数自体を格納するのに十分なメモリのみを使用し(通常、プロセッサのワードサイズと同じ)、プログラマに依存してデータに正しいオフセットを生成しますが、配列構文では、コンパイラは、行を正しくアドレス指定できるように、構造のストライドも知る必要があります。個人的には、この理由だけで配列をパラメーターとして渡すのは好きではありません。コンパイル時にストライドが修正されます。私の意見では、行と列の補助パラメーターを使用して常にT**ルートを使用する方がよいと思います。

于 2012-07-20T15:35:58.533 に答える
0
void func(float* state[6], float* err[6][6]);


int main()
{
  float state[6];
  float err[6][6];

  func(&state, &err);

  return 0;
}

次の2つの宣言はどちらも同じです...

char *message = "Hello World!";
char message[13] = "Hello World!"; /* "Hello World!" is 12 chars + \0 termination */

配列はポインタであり、処理が異なります。したがって、messageこれらの宣言のいずれかでのアドレスをfunc1(char *)またはfunc1(char [])に渡すには、それがアドレスを渡すと言いfunc1(message);ます。

配列は、アドレスとして最初の値にのみ渡すことができます。次のプログラムを実行して、その事実を示します。

#include <stdio.h>
void func(float* array);

int main()
{
  float state[6];
  int i = 0;
  printf ( "Sizeof state: %d\n", sizeof(state) );
  for ( i = 0; i < 6; i ++ ) { state[i] = i+1; }
  func(state);

  return 0;
}

void func ( float *array )
{
 printf ( "Sizeof float: %d\n", sizeof(float) );
 printf ( "Sizeof array: %d\n", sizeof(array) );
 printf ( "Value in array[0] = %f\n", array[0] );
 printf ( "Value in *array = %f\n", *array );
 array++;
 printf ( "Value in array[-1] = %f\n", array[-1] );
 printf ( "Value in array[0] = %f\n", array[0] );
 printf ( "Value in *array = %f\n", *array );
}

したがって、への呼び出しfunc(float* state[6], float* err[6][6] );は、2レベルのポインターと3レベルのポインターを宣言しています。同様の機能ですが、同じ呼び出しで、func(float **state, float ***err );

言うまでもなく、あなたが目指しているものではありません。

于 2012-07-20T19:43:45.193 に答える