0

これはおそらくかなり基本的な質問になるでしょうが、私はこのようなものを実装する方法について混乱しています。

CIを採用しているクラスの場合、長さが異なる2つの配列を取得し、それらの要素を別の関数で比較する必要があります。(この関数は、サイズではなく、配列のみをパラメーターとして受け取ります)両方の配列にある要素は、別の配列に入れてその配列を返す必要があります(注:各配列は、同じ配列で要素が繰り返されないという点でセットのようなものです)。私はこれをどのように実装するかを少し調べましたが、ここで私が直面している問題のいくつかを紹介します。

  1. 配列の終わりがどこにあるかをどうやって知ることができますか?

    null要素の配列内の要素として{0}を実行できる可能性があることを確認したと思います。これが本当の場合、nullをチェックするためにこの要素を何と比較するかわかりません。

  2. Cが配列の値を渡せるとは思わないので、配列の最初の要素にポインタを渡すことになっていると思いますが、少しわかりません。

    配列をポインターとして渡す場合、配列要素にアクセスしてデータを取得するにはどうすればよいですか?

  3. 配列をメイン関数に戻すときに、メモリをクリアせずに結果の関数を返すにはどうすればよいですか?

    結果の配列をグローバルにする必要がありますか、それともそれを処理するためのより良い方法がありますか?

前もって感謝します。

4

4 に答える 4

2

あなたの質問は少し曖昧です。配列で表される2つのセットがあり、出力が配列として実装された別の配列であるセット交差を実装したいようです。

1.配列の終わりがどこにあるかを知るにはどうすればよいですか?

Cでは、それを知る方法はありません。長さを関数として渡すことができない場合、堅牢なソリューションを実行することはできません。#2に似たものである必要があります。

2.null要素の配列内の要素として{0}を実行できる可能性があることを確認したと思います。これが本当の場合、nullをチェックするためにこの要素を何と比較するかわかりません。

値0だけのヌル文字を追加できます。確認するには、0と比較する必要があります。各配列要素が何で構成されているかはわかりませんが、注意すべき点の1つは、これらの値は、配列マーカーの終わりとして予約されているため、ゼロにすることができます。

3. Cが配列の値を渡せるとは思わないので、配列の最初の要素にポインターを渡すことになっていると思いますが、少しわかりません。

はい。ポイントされた最初の要素を渡します。これは、Cでは配列記号です。

int A[10]; // pass A

4.配列をポインターとして渡す場合、配列要素にアクセスしてデータを取得するにはどうすればよいですか?

ポインタAを渡したとすると、A [i]として単純なインデックスを作成して要素にアクセスし、要素iを取得できます。

5.配列をメイン関数に戻す場合、メモリをクリアせずに結果の関数を返すにはどうすればよいですか?

malloc作成している関数では、配列を作成して、mallocによって作成された配列へのポインターを渡すことができます。関数が終了しても、マロックされたメモリは削除されません。

于 2013-02-19T22:35:49.630 に答える
1

配列の終わりがどこにあるかをどうやって知ることができますか?

配列のサイズを個別のパラメーターとして渡さない場合(そうする必要があります)、ある種の番兵値を使用する必要があります(C文字列が文字列の最後の文字の後に0を使用する方法) )。

Cが配列の値を渡せるとは思わないので、配列の最初の要素にポインタを渡すことになっていると思いますが、少しわかりません。

Cの配列セマンティクスは少し注意が必要です。、、、または単項演算子のオペランドである場合、または宣言内の配列を初期化するために使用される文字列リテラルである場合を除き、sizeof「N要素配列の」タイプの式は「ポインタ」タイプの式に変換されます。に"を指定すると、式の値は配列の最初の要素のアドレスになります。だから、コードを考えると_Alignof&TT

int arr1[10];

foo(arr1); // equivalent to foo(&arr1[0]);

arr1toの呼び出しの式は、 foo「の10要素配列からint」への「ポインタからint」に変換されます。によって受信される値はfoo、配列の最初の要素のアドレスです。

void foo(int *a)
{
  // do stuff with a[i]
}

式は;a[i]として解釈されます。次の'番目の要素*(a + i)のアドレスを見つけ、結果を逆参照します。 ia

[]これは、関数の引数に通常の配列であるかのように演算子を 使用するという、長い間言われている方法です。

配列をメイン関数に戻すときに、メモリをクリアせずに結果の関数を返すにはどうすればよいですか?

ここで何を意味するのか正確にはわかりません。次のコード機能しないことに注意してください。

int *foo(int *a1, int *a2)
{
  int a3[SOME_SIZE];

  // copy elements from a1 and a2 to a3;

  return a3;
}

終了するとfoo、アレイa3は存在しなくなります。そのメモリはシステムによって再利用されるため、返すポインタ値は無効になります。3つのオプションがあります。

まず、ターゲット配列を3番目の引数として渡すことができます。

int main(void)
{
  int arr1[N];
  int arr2[M];
  int arr3[K];
  ...
  foo(arr1, arr2, arr3);
  ...
}

void foo(int *a1, int *a2, int *result) { ... }

見つけたすべての要素を保持するのに十分な大きさの配列を指すという前提条件がありresultます(2つのソース配列のうち大きい方と同じ大きさである必要があります)。動的メモリ管理を台無しにしたくない場合は、これが最適な方法です。

次に、関数でターゲット配列を動的に割り当てることができます。

int main(void)
{
  int a1[M];
  int a2[N];
  int *a3;
  ...
  a3 = foo(a1, a2);
  ...
  free(a3);
}

int *foo(int *a1, int *a2)
{
  int *result = malloc(sizeof *result * SOME_SIZE);
  ...
  if (element_in_both_arrays())
    result[n++] = element_from_both_arrays();
  ...
  return result;
}

使い終わったら、メモリの割り当てを解除することを忘れないでください。

最後に、ターゲット配列をグローバル変数として(つまり、ファイルスコープで)宣言できます。あなたがそれをしたくないので、私は例を提示するつもりはありません。

配列を関数に渡したり、動的に割り当てられたバッファーを返したりするときはいつでも、配列サイズを個別のパラメーターとして渡す必要があります。一般に、ポインタ値だけに基づいて配列に含まれる要素の数を決定することは不可能です。番兵の値を使用できますが、それらは配列の論理サイズのみを示し、物理サイズは示しません。例えば:

char buffer[1024] = "foo";

論理サイズbufferは3(文字列の長さ)ですが、物理サイズは1キロバイトです。

于 2013-02-19T22:56:36.430 に答える
0
  1. 配列の長さを知るには、長さを引数として渡すか、配列に最後の項目であることを示す特別な値を指定する必要があります。

  2. 配列を渡す場合は、配列へのポインターを渡します。これが明確でない場合は、おそらくいくつかのコードを含める必要があります。

  3. 配列を関数に渡すと、配列に加えられた変更はすべて呼び出し元のメソッドに表示されます。何も返却する必要はありません。

于 2013-02-19T22:30:39.403 に答える
0

1の場合:関数の呼び出し元は、各配列の長さを知っている必要があります。この情報を関数に渡すことができます。オプションで番兵値を使用して有効な要素の終わりを示すことができますが、関数のすべてのユーザーがこの規則を認識し、それに従うことを確認する必要があります。

2の場合:配列名は、配列の最初の要素のアドレスの値を持つポインター型に劣化します(ほとんどの場合)。これを行うために特別なことをする必要はありません。

3の場合:出力がコピーされるメモリへのポインタを呼び出し元に提供させることができます。または、関数によって配列を動的に割り当てることもできますが、呼び出し元はこのメモリを解放することを知っている必要があります。

/* Finds elements common to both a and b, and copies them to c. The c out
   parameter is assumed to be at least as large as the smaller of the a_sz
   and b_sz. Returns the number of elements copied into c. */
int find_in_common (const int *a, size_t a_sz, const int *b, size_t b_sz,
                    int *c)
{
    /* ... */
}
于 2013-02-19T22:33:43.410 に答える