1

静的配列の要素を設定する必要がある場合、 memset の最初のパラメーターとして何を渡すかについて少し混乱しています。検索しましたが、いくつかの特定の質問に対する答えが見つかりませんでした。

次のように宣言された配列がある場合:

char arr[10];

これら 2 つの呼び出しが有効であり、同じ効果が得られることを確認しました。

memset( arr, 0, 10);
memset( &arr, 0, 10);

私の具体的な質問は次のとおりです。

1-なぜarrに同じ効果があるのですか?

2- これらの呼び出しの違いは何ですか?

3-どれが正しいと考えられますか?

ありがとうございました!

4

3 に答える 3

6

保存期間はそれとは何の関係もありません。配列は配列です。この式:

&arr

を生成します。つまり、 10個の要素char (*)[10]を持つ配列へのポインタです。charただし、arr次のような関数に渡される場合:

memset(arr, 0, 10);

最初の要素へのポインタ、つまり。に劣化しますchar*。これらは同じものではありません。「正しい」(慣用的な)呼び出しは次のとおりです。

memset(arr, 0, 10);

ただし、この場合、関数void*に渡さmemsetれて関数で.として解釈されると、両方ともに変換されunsigned char*ます。どちらも同じ場所を指しているため、同じ結果が得られます。

ただし、真のそれぞれの型(つまり、ではないvoid*)を処理する場合、配列へのポインターは配列の最初の要素へのポインターと同じで はないことを理解することが重要です。

たとえば、achar (*)[10]をインクリメントするとポインタsizeof(char[10])バイトがインクリメントされますが、achar*をインクリメントすると1バイトだけインクリメントされます。

于 2013-03-17T20:36:44.373 に答える
3

なぜそれらはarrに同じ影響を与えるのですか?これらの呼び出しの違いは何ですか?

配列のアドレスは最初の要素のアドレスと同じであるため(配列は関数に渡されると最初の要素へのポインターに減衰します)、それは単にそれらが異なるタイプを持っているということです。arrタイプがあり、関数に渡されるchar[10]とに減衰します。char *対照的に、関数の引数として渡されたときに変更されない&arr型があります。char (*)[10]

どちらが正しいと見なされますか?

関数が特定の型を予期しない、つまり受け入れる限りvoid *、どちらかが適切です。ただし、呼び出された関数がいずれかのタイプが指定されていることを予期している場合は、もう一方のタイプを使用しないでください。プログラムの形式が正しくなく、未定義の動作が呼び出されるためです。

于 2013-03-17T20:37:08.713 に答える
1

1-なぜそれらはarrに同じ影響を与えるのですか?

どちらにも、配列の先頭のアドレスである同じ値が含まれています。

2-これらの呼び出しの違いは何ですか?

arrcharへのポインタに減衰します。つまりchar*(この変換は、配列の名前を関数に渡すときに発生します)、charの配列&arrへのポインタです。char (*)[]

3-どちらが正しいと見なされますか?

私は使用しますarr。両方が機能する理由であるをmemset受け入れます。void*

また、char arr[10] = {};配列をゼロ初期化するために使用できることに注意してください。

于 2013-03-17T20:35:49.127 に答える