どういうわけか、私が見ているコードには次のようなものがたくさんあります
char tmp[4];
memcpy(&tmp[0],foo_pointer,bar_size)
私は単純に期待していたでしょう
char tmp[4];
memcpy(tmp,foo_pointer,bar_size)
私が最初の方法でそれを書くことに欠けている理由はありますか?
配列を関数に渡すと、配列はその最初の要素へのポインターに減衰するため、これを呼び出す両方の方法は同等です
いいえ、同じです。
前者はtmp
、視界の定義がなくてもより明確になる可能性があります。
(そして、なぜそうなのかについてこの答えを完全にするために、ここに標準の後半のドラフトからの興味深いビットがあります:)
(6.3.2.1p3)
sizeof
演算子、_Alignof
演算子、または単項演算子のオペランドである場合&
、または配列の初期化に使用される文字列リテラルである場合を除き、「タイプの配列」タイプの式は式に変換されます。配列オブジェクトの初期要素を指し、左辺値ではないタイプ「pointertotype」を使用します。配列オブジェクトにレジスタストレージクラスがある場合、動作は未定義です。
その書き込みに気付くと便利です
&tmp[0]
冗長です。と同等です
&(*(tmp + 0))
つまり、tmp を取得し、0 を追加し、tmp + 0 が指す値を取得し、tmp + 0 が指す値のアドレスを取得します。つまり、無駄な操作を行っています。
「tmp」と書くだけです。
それはスタイルの違いだけです。一部の人々は、関数に渡す値がポインタであると表現するのを好む傾向があるため&
、配列の最初の要素に (addressof) 演算子を使用します。ただし、配列はアドレスのみを使用して渡すことができるため、これは配列自体を渡すことと同じです。
それらは同等ですが、前者は将来の読者にtmp
配列であることを思い出させますが、後者はそのような区別を明白にしないかもしれません.
tmp
後者は、それが配列であることをすでに知っている場合にのみ、読みやすくなります。そうしないと、誤解を招き、別のtmp
ものとして考えてしまう可能性が高くなります。単純な変数の後に配列が導入されていること、またはあなたがそれを責めたいと思っていることのせいにしてください。ただし、余分な装飾のない変数は、多くの場合、初心者には単純な型と見なされます。