数组和指针虽然存在关联,但并不相同。

这里我借用一下《POINTERS ON C》中8.8问题。 问题如下:

8. 下面的声明取自某个原文件:

  int a[10];
  int *b = a;

但在另一个不同的源文件中,却发现了这样的代码:

  extern int  *a;
  extern int  b[];
  int x, y;
  ...
  x = a[3];
  y = b[3];

请解释一下,当两条赋值语句执行时会发生什么?(假定整形和指针的长度都是4字节)

我们都知道把语法糖[]拆开就是*(a + 3), *(b + 3)。然后a和b又是赋值过去的,最起码他们的值是相等的
我开始想的是,这两条赋值语句是把a和b的值取出来然后加上3*4的偏移量相对寻址,然后分别赋值给x和y;

依照我的想法形成的汇编代码应该是:
  movl 12+a(%rip), %eax
  movl %eax, -4(%rbp)
  movq 12+b(%rip), %eax
  movl 12(%rax), %eax
  movl %eax, -8(%rbp)

但我在gcc 下形成的汇编和我想的有那么一点不同  

它处理指针和数组的方式是不同的。首先a(指针)它是先提取指针值(这里用到的是a(%rip), 间接提取a的值),a指向的是首个元素,那么最后和12相加的是首个元素的值,假如首个元素值是0x34000那么最后赋值给x的是,*(0x34012)至于这个地址存放的是什么值就未知了。

b(数组)的话,它是先给b加上12然后再间接访问,假设b是0x433300 ,那么最后赋值给y的是*(0x33312)

两者相差甚远!

只有在全局变量上声明错误才会出现这样情况比如:在1.c中声明int a[10];在2.c中声明extern int *a;
我不思其解

原文地址:https://www.cnblogs.com/BMing/p/10505322.html