我无法理解 CCS C 编译器的代码。代码是:
addr[0] = *(((char*)&block_number)+2);
我猜“ &block_number
”是名为“block_number”的变量的地址。之后我迷路了。
我无法理解 CCS C 编译器的代码。代码是:
addr[0] = *(((char*)&block_number)+2);
我猜“ &block_number
”是名为“block_number”的变量的地址。之后我迷路了。
让我们分解一下:
*(ptr+2)
相当于:
ptr[2]
这里,ptr
是一个char*
指向 的地址block_number
。
所以说block_number
是这样一个结构的实例:
struct {
char a;
char b;
char c;
char d;
} block_number
然后addr[0]
将包含的值c
(假设这些值之间没有空格)。这是因为指向的指针block_number
被转换为 a char*
,然后像数组一样被索引。
所以基本上,这会读取block_number
.
当一个人不知道 block_number 是什么时,这有点难说。假设它是一个值为 的整数0xdeadbeef
:
unsigned int block_number = 0xdeadbeef;
在小端架构(即 x86)上:
*(char *)&block_number is 0xef,
*(((char *)&block_number) + 1) is 0xbe and
*(((char *)&block_number) + 2) is 0xad.
虽然如果 block_number 是 a char
then*(((char *)&block_number) + 2)
可以指向一个相邻的变量,假设 block_number 在堆栈上声明:
char a = 0xab, b = 0xbc, block_size = 0xcd, c = 0xde, d = 0xef;
然后((char *)&block_size + 2
可以指向 iea
并*(((char *)&block_size + 2)
返回0xab
。因为堆栈最常见的顺序是从最大地址到低地址:
heap stack
[... -> <- d | c | block_size | b | a ]
[... -> <- 0xef | 0xde | 0xcd | 0xbc | 0xab ]
但这永远不能确定,因为 C 对编译器的定位没有任何约束,a
并且该位置可能未定义。
因为sizeof(char)
它总是 1
。char
是一个字符,这就是为什么如果你想分配内存,你不需要为 malloc 指定 length*sizeof(char) 。你只做:
int length = 20;
void *mem = malloc(length);
&block_number
是对象的地址block_number
。
(char*)&block_number
将该地址视为字节数组中第一个元素的地址。我们称它为指针p
,它是一个指向-的指针char
。
*(((char*)&block_number)+2)
因此*(p + 2)
是 ,与 相同p[2]
,即它表示数组的第三个元素。
换句话说,您正在获取对象二进制表示的第三个字节block_number
(并将其存储起来addr[0]
)。
你是对的。&block_number 是该变量的地址,它被转换为 char 并在值中添加 2。例如,如果 &block_number 是 0x0000,那么如果平台上的 sizeof(char) 为 2,或者无论大小是什么,那么在执行该行之后 addr[0] 将包含 0x0002。