for循环中*(& a - i)的含义。那是乘法吗?

时间:2017-01-11 20:47:02

标签: c

当我遇到这个时,我正准备即将开始的考试:

char a = 'a';
char b = 'b';
int ai[] = { 1, 2 };
int i = 0;
     

假设字长为32位,int为32位,并且内存分配的顺序与从地址68开始的声明相反。

     

绘制一个图表,显示执行以下代码行的效果。

for (i = 0; i < 8; i++)
    *(&a – i) = 'z';

这可能听起来很奇怪,但我是C的新手,这是我第一次见到for循环的乘法。这个for循环的解释和应用它的乘法将是值得赞赏的。

2 个答案:

答案 0 :(得分:3)

这不是乘法,而是取消引用指针。但是,*(&a – i)i > 0时已经是未定义的行为。然而,在您的特定问题中,有独角兽和UB是过去的事情,并且您必须假设变量分配以相反的顺序完成它们被声明,并且没有任何填充,这将覆盖变量{{ 1}}和b

答案 1 :(得分:3)

我认为我们可以假设这是一个理论问题,如果在问题中没有定义的额外假设(即字节顺序,填充) - 问题是可以回答的。但是,正如@chux指出的那样,有针对此类行为的标准。因为,如果允许,代码会导致堆栈内存损坏。作为一个考试问题,它实际上是要求你绘制哪个内存被破坏的图表。

如果我正确地解释了这个问题,那么一个可能的存储器表示(假设整数是LSB,有1个字节填充,并且声明的顺序相反):

| Addr | Value | Desc | | ---- | ----- | ------------------------------ | | 55 | 0x00 | // int i = 0; | | 56 | 0x00 | | | 57 | 0x00 | | | 58 | 0x00 | | | 59 | 0x01 | // int ai[] = { 1, 2 }; | | 60 | 0x00 | | | 61 | 0x00 | | | 62 | 0x00 | | | 63 | 0x02 | | | 64 | 0x00 | | | 65 | 0x00 | | | 66 | 0x00 | | | 67 | 0x62 | // char b = 'b'; | | 68 | 0x61 | // char a = 'a'; |

展开的循环评估为:

[68] = 0x7a; // 'z'; [67] = 0x7a; // 'z'; [66] = 0x7a; // 'z'; [65] = 0x7a; // 'z'; [64] = 0x7a; // 'z'; [63] = 0x7a; // 'z'; [62] = 0x7a; // 'z'; [61] = 0x7a; // 'z';

所以记忆由变量表示,a,b和ai []数组的部分将被破坏。 (纳入@chux关于endianess的观察。另外,我根据@chux和@Peter A调整了ai []元素出现的顺序.Schneider评论。)

| Addr | Value | Desc | | ---- | ----- | ----------------------------------------- | | 55 | 0x08 | // int i = 8; | | 56 | 0x00 | | | 57 | 0x00 | | | 58 | 0x00 | | | 59 | 0x01 | // int ai[] = { 0x7a7a0001, 0x7a7a7a7a }; | | 60 | 0x00 | | | 61 | 0x7a | | | 62 | 0x7a | | | 63 | 0x7a | | | 64 | 0x7a | | | 65 | 0x7a | | | 66 | 0x7a | | | 67 | 0x7a | // char b = 'z'; | | 68 | 0x7a | // char a = 'z'; |