我无法理解这种类型的铸造

Amo*_*ngh 2 c arrays pointers type-conversion

我曾经做过型铸造用intchar,但不与指针,所以我张贴了这个问题.

#include <stdio.h>
int main() {
    int a[4] = { 1, 2, 6, 4 };
    char *p;
    p = (char *)a;   // what does this statement mean?
    printf("%d\n",*p);
    p = p + 1;        
    printf("%d",*p);  // after incrementing it gives 0 why?
}
Run Code Online (Sandbox Code Playgroud)

第一次调用printf给出了数组的第一个元素.在p=p+1它给出之后0.为什么?

Ed *_* S. 5

让我们设想一个相当典型的平台,其中一个字节是8位,内存使用little-endian字节排序排列,a int表示内存中的4个字节.在这个平台上,值的1布局如下:

00000001 00000000 00000000 00000000
^
the first element of 'a'
Run Code Online (Sandbox Code Playgroud)

p声明为char(非int)指针,并初始化为指向数组的第一个元素a.char此平台上的A 表示一个字节.int上面解释为a 的值char看起来像这样:

00000001 -------- -------- --------
|      |
 ------
 char is only 8 bits wide
Run Code Online (Sandbox Code Playgroud)

所以,无论我们读取一个字节还是四个字节,即我们是否读取,*p或者a[0]值是1.但是,当你递增p一个指针时char,它现在指向内存中的下一个字符,这是下一个字节:

00000001 00000000 00000000 00000000
00000001 00000000 -------- --------
^        ^        ^        ^
p       p+1      p+2      p+3       ...
Run Code Online (Sandbox Code Playgroud)

a[1]指向下一个int(2),p[1]指向下一个char,即0.


另外,您实际上偶然发现了一种确定给定处理器是使用小端还是大端字节顺序的方法.如果系统是big-endian(最重要的字节优先),那么你的第一个printf将打印0.这是因为内存布局会发生变化:

0000000 00000000 00000000 00000001
^
the first element of 'a'

0000000 -------- -------- --------
^
p
Run Code Online (Sandbox Code Playgroud)

如果您有多个以big-endian顺序排列的字节,表示值1,并且您只读取第一个字节,则可以使用其值(10)来测试机器的字节顺序:

int n = 1;
if(*(char*)&n == 1)
    // little endian
else
    // big endian
Run Code Online (Sandbox Code Playgroud)