53

我有一个关于使用intptr_tvs.的问题long int。我观察到递增内存地址(例如通过手动指针算法)因数据类型而异。例如,增加一个 char 指针会将 1 添加到内存地址,而增加一个 int 指针会增加 4、8 用于双精度,16 用于长双精度等等......

起初我做了这样的事情:

char myChar, *pChar;
float myFloat, *pFloat;

pChar = &myChar;
pFloat = &myFloat;

printf( "pChar:  %d\n", ( int )pChar );
printf( "pFloat: %d\n", ( int )pFloat );

pChar++;
pFloat++;

printf( "and then after incrementing,:\n\n" );
printf( "pChar:  %d\n", (int)pChar );
printf( "pFloat:    %d\n", (int)pFloat );

它编译和执行得很好,但是 XCode 给了我关于类型转换的警告:“从指针转换为不同大小的整数。”

经过一些谷歌搜索和搜索(后者是一个词吗?),我看到有人推荐使用intptr_t

#include <stdint.h>

...

printf( "pChar:  %ld\n", ( intptr_t )pChar );
printf( "pFloat: %ld\n", ( intptr_t )pFloat );

这确实解决了错误。所以,我想,从现在开始,我应该使用intptr_t类型转换指针......但是经过一番烦躁之后,我发现我可以通过替换来解决int问题long int

printf( "pChar:  %ld\n", ( long int )pChar );
printf( "pFloat: %ld\n", ( long int )pFloat );

所以我的问题是,为什么intptr_t有用,什么时候应该使用?在这种情况下,这似乎是多余的。显然, 和 的内存地址myChar太大myFloat而无法放入int... 所以将它们类型转换为long ints 解决了这个问题。

是不是有时内存地址也太大了long int?现在我考虑了一下,我想如果你有 > 4GB 的 RAM,这是可能的,在这种情况下,内存地址可能超过 2^32 - 1(无符号长整数的最大值......)但 C 早在那之前就被创建了可以想象,对吧?还是他们有那么有先见之明?

谢谢!

4

4 回答 4

56

intptr_t是一项新发明,是在设想 64 位甚至 128 位内存地址之后创建的。

如果您需要将指针转换为整数类型,始终使用intptr_t. 做任何其他事情都会给将来需要移植您的代码的人带来不必要的问题。

当人们想在 64 位 Linux 上编译它时,需要很长时间才能消除 Mozilla/Firefox 等程序中的所有错误。

于 2011-06-13T03:21:49.817 回答
43

事情是这样的:在某些平台上,int尺寸合适,但在其他平台上,尺寸long合适。你怎么知道你应该使用哪一个?你没有。一个可能是正确的,但标准不保证它会是哪一个(如果是的话)。因此,该标准提供了一种定义为正确大小的类型,无论您使用的是什么平台。在你必须写之前:

#ifdef PLATFORM_A
  typedef long intptr;
#else
  typedef int intptr;
#endif

现在你只需写:

#include <stdint.h>

它涵盖了更多的案例。想象一下,为您的代码运行的每个平台专门编写上面的代码片段。

于 2011-06-13T04:05:26.337 回答
11

首先,intptr_t仅适用于数据指针(不是函数),不保证存在。

那么,不,您不应该将其用于打印目的。就是为了这个%p。您只需将指针指向即可(void*)

对于算术/访问单个字节也没有好处。改为(unsigned char*)

intptr_t确实是在极少数情况下您必须将指针解释为整数(实际上并非如此)。如果你不能,就不要那样做。

于 2011-06-13T09:29:04.683 回答
11

您可以使用p转换说明符让您的生活更轻松:

printf("%p\n", (void *)foo);

此外,打印类型变量的可移植方法(u)intptr_t是使用来自;的PRI*PTR宏。inttypes.h以下相当于p在我的平台上使用(32位):

printf("%08" PRIxPTR "\n", (uintptr_t)(void *)foo);

强制转换void *是完全可移植性所必需的,但在具有统一指针表示的平台上可以省略。

于 2011-06-13T09:32:45.233 回答