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

本文共 4364 字,大约阅读时间需要 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来替代它。

转载于:https://www.cnblogs.com/alantu2018/p/8465915.html

你可能感兴趣的文章
【转】只打开一个子窗口
查看>>
WPF:类型转换器的实现
查看>>
03.Longest Substring Without Repeating Characters
查看>>
UVA 1345 Jamie's Contact Groups
查看>>
PowerShell管理Azure
查看>>
VS2008中MFC对话框界面编程Caption中文乱码的解决办法
查看>>
javascript 原生态实现ajaxform 包括客户端验证
查看>>
Spring MVC 单元测试Demo
查看>>
2019年春季学期第二周作业
查看>>
Linux的基础预备知识
查看>>
mysql 对比两个表的一致性
查看>>
公司网站 解决方案 案例
查看>>
kibana发音 logstash发音 ElasticSearch发音 音标 翻译
查看>>
Web 通信 之 长连接、长轮询(long polling)
查看>>
Python数据处理(持续更新)
查看>>
关于fastjson在序列化成JSON串时字段增加的问题
查看>>
meterpreter基本命令
查看>>
Java多线程
查看>>
python中的时间戳,与MySQL的时间戳的,对应与匹配
查看>>
构造函数(构造器)的正确重载方式------类
查看>>