3

我无法理解 CCS C 编译器的代码。代码是:

addr[0] =  *(((char*)&block_number)+2);

我猜“ &block_number”是名为“block_number”的变量的地址。之后我迷路了。

4

4 回答 4

1

让我们分解一下:

*(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.

于 2013-01-01T22:16:54.930 回答
1

当一个人不知道 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 charthen*(((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)总是 1char是一个字符,这就是为什么如果你想分配内存,你不需要为 malloc 指定 length*sizeof(char) 。你只做:

int length = 20;
void *mem = malloc(length);
于 2013-01-01T22:37:46.347 回答
0
  1. &block_number是对象的地址block_number

  2. (char*)&block_number将该地址视为字节数组中第一个元素的地址。我们称它为指针p,它是一个指向-的指针char

  3. *(((char*)&block_number)+2)因此*(p + 2)是 ,与 相同p[2],即它表示数组的第三个元素。

换句话说,您正在获取对象二进制表示的第三个字节block_number(并将其存储起来addr[0])。

于 2013-01-01T22:19:39.140 回答
0

你是对的。&block_number 是该变量的地址,它被转换为 char 并在值中添加 2。例如,如果 &block_number 是 0x0000,那么如果平台上的 sizeof(char) 为 2,或者无论大小是什么,那么在执行该行之后 addr[0] 将包含 0x0002。

于 2013-01-01T22:02:39.517 回答