数组被"清零"的困惑

Ape*_*123 1 c arrays

#include<stdio.h>
#include<stdlib.h>

static char mem[4];

int main()
{
    int* A = (int*)(mem);

    mem[0] = 0;
    mem[1] = 1;
    mem[2] = 2;
    mem[3] = 3;

    int i;
    A[0] = 5;

    for (i = 0; i<4; i++)
    {
        printf("%d\t", mem[i]);
    }

    printf("\n");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,为什么打印5 0 0 0而不是5 1 2 3?为什么阵列"消失了?"

Jea*_*bre 6

在你的情况下

A[0] = 5;
Run Code Online (Sandbox Code Playgroud)

5整数,其大小大于char(2,4,8,取决于).

你的系统似乎是小端,所以5写在第一个char位置,然后是零.

请注意,如果sizeof(int)是8(因为它可能在某些系统上发生),您的代码是不安全的并且会触发未定义的行为,因为它会覆盖通过mem阵列的内存(更不用说可能导致操作速度减慢甚至在某些处理器上崩溃的错位问题)

这就是为什么我们必须遵守严格的别名规则以避免"撒谎到编译器",例如,创建一个union以便编译器可以调整对齐和检查大小.

这个其他问答是相关的:当地址不是字对齐时,在C中将char*地址转换为int*时会发生什么?

  • @ZanLynx - 看起来不像一个,*是*一个.您可以使用`char*`来访问任何对象类型.您不能使用`int*`来访问声明为`char [4]`的对象.这是不一样的. (4认同)
  • @ZanLynx - 我称之为未定义的行为.允许实现定义它,但它不是ISO C使它没问题 (2认同)
  • @ZanLynx - 通过字符类型访问,而具有*字符(数组)类型的对象*是不一样的.当OP写入5时,OP会通过`int`类型进行访问. (2认同)
  • @ZanLynx:`A [0] = 5`不"将字节写入字符数组."在C标准的术语中,它通过`int`类型的左值访问`char`数组的对象, [C 2011(N1570)6.5 7](/sf/answers/3416002551/)明确禁止这一点. (2认同)