32位系统下C语言中void*转long long结果异常,如何正确转换?
32位系统下void*转long long的问题分析与解决
问题根源
你的代码输出异常主要是两个原因导致:
- printf格式符不匹配:
- 输出
void*时用%d,这属于未定义行为——32位系统中指针是无符号4字节类型,而%d对应有符号int,类型不匹配会导致输出结果不可控。 - 输出
long long时仍用%d,%d只能读取4字节数据,但long long是8字节,会错误截取部分字节,最终输出乱值。
- 输出
- 指针转整数的方式不安全:直接将
void*强转为long long,若指针值的最高位为1(即数值大于2^31),会触发符号扩展,导致long long被错误填充高位数据。
修复方案
1. 使用正确的printf格式符
- 指针类型优先用
%p(标准指针输出格式),若要输出数值形式,用%u(无符号int,匹配32位指针的长度)。 long long类型必须对应%lld格式符,确保完整读取8字节数据。
2. 安全的指针转整数路径
用C99标准定义的uintptr_t类型(需包含<stdint.h>头文件),它专门用于存储指针的数值,长度与指针一致,再转成long long可避免符号扩展问题。
修复后的代码
#include <stdio.h> #include <stdint.h> int main() { // 用%zu输出sizeof结果(sizeof返回size_t类型) printf("size of long long is %zu, unsigned int is %zu, void* is %zu\n", sizeof(long long), sizeof(unsigned int), sizeof(void*)); void* ptr = (void*)12340000; // 显式强制转换消除编译器警告 long long test = (long long)(uintptr_t)ptr; // 安全转换流程 // 多方式验证结果 printf("ptr的标准指针格式:%p\n", ptr); printf("ptr的数值形式:%u\n", (unsigned int)ptr); printf("转换后的long long值:%lld\n", test); return 0; }
预期输出
size of long long is 8, unsigned int is 4, void* is 4 ptr的标准指针格式:0x0000bc6140(不同系统显示可能略有差异) ptr的数值形式:12340000 转换后的long long值:12340000
内容的提问来源于stack exchange,提问作者Narendra Thamatam
相关产品推荐
相关产品推荐

