繁体   English   中英

这个代码在C中是什么?

[英]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]));

我必须编写以下表达式的值:

  1. I [2]
  2. P->Ç

解决方案是:

  1. 7
  2. 10

但是我只是不知道我们如何获得这些价值。 谁能帮我吗? 谢谢= 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_cstruct的指针。 让我们像上面一样简化一下。

   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_cbytes数组的第6个元素开始。 警告 :这是未定义的行为,实际上,在大多数计算机上,它的行为将与以下部分中所述的行为相同。
该结构由一个int和一个char组成。 我假设sizeof(int) = 4并且intchar之间没有填充,为了给定的结果正确,都需要假设两者。
这意味着该结构中的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, 5ii现在是具有从所述元件字符的阵列512 因此, 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM