通过阅读网上有关size_t
和ptrdiff_t
的帖子,我想确认以下内容:
-
如果数组的最大大小小于
1/2*(max number represent-able by size_t)
,我可以安全地使用ptrdiff_t
并检查指向同一对象的两个指针之间的相对距离?(因为我说的是数组,"指向同一对象的指针"意味着"指向同一数组的指针")。 -
如果我想声明一个变量,可以表示从另一个指针的偏移量,我最好声明为类型
ptrdiff_t
? -
如何在C和c++中输出
size_t
和ptrdiff_t
类型的变量?以下是正确的:跨平台格式字符串类型的变量size_t? -
是
uintptr_t
只是size_t
的另一个名称还是应该作为size_t
的单独类型使用? -
是
ssize_t
和intptr_t
另一个名称为ptrdiff_t
或它必须使用不同?
我开始在Ubuntu上使用gcc。我只是在使用某人的时候才发现这些类型别人的代码。
添加:我希望能够使用负偏移量。使用uintptr_t
和intptr_t
有什么区别吗?
1:如果数组的最大大小小于1/2*(
size_t
可表示的最大数量),我可以安全地使用ptrdiff_t
并检查指向同一对象的两个指针之间的相对距离?
这将是sizeof(size_t) <= sizeof(prtdiff_t)
的情况。在一个合理的实现中将是这种情况,但不能保证。
2:如果我想声明一个变量,可以表示从另一个指针的偏移量,我最好声明为类型
ptrdiff_t
?
是的,这就是该类型的目的。
在C:3:如何在C和c++中输出size_t和ptrdiff_t类型的变量?
printf("%zu %tdn", size, ptrdiff);
在c++: std::cout << size << ' ' << ptrdiff << 'n';
4:是
uintptr_t
只是size_t
的另一个名字,还是应该作为size_t
的单独类型使用?
应被视为单独的类型。uintptr_t
是一个整型,可以包含任何转换为整型的指针值;在某些平台上可能不存在。
5:
ssize_t
和intptr_t
是ptrdiff_t
的另一个名字还是必须不同使用?
ssize_t
就C或c++语言而言不是标准类型;它被Posix定义为一些函数参数和返回值的类型。除了直接处理Posix函数外,最好使用ptrdiff_t
。
intptr_t
用于保存指针的整数表示形式,而不是指针之间的差异。在某些平台上,它们可能有不同的大小,并且intptr_t
可能根本没有定义,因此它们不应该互换使用。
我确实希望能够使用负偏移量。使用
uintptr_t
和intptr_t
有什么区别?
不要使用这两种类型来表示偏移量;使用ptrdiff_t
。在特殊情况下使用这些类型,当您出于某种原因需要将指针转换为它们的整数表示形式时。
uintptr_t
和intptr_t
足够大,可以保存任何void*
指针的值而不会丢失信息。它们需要能够唯一地表示程序的整个地址空间中任何对象的地址——包括任何对象中的任何字节。
size_t
是sizeof
运算符生成的类型;ptrdiff_t
是通过减去两个指针得到的类型。它们只需要大到足以容纳一个物体。(也有可能有一个对象太大,以至于减去两个指向相反两端的指针会溢出。)
大多数当前的系统都有一个单一的单片地址空间,但是C语言被设计成在没有这样的系统上工作。例如,在某些系统上,可能的最大对象可能是整个地址空间大小的一小部分——并且比较或减去指向不同对象的指针可能没有意义。(考虑一个分段寻址方案,其中指针减法和比较只考虑地址的偏移部分。)
假设_ptrdiff_t_
是一个错别字:
1)是的。如果数组的最大大小小于SIZE_MAX/2
,则可以安全地使用ptrdiff_t
2)有时:ptrdiff_t
通常是两个指针之间的差异,而size_t
是偏移量。重要的是size_t
总是带正电,ptrdiff_t
可能带负电。请注意,在某些平台上,它们的大小可能相差很大。
3)输出size_t
和ptrdiff_t
类型的变量的方式与输出任何其他变量类型的方式相同。
size_t a = 10;
ptrdiff_t b = 20;
printf("%u %d", ((unsigned int)a), ((int)b));
std::cout << a << b;
4) uintptr_t
是一个至少和int*
一样大的无符号整数,以便安全地对指针进行整数运算。据我所知,size_t
不能保证是相同的。
5) ssize_t
为非标准C类型,对应ptrdiff_t
。使用ptrdiff_t
代替。(On 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.
http://en.wikipedia.org/wiki/Size_t)