为何int类型值未占用char数组的两个字节?技术咨询
嘿,我来帮你理清这个困惑!咱们一步步拆解问题:
1. 为啥arr[0] = 16只改了数组的一个位置?
你的数组arr是**char类型数组**,在C语言里char铁定是1字节大小。当你把int类型的16赋值给arr[0]时,编译器做了个隐式转换:它把4字节的int(假设你用的是常见的32/64位平台)直接截断成1字节的char——说白了就是只保留了int的低8位。
16的二进制是00000000 00000000 00000000 00010000,截断后剩下00010000(也就是十六进制0x10),这个值非零,所以arr[0]被设成了0x10,但arr[1]及后面的元素还是初始的'\0'(也就是0)。
你的循环while(arr[p] != '\0')会在p=1的时候停下来,因为arr[1]是0,所以最终输出p=1。核心点在于:你只是给单个char元素赋值,自然只会占用这一个1字节的位置,和int本身的大小没关系——赋值操作是针对数组的单个元素,不是把整个int直接拷贝到数组的连续内存里。
2. 怎么让整数占用数组的两个内存位置?
如果你想把一个整数的二进制数据存到数组的连续两个字节里,有两种靠谱的方法:
方法一:用指针强制类型转换(直接拷贝整数字节)
如果你要存的整数范围在-32768到32767之间,用short类型(通常是2字节)最合适。你可以把char数组的地址转换成short*指针,然后直接赋值:
// 把arr的起始地址转成short*,然后给这个指针指向的内存赋值 *(short*)&arr[0] = 0x1001; // 选一个两个字节都非零的数,比如0x1001
这样操作会把short类型的0x1001直接拷贝到arr[0]和arr[1]的位置(具体每个字节的值取决于你的平台是大端还是小端,但不管哪种,这两个位置都不会是0)。这时候你的循环会执行两次,最终输出p=2。
方法二:手动拆分整数字节到数组元素
如果你想精确控制每个字节的内容,那就手动把整数的高8位和低8位拆出来,分别放到数组的两个元素里:
int val = 0x1001; // 这个数的低8位是1,高8位是16 arr[0] = val & 0xFF; // 提取低8位,赋值给arr[0] arr[1] = (val >> 8) & 0xFF; // 把val右移8位后提取低8位,赋值给arr[1]
这样arr[0]和arr[1]都会被设为非零值,你的循环就会走到p=2,刚好满足你要的“占用两个内存位置”的需求。
再补个内存机制的关键点
char数组在内存里是一串连续的1字节小格子,每个格子独立。直接给arr[i]赋值,只会修改第i个格子,不管你赋值的是int还是其他类型——编译器都会自动把源类型转换成char(截断高位)。如果想把多字节类型(比如short、int)的完整二进制数据塞进数组的连续格子里,必须用指针转换或者手动拆分字节,而不是直接给单个数组元素赋值。
内容的提问来源于stack exchange,提问作者madmax007

