Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1725800
  • 博文数量: 98
  • 博客积分: 667
  • 博客等级: 上士
  • 技术积分: 1631
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-27 15:59
个人简介

一沙一世界 一树一菩提

文章分类

全部博文(98)

文章存档

2021年(8)

2020年(16)

2019年(8)

2017年(1)

2016年(11)

2015年(17)

2014年(9)

2013年(4)

2012年(19)

2011年(1)

2009年(4)

分类: C/C++

2014-12-11 09:04:35

这篇文章是从别的地方看到的,感觉有必要记录下来,于是转了过来,各位搞编程的可以参考下。
在具体编程的时候可以借鉴下,以提高程序的可移植性和适用性,

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  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   
2 #include   
3 #include   
4 #include   
5 #include <string.h>  
6 #include   
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 }
复制代码
阅读(2052) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~