为何void指针转int指针后,取值未得到字符ASCII值而是无效值?
为什么将char指针转为int*后取值得不到预期的ASCII值?
问题重现
你定义了一个char变量letter = 'A',通过void指针中转后转为int指针,解引用int*指针时却得到了无效整数值,而非预期的65。代码及输出如下:
#include <stdio.h> int main(){ char letter = 'A'; void* genericPointer = &letter; int* integerPointer = (int*) genericPointer; // 类型转换 fprintf(stdout,"Generic Adress: %p | Char Value: %c | Integer Value: %i \n",genericPointer, *(char*) genericPointer, *(char*) genericPointer); fprintf(stdout,"Integer Adress: %p | Char Value: %c | Integer Value: %i \n",integerPointer, *integerPointer, *(char*)integerPointer); fprintf(stdout,"Integer Adress: %p | Char Value: %c | Dead Integer Value: %i \n",integerPointer, *integerPointer, *integerPointer); // 为什么不是65? return 0; }
输出:
Generic Adress: 0x7ffc31336a77 | Char Value: A | Integer Value: 65 Integer Adress: 0x7ffc31336a77 | Char Value: A | Integer Value: 65 Integer Adress: 0x7ffc31336a77 | Char Value: A | Dead Integer Value: 862615361
核心原因
问题出在内存访问范围不匹配和未定义行为:
- 内存大小差异:在绝大多数平台上,
char类型仅占用1字节,而int类型占用4字节。当你把char变量的地址强制转为int*后,解引用*integerPointer会从该地址开始读取连续4个字节的数据。 - 垃圾数据拼接:你的
letter变量只占1字节(存储值0x41,即'A'的ASCII码),剩下的3个字节是栈上未初始化的垃圾数据。这4个字节拼接成的整数自然不是你预期的65。比如你得到的862615361转成十六进制是0x336A7741,其中0x41是'A'的字节,后面的0x776A33就是栈上的随机垃圾数据。 - 严格别名规则:C标准规定,不同类型的指针(除了char*)不能用来访问另一种类型的变量,这种行为属于未定义行为——虽然某些情况下可能看起来“正常”,但结果完全不可靠。
正确做法
如果要将char的值转换为int,应该先读取char变量的内容,再赋值给int变量,而非直接转换指针:
// 方法1:直接读取char变量 int intValue = letter; // 方法2:通过void*指针转换为char*后读取 int intValue = *(char*)genericPointer; printf("正确的整数值:%i\n", intValue); // 输出65
内容的提问来源于stack exchange,提问作者user23077310
相关产品推荐
相关产品推荐

