【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`         : 以十进制形式输出带符号整数
}

posted @ 2022-05-27 15:36  Alan_LJP  阅读(3864)  评论(1编辑  收藏  举报