博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C语言指针转换为intptr_t类型
阅读量:5818 次
发布时间:2019-06-18

本文共 4310 字,大约阅读时间需要 14 分钟。

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
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 }

5、参考网址

 

 

 

C语言编程需要注意的64位和32机器的区别

一、数据类型特别是int相关的类型在不同位数机器的平台下长度不同。C99标准并不规定具体数据类型的长度大小,只规定级别。作下比较:

16位平台

char         1个字节8位

short        2个字节16位

int            2个字节16位

long         4个字节32位

指针         2个字节

32位平台

char         1个字节8位

short        2个字节16位

int            4个字节32位

long         4个字节

long long 8个字节

指针         4个字节

64位平台

char         1个字节

short        2个字节

int            4个字节

long         8个字节(区别)

long long 8个字节

指针        8个字节(区别)

二、编程注意事项

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

typedef signed char       int8_t

typedef short int             int16_t;

typedef int                      int32_t;

# if __WORDSIZE == 64

typedef long int              int64_t;
# else
__extension__
typedef long long int      int64_t;

#endif

三、使用int时也可以使用intptr_t来保证平台的通用性,它在不同的平台上编译时长度不同,但都是标准的平台字长,比如64位机器它的长度就是8字节,32位机器它的长度是4字节,使用它可以安全地进行整数与指针的转换运算,也就是说当需要将指针作为整数运算时,将它转换成intptr_t进行运算才是安全的。intptr_t需要引用stddef.h头文件,它的定义如下:

#if __WORDSIZE == 64

typedef long int                intptr_t;
#else
typedef int                        intptr_t;
#endif
编程中要尽量使用sizeof来计算数据类型的大小

以上类型定义都有相应的无符号类型。

四、使用ssize_t和size_t

它们分别是unsigned和signed size of computer word size。它们也是表示计算机的字长,在32位机器上是int型,在64位机器上long型。使用它们对于增加平台的通用性有很大好处,从某种意义上来说它们等同于intptr_t和uintptr_t。使用它们也需要引用stddef.h头文件。

五、socket的accept函数在有些操作系统上使用size_t是不正确的,因为accept接收的int*类型,而size_t的长度可能会超过int*的长度限制,导致错误。后来BSD使用sock_t来替代它。

转载地址:http://oiwdx.baihongyu.com/

你可能感兴趣的文章
ADO.NET入门教程(一) 初识ADO.NET
查看>>
一个php写的linux下lvm自动快照实现脚本
查看>>
【015】SQL Server 2008不能连接
查看>>
Javascript 动态增减元素
查看>>
用C语言扩展Python的功能
查看>>
POJ---1703 Find them, Catch them [并查集]
查看>>
ios6:UIImagePickerController & Rotation
查看>>
js通过八个点 拖动改变div大小
查看>>
PHP截取字符串
查看>>
Ubuntu12下挂载硬盘(9TB)(文章索引)
查看>>
java中FileInputStream,FileReader等的区别(转)
查看>>
CentOS下MongoDB的升级
查看>>
tomcat多版本war应用部署(实例讲解)
查看>>
JS对img进行操作
查看>>
哈夫曼编码与译码
查看>>
分块查找算法
查看>>
C++const用法总结 (转)
查看>>
一段旅程的结束和另一端旅程的开始
查看>>
iPhone 屏幕上的 Home 键在哪里?(已解决)
查看>>
background-position 用法详细介绍
查看>>