20

size_tとに関連するオンラインの投稿を読んでptrdiff_t、次のことを確認したいと思います。

  1. 配列の最大サイズが。未満の場合、同じオブジェクトへの2つのポインター間の相対距離1/2*(max number represent-able by size_t)を安全に使用ptrdiff_tして確認できますか?(配列について話していたので、「同じオブジェクトへのポインター」は「同じ配列へのポインター」を意味します) 。

  2. 別のポインタからのオフセットを表すことができる変数を宣言したい場合は、型として宣言する方がよいptrdiff_tでしょう。

  3. size_tタイプの変数をCおよびptrdiff_tC++で出力するにはどうすればよいですか?次は正しいですか:size_t型の変数のクロスプラットフォームフォーマット文字列?

  4. はORuintptr_tの単なる別名であり、 ?size_tとは別のタイプとして使用する必要があります。size_t

  5. ORの別の名前は別の方法で使用する必要がありssize_tますintptr_tか?ptrdiff_t

Ubuntuでgccを使い始めています。他の人のコードを使用しているときに、これらのタイプについて知りました。

追加:負のオフセットを使用できるようにしたい。そして、との使用uintptr_tに違いはありintptr_tますか?

4

3 に答える 3

20

1:配列の最大サイズが1/2 *(最大数はで表すことができます)未満の場合、同じオブジェクトへの2つのポインター間の相対距離をsize_t安全に使用して確認できますか?ptrdiff_t

の場合はそうなりますsizeof(size_t) <= sizeof(prtdiff_t)。これは賢明な実装の場合ですが、保証はありません。

2:別のポインターからのオフセットを表すことができる変数を宣言したい場合は、型として宣言する方がよいptrdiff_tでしょうか。

はい、それがそのタイプの目的です。

3:CおよびC ++でsize_tおよびptrdiff_t型の変数を出力するにはどうすればよいですか?

Cの場合:

printf("%zu %td\n", size, ptrdiff);

C ++の場合:

std::cout << size << ' ' << ptrdiff << '\n';

4:isuintptr_tはORの単なる別名であり、 ?size_tとは別のタイプとして使用する必要があります。size_t

別のタイプと見なす必要があります。uintptr_t整数に変換された任意のポインタ値を含むことができる整数型です。一部のプラットフォームには存在しない場合があります。

5:ORの別の名前は別の方法で使用する必要がssize_tありますか?intptr_tptrdiff_t

ssize_tCまたはC++言語に関する限り、標準タイプではありません。これは、Posixによっていくつかの関数の引数と戻り値のタイプとして定義されています。ptrdiff_tPosix関数を直接処理する場合を除いて、使用するのが最適です。

intptr_tポインタ間の違いではなく、ポインタの整数表現を保持することを目的としています。一部のプラットフォームでは、これらのサイズが異なる場合があり、intptr_tまったく定義されていない場合があるため、同じ意味で使用しないでください。

負のオフセットを使用できるようにしたいのですが。そして、との使用uintptr_tに違いはありintptr_tますか?

オフセットを表すためにこれらのタイプのいずれも使用しないでください。を使用しますptrdiff_t。何らかの理由でポインタを整数表現に変換する場合は、特別な状況でこれらの型を使用してください。

于 2011-10-31T17:02:26.300 に答える
1

uintptr_t情報を失うことなくポインタ値intptr_tを保持するのに十分な大きさです。void*それらは、プログラムのアドレス空間全体(オブジェクト内の任意のバイトを含む)内の任意のオブジェクトのアドレスを一意に表すことができる必要があります。

size_tsizeof演算子によって生成されるタイプです。ptrdiff_t2つのポインタを減算することによって生成されるタイプです。それらは、単一のオブジェクトに対して十分な大きさである必要があります。(そして、反対側の端を指す2つのポインターを引くとオーバーフローするほど大きなオブジェクトを持つ可能性があります。)

現在のほとんどのシステムには単一のモノリシックアドレス空間がありますが、Cはそうでないシステムで動作するように設計されています。たとえば、一部のシステムでは、可能な最大のオブジェクトがアドレス空間全体のサイズのごく一部である場合があります。また、ポインタを個別のオブジェクトと比較または減算しても意味がない場合があります。(ポインタの減算と比較でアドレスのオフセット部分のみが考慮される、セグメント化されたアドレス指定スキームについて考えてみてください。)

于 2011-10-31T21:04:05.457 に答える
0

_ptrdiff_t_タイプミスであると仮定します。

1)はい。配列の最大サイズが、未満の場合はSIZE_MAX/2、安全に使用できますptrdiff_t
。2)場合によっては:ptrdiff_tは通常、2つのポインター間の差でありsize_t、はオフセットです。ここで重要なことはsize_t、常にポジティブでptrdiff_tあり、ネガティブかもしれません。一部のプラットフォームでは、サイズが大きく異なる場合があることに注意してください。
3)タイプの変数を出力し、他の変数タイプを出力するのと同じ方法で出力します size_tptrdiff_t

size_t a = 10;
ptrdiff_t b = 20;
printf("%u %d", ((unsigned int)a), ((int)b));
std::cout << a << b;

4)は、ポインタで整数演算を安全に行えるようにするために、 uintptr_t少なくとも。と同じ大きさの符号なし整数です。私が知る限り、同じであるとは限りません。 5)は非標準のCタイプであり、に対応します。代わりに使用してください。(http://en.wikipedia.org/wiki/Size_tint*size_t
ssize_tptrdiff_tptrdiff_tOn platforms supporting the POSIX 1003.1-1996 API standard, which includes most Unix-like systems, a signed variant of size_t named ssize_t is available, which was not part of the ANSI or ISO C standards.

于 2011-10-31T16:54:19.233 に答える