【C语言】void*转int,无类型指针转整型
简单示例(第7行)
#include <stdio.h> // printf
#include <stdint.h> // intptr_t --- 这是重点!!!
int main()
{
void *pointer = (void*)233;
int number = (int)(intptr_t)pointer; // 先intptr_t强转,再int强转--- 这是重点!!!
printf("number = %d\n", number); // 输出:number = 233
}
逐字解释
#include <stdio.h> // C标准库
// printf - 标准库函数,功能:发送格式化输出到标准输出stdout
#include <stdint.h> // C99中引进的一个标准C库的文件
// intptr_t - 扩展的整数类型,不同平台上定义不一样,要么是long int,要么是int
int main()
{
void *pointer = (void*)233;
# 代码大意:将int型数字转换为void*型,再赋值给void*指针
# `void *` : 通用型指针/不确定类型的指针,可存任何地址,可接受任意类型的赋值
# `pointer` : 指针名,随意取的名字
# `(void*)` : 强制转换数据类型,将后面的int型转换为void*型
# `233` : 整型的数字
int number = (int)(intptr_t)pointer;
# 代码大意:先将void*型安全地转换为intptr_t型,再将intptr_t型转为int型,最后赋值给int型变量number
# `int` : 整型
# `number` : 变量名,随意取的名字
# `(int)` : 强制转换数据类型,将后面的intptr_t型转换为int型
# `(intptr_t)` : 强制转换数据类型,“安全地”将void*型转换为intptr_t型
#
# 问题一) 可以直接写成:int number = (int)pointer; 吗?
# 可以,但是编译过程种可能给你告警,IDE也可能提示你这样做不好
# 即就是,直接将(void*)转成(int),编译时不认可,IDE不认可
#
# 问题二) 为什么要先用(intptr_t)强转?
# * 规避告警:
# 编译的时候,如果不添加(intptr_t)强转,那么可能会给你个告警:
# 大意就是将整型转换为了不同大小的指针型
# warning: cast to pointer from integer of different size
# 或者不添加(intptr_t)强转的时候IDE直接给你警告:
# 大意就是从大的类型(void*)转成了小的类型(int),因为sizeof(void*)可能比sizeof(int)大
# Cast to smaller integer type 'int' from 'void *' (aka 'void *')
# * 为了移植代码的时候不报错,不同平台上编译的时候不报错
# 也就是说:
# * 需要先弄个能完美存下通用型指针的,即用intptr_t类型的存下
# (存储范围小的void*类型到存储范围大的intptr_t类型,精度不丢失)
# * 然后再进行强制转化,将intptr_t类型的转为int类型的
# (存储范围大的intptr_t类型到存储范围小的int类型,可能导致精度丢失,但这种行为编译器是允许的)
# (也就是它不会报错告警了)
#
# 问题三) 最终还是可能存在精度丢失,也就是值不一致的情况吗?
# 可能存在,主要是intptr_t型的转为int型,可能存在精度丢失
# 所以程序员需要人工来确保这个值传入和析出一致(类型一致+值一致)
#
# `pointer` : 上面命名的指针名
printf("number = %d\n", number); // 输出:number = 233
# 代码大意:打印整型的变量number
# `printf` : C语言标准库函数,用于将格式化后的字符串输出到标准输出
# `%d` : 以十进制形式输出带符号整数
}