[英]What does this code in C?
我有以下代码:
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
您获得的值显然来自bytes数组,但是为什么要获得这些值呢?
unsigned char bytes[12] = { 1, 2, 3, 4,5, 6, 7, 8,9, 10, 11, 12};
在这里, bytes
可以看作是指向数组第一个元素(即1)的unsigned char*
。现在让我们分解一下指针算法,可以吗?
首先,让我们将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
的第五个元素的指针,因为我们从一个指向第一个元素的指针开始,并向其添加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
实际上是指向类型为i_and_c
的struct
的指针。 让我们像上面一样简化一下。
struct i_and_c {int x;char c;};
struct i_and_c *p;
p = (struct i_and_c *) (bytes+5);
好了,现在我们有了一个指向struct i_and_c
的指针,该struct i_and_c
从bytes
数组的第6个元素开始。 警告 :这是未定义的行为,实际上,在大多数计算机上,它的行为将与以下部分中所述的行为相同。
该结构由一个int和一个char组成。 我假设sizeof(int) = 4
并且int
和char
之间没有填充,为了给定的结果正确,都需要假设两者。
这意味着该结构中的int
将从字节的第6个元素到达第9个元素(包括它)。 char
将紧随其后,这意味着它是第十个元素。 现在p->c
与(*p).c
相同,这意味着您要获取该char。 bytes
的第10个元素是10,所以这就是结果。
希望我的解释有所帮助:)
这里bytes
是一个char
数组,因此数组的每个元素均为1个字节。
像这样定义结构
struct i_and_c{
int x;
char c;
} *p;
因此,* p是指向已定义结构的指针。
现在,当要传递的地址5th
所述的元件bytes
阵列,EI, 5
到i
, i
现在是具有从所述元件字符的阵列5
至12
。 因此, i[2]
是i
数组的third
元素,即7
。
现在,您将bytes
数组的6th
元素的地址存储到p
。 p
包含一个int
(4个字节)和一个char
(1个字节)。 即,前4个字节存储在x
,下一个字节存储在c
。 因此, p->c
存储10
。
明白?
希望能有所帮助...
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 *
type并将其分配给p
。 p->c
是(*p).c
的语法糖。 因此,它访问的地址与p
指向的地址之间的偏移sizeof(int)
处的值。 您的计算机上的sizeof(int)
为4。这意味着(*p).c
访问bytes
数组的第(6 + 4)=第10个元素(即索引9的元素),即10。
请注意,上面的语句违反了严格的别名规则 ,因此调用了未定义的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.