私は周りに浮かぶ配列の長さのいくつかのマクロを見てきました:
から この質問 :
#define length(array) (sizeof(array)/sizeof(*(array)))
#define ARRAY_LENGTH(array) (sizeof((array))/sizeof((array)[0]))
#define SIZE(array, type) (sizeof(array) / (sizeof(type))
そしてVisual Studioの _countof
:
#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
私が知りたいのは:
array[0]
と*array
を使用しているものの違いは何ですか?これはより良いCバージョンです(GoogleのChromiumプロジェクトから):
_#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
_
_array[0]
_を使用して_*array
_または_0[array]
_バージョンを改善します。これはプレーン配列の_array[0]
_と同等ですが、array
が発生するとコンパイルに失敗しますoperator[]()
をオーバーロードするC++型になる。
除算は、ポインターがarray
パラメーターとして渡される多くの(すべてではない)状況でゼロ除算演算(コンパイル時に定数式であるため、コンパイル時にキャッチされる必要があります)を引き起こします。
詳細については、 配列の長さを返すCの標準関数はありますか? を参照してください。
C++コードにはより良いオプションがあります。詳細については、 マクロを使用せずにsizeof_arrayをコンパイルする を参照してください。
(1)Cに違いはありません。C++の実際のraw配列に違いはありません。
(2)どちらか一方を好む技術的な根拠はありませんが、初心者はポインターの逆参照によって混乱する可能性があります。
(3)C++では、非常に安全でないため、通常はマクロを使用しません。実際の生の配列の代わりにポインタを渡すと、コードはコンパイルされますが、不正な結果が生じます。したがって、C++では、代わりに関数テンプレートを使用するか、または使用する必要があります。
#include <stddef.h>
typedef ptrdiff_t Size;
template< class Type, Size n >
Size countOf( Type (&)[n] ) { return n; }
これは引数として実際の生の配列のみを受け入れます。
関数startOf
、endOf
およびcountOf
のトライアドの一部であり、生の配列と標準ライブラリコンテナーの両方に適用できるように定義すると非常に便利です。私の知る限り、このトライアドはディートマーキュールによって最初に識別されました。 C++ 0xでは、startOf
およびendOf
はおそらくstd::begin
およびstd::end
。
乾杯&hth。、
1)何もありません。配列の値は、その最初の要素へのポインターです。したがって、* array == array [0]
2)個人の好み
3)いいえ
このマクロは、配列がパラメーターとして関数に渡される関数内で呼び出された場合は機能しません。これは、配列オブジェクトがディープコピーではなくポインタに「減衰」を渡したためです。