uintptr_t 和 intptr_t 类型

intptr_tuintptr_t 这两个数据类型是 ISO C99 定义的,具体代码在 linux 平台的 /usr/include/stdint.h 头文件中。

/* Types for `void *' pointers.  */
#if __WORDSIZE == 64
# ifndef __intptr_t_defined
typedef long int		intptr_t;
#  define __intptr_t_defined
# endif
typedef unsigned long int	uintptr_t;
#else
# ifndef __intptr_t_defined
typedef int			intptr_t;
#  define __intptr_t_defined
# endif
typedef unsigned int		uintptr_t;
#endif

下不同的数据类型在不同字长机器上长度大小。

位数charshortintlong指针
161个字节8位2个字节16位2个字节16位4个字节32位2个字节16位
321个字节8位2个字节16位4个字节32位4个字节32位4个字节32位
641个字节8位2个字节16位4个字节32位8个字节64位8个字节64位

指针在32位平台和64位平台下均与 long 类型的长度一致,然而在16位机器上,long 为4个字节,而指针为2个字节。

因此,就可以发现 intptr_t 和 uintptr_t 定义的巧妙之处:

在64位机器上,intptr_t 为 long intuintptr_t 为 unsigned long int。而在非64位机器上,intptr_t 为 int,uintptr_t 为 unsigned int

这样就可以保证 intptr_t 和 uintptr_t 的长度与机器的指针长度一致,因此在进行整数与指针的相互转换时可以用 intptr_t 进行过渡。

C语言指针用来保存变量或常量的地址,地址长度由处理器的位数决定。在windows程序中,经常用到句柄,其实就是一个地址,具备通用性,对底层进行了封装。 指针长度取决于使用的机器和编译器。64位机器的出现导致为不同数据类型分配的内存在长度上的差异变得明显。

指针相关的预定义类型

使用指针时经常用到以下四种预定义类型:

  • size_t:用于安全地表示长度。
  • ptrdiff_t:用于处理指针算术运算。
  • intptr_t 和 uintptr_t:用于存储指针地址。

size_t

  • size_t 类型表示 C 中任何对象所能达到的最大长度,它是无符号整数。
  • size_t 用做 sizeof 操作符的返回值类型,同时也是很多函数的参数类型,包括 malloc 和 strlen。

intptr_t 和 uintptr_t:

intptr_t 和 uintptr_t 类型用来存放指针地址。

作用:通常用于将指针转换为整数,以及在整数形式下进行操作,直到再次将其转换为指针类型。

它们提供了一种可移植且安全的方法声明指针,而且和系统中使用的指针长度相同,对于把指针转化成整数形式来说很有用。当需要将指针作为整数运算时,将它转换成 intptr_t / uintptr_t 进行运算才是安全的。

避免把指针转换成整数。如果指针是64 位,整数只有4 字节时就会丢失信息。

#include <iostream>
#include <iomanip>       // std::setfill() std::setw()
//#include "stdint.h"      // uintptr_t

int main()
{
    int a = 10;
    int* p = &a;

    uintptr_t p_addr = (uintptr_t)p;
    std::cout << std::uppercase << std::hex << std::setfill('0') << "Address of p = 0x" << p_addr << std::endl;

    // 恢复默认的格式设置
    std::cout << std::defaultfloat << std::setfill(' ');

    return 0;
}

uintptr_t 和 void * 的区别:

uintptr_t 表示一个整数地址,在 C 和 C++ 中前者是无符号整型数据类型,而后者是指向未知类型的指针类型,不能直接通过指针的类型进行转换和使用,因为 void* 无法进行加减操作,也无法进行指针的解引用。因此,两者是有明显区别的,uintptr_t 表示的是指针的地址,void* 表示的是指向某个内存地址的指针。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值