转载来源:http://www.cnblogs.com/Anker/p/3438480.html

C语言指针转换为intptr_t类型

1、前言

  今天在看代码时,发现将之一个指针赋值给一个intptr_t类型的变量。由于之前没有见过intptr_t这样数据类型,凭感觉认为intptr_t是int类型的指针。感觉很奇怪,为何要将一个指针这样做呢?如是果断上网查查,发现我的感觉是错误的,所以,任何事情不能凭感觉,要弄清楚来龙去脉。先总结一下intptr_t类型,然后介绍指针与intptr_t类型的转换,最后给出测试程序。

2、intptr_t类型

  我接触最早的处理器是32位,目前64位处理器发展迅速。数据类型特别是int相关的类型在不同位数机器的平台下长度不同。C99标准并不规定具体数据类型的长度大小。

位数 char short int long 指针
16  1个字节8位   2个字节16位  2个字节16位  4个字节32位 2个字节16位
32  1个字节8位   2个字节16位 4个字节32位  4个字节32位 4个字节32位
64  1个字节8位   2个字节16位  4个字节32位  8个字节64位 8个字节64位

为了保证平台的通用性,程序中尽量不要使用long类型。可以使用固定大小的数据类型宏定义,这些宏定义需要引用stdint.h头文件。

 1 /* There is some amount of overlap with <sys/types.h> as known by inet code */
 2 #ifndef __int8_t_defined
 3 # define __int8_t_defined
 4 typedef signed char         int8_t;
 5 typedef short int          int16_t;
 6 typedef int               int32_t;
 7 # if __WORDSIZE == 64
 8 typedef long int          int64_t;
 9 # else
10 __extension__
11 typedef long long int        int64_t;
12 # endif
13 #endif
14
15 /* Unsigned.  */
16 typedef unsigned char         uint8_t;
17 typedef unsigned short int    uint16_t;
18 #ifndef __uint32_t_defined
19 typedef unsigned int          uint32_t;
20 # define __uint32_t_defined
21 #endif
22 #if __WORDSIZE == 64
23 typedef unsigned long int       uint64_t;
24 #else
25 __extension__
26 typedef unsigned long long int    uint64_t;
27 #endif

关于intptr_t的类型定义如下:

//intptr_t类型是为指针准备的
 1 /* Types for `void *' pointers.  */
 2 #if __WORDSIZE == 64
 3 # ifndef __intptr_t_defined
 4 typedef long int               intptr_t;
 5 #  define __intptr_t_defined
 6 # endif
 7 typedef unsigned long int    uintptr_t;
 8 #else
 9 # ifndef __intptr_t_defined
10 typedef int                    intptr_t;
11 #  define __intptr_t_defined
12 # endif
13 typedef unsigned int        uintptr_t;
14 #endif

从定义可以看出,intptr_t在不同的平台是不一样的,始终与地址位数相同,因此用来存放地址,即地址。

3、指针与intptr_t

  C语言指针用来保存变量或常量的地址,地址由处理器的位数决定。在windows程序中,经常用到句柄,其实就是一个地址,具备通用性,对底层进行了封装。先对这个理解不深刻,什么时候需要将指针转换为intptr_t类型。

4、测试程序

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 #include <stdint.h>
 5 #include <string.h>
 6 #include <assert.h>
 7
 8 #define ID_STR_LEN   12
 9 #define NAME_STR_LEN 10
10
11 typedef struct student
12 {
13     char id[ID_STR_LEN];
14     char name[NAME_STR_LEN];
15     uint8_t age;
16 }student;
17
18 student * create_student()
19 {
20     student *stu = (student *)malloc(sizeof(student));
21     if (stu == NULL)
22     return NULL;
23     memset(stu, 0, sizeof(student));
24     return stu;
25 }
26
27 void *free_student(student *stu)
28 {
29     if (stu)
30     free(stu);
31 }
32
33 static void init_student(student * stu)
34 {
35     assert(stu);
36     const char *id = "2013112210";
37     const char *name = "Anker";
38     uint8_t age = 21;
39     memcpy(stu->id, id, strlen(id));
40     memcpy(stu->name, name, strlen(name));
41     stu->age = age;
42 }
43
44 static int handle_student(intptr_t handle)
45 {
46     if (handle == 0)
47     {
48     return -1;
49     }
50     student *stu = (student*)handle;
51     printf("id: %s\n", stu->id);
52     printf("name: %s\n", stu->name);
53     printf("age: %u\n", stu->age);
54     return 0;
55 }
56
57 int main()
58 {
59     student *stu;
60     stu = create_student();
61     init_student(stu);
62     //将指针转换为intptr_t类型
63     intptr_t handle = (intptr_t)stu;
64     handle_student(handle);
65     free_student(stu);
66     return 0;
67 }

5、参考网址

http://blog.163.com/tianle_han/blog/static/6617826200910663018319/

http://hi.baidu.com/woxmpmcafubctzq/item/67efee5764ebec07e7c4a5d5

c uintptr_t相关推荐

  1. 关于 uintptr_t和intptr_t 类型

    简介 最近在看代码时,发现了两个之前没见过的数据类型:intptr_t,uintptr_t.这两个数据类型是ISO C99定义的,具体代码在linux平台的/usr/include/stdint.h头 ...

  2. C++ OpenCV创建xml,yml文件(图像)列表程序

    最近在学习关于相机标定的程序,标定时需要将图片打包成XML YML TXT格式,下面贴出生成xml图像序列的程序,同样适用于yml,记录一下,欢迎讨论~ #include "opencv2/ ...

  3. C++ Opencv 读取指定路径中的所有文件(图片)及指定路径中指定格式的所有文件(图片)

    读取指令路径下的所有文件,程序如下: #include <io.h> #include < fstream> #include < string> #include ...

  4. Redis源码和java jdk源码中hashcode的不同实现

    一.redis实际上是使用了siphash 这个比较简单,我说的简单是指redis代码比较少不像jdk一样调用C++代码调用栈非常深. 先看这个rehashing.c 主要就是dictKeyHash函 ...

  5. nginx源码分析--内存对齐处理

    1.nginx内存对齐主要是做2件事情: 1) 内存池的内存地址对齐: 2) 长度按照2的幂取整.因为前面结构体已经是对齐了,如果后面的内存池每一小块不是2的幂,那么后面的就不能对齐 2.通用内存对齐 ...

  6. Nginx内存池--pool代码抽取(链表套路)

    ngx_palloc.c文件 ngx_palloc_large_hm是自己写的代码没有nginx原版的ngx_palloc_large写的好,细节要品味才会发现nginx的美 nginx链表的套路,正 ...

  7. Nginx源码分析--基本数据类型的别名

    typedef intptr_t        ngx_int_t; typedef uintptr_t       ngx_uint_t; typedef intptr_t        ngx_f ...

  8. C和C++安全编码笔记:整数安全

    5.1 整数安全导论:整数由包括0的自然数(0, 1, 2, 3, -)和非零自然数的负数(-1, -2, -3, -)构成. 5.2 整数数据类型:整数类型提供了整数数学集合的一个有限子集的模型.一 ...

  9. 4 OC 中的内存分配以及内存对齐

    目录 一  OC  中的内存分配 一  OC  中的内存分配 student 结构体明明是20?为什么是24个字节,因为结构体会按照本身成员变量最大的内存进行对齐,最大成员变量是8个字节,因此就是8的 ...

最新文章

  1. 和平精英为什么找不到服务器,和平精英为什么登不上去 和平精英游戏登不上原因分析...
  2. 一个很好学习Mysql网站
  3. communication with respect to scholars
  4. jsp jdbc mysql增删改查_使用JSP+SERVLET+JDBC实现对数据库的增删改查(详细)
  5. android 模拟器方向键,键盘操控使用方法
  6. MakerDAO 通过首个实体融资执行提案
  7. linux正则表达式脚本实例,Shell下的正则表达式及实例
  8. 提高python 程序运行速度_3个Python函数帮程序员们避免编写循环,提高运行速度...
  9. 通过在jquery中添加函数发送ajax请求来加载数据库数据,以json的格式发送到页面...
  10. PHP面向对象关键词static 、self
  11. jQuery 左侧滑动
  12. openSUSE Tumbleweed 支持 Linux Kernel 4.20
  13. 最流行的国家级域名是什么?不是.cn 也不是.uk
  14. Build Path
  15. iphone绕过id_破解苹果安卓手机屏幕锁ID锁 极品神器
  16. rapidminer简介与安装
  17. 【科普】数字货币的基石--区块链
  18. python打印质数(素数)
  19. 教你学习JavaScript的this入门到进阶最全用法
  20. 8086CPU I/O系统组织 8253芯片 8255A芯片

热门文章

  1. 如何成为优秀的PPT架构师?
  2. Hive将带有斜杆的时间拼接成字符串
  3. 使用turtle来画奥运五环使用turtle进行图形化的程序设计来绘制自己想要的图形
  4. STL bitset用法小结(详细)附蓝桥杯题:明码
  5. 红外探测器 - 超声波测速器 - 毫米波雷达探测器
  6. 教你认识水货手机翻新手机14天机的鉴别和选购
  7. Snagit 如何在截图的时候隐藏鼠标
  8. 《岗位说明书》--老白的作业
  9. 浙江教师计算机职称考试,浙江今年不再组织职称外语统一考试 计算机照考
  10. 阿里云 EDAS Java服务日志中打印调用链TraceId