将int数组转换为short*时,为什么为元素赋值会覆盖整个整数?

Bry*_*mas 1 c int casting short

我正在观看Jerry Cain的Programming Paradigms Lecture 3视频,其中展示了在int数组和短数组之间进行元素分配后的效果.本质上,参数是如果你要分配一个int数组元素arr[3] = 128,然后暂时将int数组转换为short*并赋值arr[6] = 2,那么arr [3]应该变为128 + 512 = 640,因为2将被解释为在2 ^ 9位置.代码演示:

#include <stdio.h>

int main() {
  printf("sizeof(int) is %lu\n", sizeof(int));
  printf("sizeof(short) is %lu\n", sizeof(short));
  int arr[5];
  arr[3] = 128;
  ((short*)arr)[6] = 2;
  printf("arr[3] is equal to %d\n", arr[3]); //expect 640, get 2 instead
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我运行此代码时,我得到以下输出:

sizeof(int) is 4
sizeof(short) is 2
arr[3] is equal to 2
Run Code Online (Sandbox Code Playgroud)

我希望arr [3]等于640,但它只是等于2.我当然是一个C菜鸟 - 任何人都能解释一下吗?

Jon*_*ler 5

我认为Big-endian vs little-endian.

代码本质上是特定于平台的(官方的,几乎肯定是未定义的行为).我不确定你应该被教导,但是,我猜,这是另一个问题.

2分配给四个字节中的两个arr[3].如果您已分配,((short *)arr)[7]则可能会看到预期结果.

你在测试什么机器(什么类型的CPU)?


关于第二个想法-虽然部分问题可能是大端VS小端,另一个问题是shortVS char.这里有一些代码可以显示解决方案的各种途径:

#include <stdio.h>

int main(void)
{
    printf("sizeof(int) is %lu\n", sizeof(int));
    printf("sizeof(short) is %lu\n", sizeof(short));
    int arr[5];

    arr[3] = 128;
    ((short*)arr)[6] = 2;
    printf("arr[3] is equal to %8d (0x%08X)\n", arr[3], arr[3]);

    arr[3] = 128;
    ((short*)arr)[7] = 2;
    printf("arr[3] is equal to %8d (0x%08X)\n", arr[3], arr[3]);

    for (int i = 12; i < 16; i++)
    {
        arr[3] = 128;
        ((char *)arr)[i] = 2;
        printf("arr[3] is equal to %8d (0x%08X) i = %d\n", arr[3], arr[3], i);
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

修订后的代码的输出是:

sizeof(int) is 4
sizeof(short) is 2
arr[3] is equal to        2 (0x00000002)
arr[3] is equal to   131200 (0x00020080)
arr[3] is equal to        2 (0x00000002) i = 12
arr[3] is equal to      640 (0x00000280) i = 13
arr[3] is equal to   131200 (0x00020080) i = 14
arr[3] is equal to 33554560 (0x02000080) i = 15
Run Code Online (Sandbox Code Playgroud)

使用GCC 4.2.1 XCode 4.2(LLVM)在MacOS X 10.7.2上进行测试.