我有以下代码:
unsigned char bytes[12] = { 1, 2, 3, 4,5, 6, 7, 8,9, 10, 11, 12};
char *i;
struct i_and_c {int x;char c;} *p; //What's the meaning of *p? Is it a pointer
//to the struct "i_and_c"???
i = (char *) (&(bytes[4]));
p = (struct i_and_c *) (&(bytes[5]));
我必须写下列表达式的值:
解决方案是:
但我只是不知道我们如何得到这个价值观。有人可以帮我吗?谢谢= D
答案 0 :(得分:2)
你得到的值显然来自bytes数组,但为什么你会得到这些值?
unsigned char bytes[12] = { 1, 2, 3, 4,5, 6, 7, 8,9, 10, 11, 12};
这里bytes
可以被视为指向数组第一个元素的unsigned char*
,即1.现在让我们打破这个指针算术,是吗?
首先,让我们将i
的类型从char*
更改为unsigned char*
,因为这就是它的真实或应该。
unsigned char *i;
i = (unsigned char *) (&(bytes[4]));
括号表示访问第n个元素,即第5个元素,因为索引从0开始。这意味着我们可以将它们重写为简单的加法和解引用。
unsigned char *i;
i = (unsigned char *) (&(*(bytes+4)));
等等,我们真的得到了我们从取消引用指针获得的值的地址吗?是的,我们这样做。我们同时应用操作及其反转。那是什么意思?我们可以简单地将两个部分都留下来!
unsigned char *i;
i = (unsigned char *) (bytes+4);
所以现在i
是指向bytes
的第5个元素的指针,因为我们从指向第一个元素的指针开始并向其添加4。现在i[2]
与*(i+2)
相同。如果i
是指向第5个元素的指针,i+2
是指向第7个元素的指针,则i[2]
是bytes
的第7个元素,恰好是7。
现在我们已经解决了这个问题,让我们继续讨论下一个问题,但它有点棘手。让我们更改代码,以便更清楚它的作用。
struct i_and_c {int x;char c;};
struct i_and_c *p;
p = (struct i_and_c *) (&(bytes[5]));
*p
确实是指向struct
类型i_and_c
的指针。让我们以与上面相同的方式简化它。
struct i_and_c {int x;char c;};
struct i_and_c *p;
p = (struct i_and_c *) (bytes+5);
好的,现在我们有一个指向struct i_and_c
的指针,它从bytes
数组的第6个元素开始。 警告:这是未定义的行为,实际上,在大多数机器上,它的行为与下一节中描述的相似。
该结构由一个int后跟一个char组成。我假设sizeof(int) = 4
并且int
和char
之间没有填充,这两者都需要假设您的给定结果是正确的。
这意味着结构中的int
将从第6个字节元素到第9个元素(包括它)。而char
将在此之后出现,这意味着它是第10个元素。现在p->c
与(*p).c
相同,这意味着您希望获得该字符。 bytes
的第10个元素是10,所以这就是你得到的结果。
我希望我的解释有所帮助:)。
答案 1 :(得分:0)
此处bytes
是一个char
数组,因此数组的每个元素都是1个字节。
结构定义如下,
struct i_and_c{
int x;
char c;
} *p;
是的,* p是指向已定义结构的指针。
现在,当您将5th
数组bytes
元素的地址ei,5
传递给i
时,i
现在是一个数组具有5
到12
元素的字符。因此,i[2]
是third
数组的i
元素,即7
。
现在,您要将6th
数组的bytes
元素的地址存储到p
中。 p
包含int
(4字节)和char
(1字节)。即,前4个字节存储在x
中,下一个字节存储在c
中。因此,p->c
存储10
。
明白了??
希望它有所帮助...
答案 2 :(得分:0)
struct i_and_c {int x; char c;} *p;
上述语句定义了一个新类型struct i_and_c
,并定义了一个变量p
,它是指向struct i_and_c
类型对象的指针。
i = (char *) (&(bytes[4]));
以上获取数组bytes
的第5个元素的地址(因为数组的索引从零开始)并将其转换为char *
类型。 i[2]
计算为*(i + 2)
,这意味着byte
数组的第7个元素。因此,i[2]
的计算结果为7.接下来是以下语句
p = (struct i_and_c *) (&(bytes[5])); // violates strict aliasing rule
将bytes
数组的第6个元素的地址转换为struct i_and_c *
类型,并将其分配给p
。 p->c
是(*p).c
的语法糖。因此,它访问与sizeof(int)
指向的地址偏移p
的地址处的值。你的机器上的sizeof(int)
是4.这意味着(*p).c
访问bytes
数组的第(10 + 4)=第10个元素(即索引9处的元素)。
请注意,上述语句违反了strict aliasing rule,因此会调用未定义的行为。