为什么/何时使用`intptr_t`在C中进行types转换?
我有一个关于使用intptr_t与long int 。 我发现增加内存地址(例如通过手动指针算术)因数据types而异。 例如增加一个字符指针增加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给我警告我的types转换:“从指针转换为不同大小的整数”。
 经过一些谷歌search和结果(后者是一个字吗?),我看到一些人推荐使用intptr_t : 
 #include <stdint.h> 
…
 printf( "pChar: %ld\n", ( intptr_t )pChar ); printf( "pFloat: %ld\n", ( intptr_t )pFloat ); 
 这确实解决了错误。 所以,我想,从现在开始,我应该使用intptr_t来进行types转换指针…但是后来发现我可以通过用intreplaceint来解决问题: 
 printf( "pChar: %ld\n", ( long int )pChar ); printf( "pFloat: %ld\n", ( long int )pFloat ); 
 所以我的问题是,为什么intptr_t有用,它应该什么时候使用? 在这种情况下,这似乎是多余的。 很显然, myChar和myFloat的内存地址太大,无法放入int …所以将它们typesmyFloat long int解决这个问题。 
 是否有时内存地址太长,以至于long int ? 现在我想起来了,如果你有大于4GB的内存,那么内存地址可能会超过2 ^ 32  –  1(无符号长整型的最大值…),但是C之前就已经创build了可以想象的吧? 还是他们有先见之明? 
谢谢!
 这是事情:在一些平台上, int是正确的大小,但在其他平台上, long是正确的大小。 你怎么知道你应该使用哪一个? 你没有。 有人可能是对的,但标准不能保证它会是哪一个(如果是的话)。 所以标准提供了一个被定义为正确大小的types,不pipe你在哪个平台上。 之前你必须写: 
 #ifdef PLATFORM_A typedef long intptr; #else typedef int intptr; #endif 
现在你只写:
 #include <stdint.h> 
它涵盖了更多的情况。 想象一下专门为您的代码运行的每个平台上面的代码片段。
  intptr_t是一个新的发明,创造了64位甚至128位内存地址后想象。 
 如果您需要将指针转换为整数types,则始终使用intptr_t 。 做任何事情都会给将来需要移植代码的人带来不必要的问题。 
在Mozilla / Firefox这样的程序中,当人们想要在64位Linux上进行编译时,需要很长时间才能解决所有这些问题。
 首先, intptr_t仅用于数据指针(不是函数),并不保证存在。 
 那么,不,你不应该用它来打印的目的。  %p是为了这个。 你只需要把你的指针指向(void*)然后就可以了。 
 算术/访问单个字节也是不好的。 转换为(unsigned char*) 。 
  intptr_t是真正的罕见场合,你必须将指针解释为整数(它们实际上不是)。 不,如果你不这样做。 
 你可以通过使用p转换说明符让你的生活更轻松: 
 printf("%p\n", (void *)foo); 
 另外,打印type (u)intptr_tvariables的可移植方法是使用inttypes.h的PRI*PTRmacros; 以下相当于在我的平台(32位)上使用p : 
 printf("%08" PRIxPTR "\n", (uintptr_t)(void *)foo); 
 为了完全的可移植性,对void *进行强制转换是必要的,但是在具有统一指针表示的平台上可以省略。