745

私はsize_tCで混乱しています.私はそれがsizeof演算子によって返されることを知っています. しかし、それは正確には何ですか?データ型ですか?

forループがあるとしましょう:

for(i = 0; i < some_size; i++)

またはを使用する必要がありますint i;size_t i;

4

15 に答える 15

526

ウィキペディアから

1999 ISO C 標準 (C99) によると、size_t少なくとも 16 ビットの符号なし整数型です (セクション 7.17 および 7.18.3 を参照)。

size_tで定義されている C99 ISO/IEC 9899 標準など、いくつかの C/C++ 標準で定義されている符号なしデータ型stddef.hです。1stdlib.hこのファイルは内部的にサブインクルードされているため、 をインクルードすることでさらにインポートできます stddef.h

この型は、オブジェクトのサイズを表すために使用されます。サイズを取得または返すライブラリ関数は、サイズが の型であるか、戻り値の型を持っていることを期待していますsize_t。さらに、最も頻繁に使用されるコンパイラベースの演算子 sizeof は、 と互換性のある定数値に評価される必要があり size_tます。

暗黙的に、size_t任意の配列インデックスを保持することが保証されている型です。

于 2010-03-31T05:56:32.267 に答える
257

size_t符号なしタイプです。したがって、負の値 (<0) を表すことはできません。何かを数えるときに使用し、それが負になることはないと確信しています。たとえば、文字列の長さは少なくとも 0 である必要がstrlen()あるため、a を返します。size_t

あなたの例では、ループ インデックスが常に 0 より大きい場合size_t、または他の符号なしデータ型を使用するのが理にかなっています。

オブジェクトを使用するときsize_tは、算術演算を含め、オブジェクトが使用されるすべてのコンテキストで負でない値が必要であることを確認する必要があります。たとえば、あなたが持っているとしましょう:

size_t s1 = strlen(str1);
size_t s2 = strlen(str2);

と の長さの差を見つけたいとしstr2ますstr1。次のことはできません。

int diff = s2 - s1; /* bad */

これは、符号なしの型で計算が行われるため、 のdiff場合でも、 に代入される値が常に正の数になるためです。この場合、ユースケースによっては、 と に(または) をs2 < s1使用した方がよい場合があります。intlong longs1s2

C/POSIX には を使用できる/使用すべき関数がいくつかありますがsize_t、歴史的な理由により使用しません。たとえば、 の 2 番目のパラメータfgetsは理想的にはである必要size_tがありますが、実際にはintです。

于 2010-03-31T09:11:09.050 に答える
82

あなたが経験型なら

echo | gcc -E -xc -include 'stddef.h' - | grep size_t

Ubuntu 14.04 64 ビット GCC 4.8 の出力:

typedef long unsigned int size_t;

GCC 4.2stddef.hの glibc ではなく、GCC によって提供されることに注意してください。src/gcc/ginclude/stddef.h

興味深い C99 の外観

  • mallocは引数として取るsize_tので、割り当てられる最大サイズを決定します。

    また、 からも返されるsizeofため、配列の最大サイズを制限していると思います。

    参照: C の配列の最大サイズは?

于 2015-06-14T21:07:21.907 に答える
26

types.hのマンページには次のように書かれています。

size_t は符号なし整数型でなければなりません

于 2010-03-31T05:56:25.573 に答える
10

size_t交換可能ではありintません。たとえば、64 ビットの Linux ではsize_t、サイズは 64 ビット (つまりsizeof(void*)) ですが、int32 ビットです。

size_tまた、署名されていないことに注意してください。署名されたバージョンが必要な場合はssize_t、一部のプラットフォームにあり、例により関連性があります。

原則として、intほとんどの一般的なケースに使用し、特定の必要がある場合にのみsize_t/を使用することをお勧めします (たとえば)。ssize_tmmap()

于 2013-10-30T03:03:10.320 に答える
3

一般に、0 から開始して上に向かっている場合は、負の値の状況に陥るオーバーフローを避けるために、常に符号なし型を使用してください。これは非常に重要です。なぜなら、配列の境界がたまたまループの最大値よりも小さく、ループの最大値がたまたま型の最大値よりも大きい場合、負の値にラップアラウンドし、セグメンテーション フォールト(SIGSEGV)が発生する可能性があるためです。 )。そのため、一般に、0 から開始して上に向かうループに int を使用しないでください。無印を使用。

于 2013-11-09T17:34:13.240 に答える
2

これはプラットフォーム固有のtypedef. たとえば、特定のマシンでは、unsigned intまたはの場合がありますunsigned long。コードの移植性を高めるために、この定義を使用する必要があります。

于 2021-02-02T10:54:33.237 に答える
-3

私の理解でsize_tは、unsignedビット サイズがネイティブ アーキテクチャのポインタを保持するのに十分な大きさの整数です。

そう:

sizeof(size_t) >= sizeof(void*)
于 2013-03-07T21:48:39.433 に答える