C中的这段代码是什么?

时间:2014-04-01 12:47:34

标签: c arrays pointers

我有以下代码:

   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. 对 - &以及c
  3. 解决方案是:

    1. 7
    2. 10
    3. 但我只是不知道我们如何得到这个价值观。有人可以帮我吗?谢谢= D

3 个答案:

答案 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并且intchar之间没有填充,这两者都需要假设您的给定结果是正确的。
这意味着结构中的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现在是一个数组具有512元素的字符。因此,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 *类型,并将其分配给pp->c(*p).c的语法糖。因此,它访问与sizeof(int)指向的地址偏移p的地址处的值。你的机器上的sizeof(int)是4.这意味着(*p).c访问bytes数组的第(10 + 4)=第10个元素(即索引9处的元素)。

请注意,上述语句违反了strict aliasing rule,因此会调用未定义的行为。