引入

我们的前提是下面几个变量:

int array[10];
int *p;
int var;

下面六种赋值之后,变量var的值是否相同?

  • var = array[4]
  • var = *(array + 4)
  • var = 4[array]
  • p = &[array4]; var = *p;
  • var = *(int *) ( (void *)array + 4 * (sizeof(int)))
  • p = &var; *p = *(array + 4);

当然看到这里,如果你已经有非常自信的答案,你当然可以无视这一篇文章后面的部分。

答案

上面六种赋值之后,变量var的值相同。

我们来分析一下这个数组在程序的栈的布局 (这里Address 10568仅为array地址的例子):

+---------------------+-------------+---------+
| Variable Name       | Address     | Value   | 
+---------------------+-------------+---------+
| array               | 10568       | 0      |
|                     |             +---------+
|                     |             | 1      |
|                     |             +---------+
|                     |             | 2      |
|                     |             +---------+
|                     |             | 3      |
|                     |             +---------+
|                     |             | 4      |
|                     |             +---------+
|                     |             | 5      |
|                     |             +---------+
|                     |             | 6      |
|                     |             +---------+
|                     |             | 7      |
|                     |             +---------+
|                     |             | 8      |
|                     |             +---------+
|                     |             | 9      |
+---------------------+-------------+---------+

var = array[4], var = *(array + 4) , var = 4[array], p = &[array4]; var = *p;
这四种其实非常类似,都是已知array是一个int*,在array这个基地址(例子中的10568)上进行四个元素的偏移,因此能落在4号元素的地址上,再讲这个地址视作int*读出int内容。

var = *(int *) ( (void *)array + 4 * (sizeof(int)))
这个写法虽然繁琐,但是非常像对应的汇编代码。(void *)array首先将array转成一个void*,也就是抹去了它int*的原身份。再对这个void*空类型指针进行偏移操作,注意这时候的偏移量不再是4,而是对应4个int对应的Byte量,即4 * (sizeof(int)。最后再将这个空类型指针转化成int*去读取数据。

p = &var; *p = *(array + 4);
利用了另外一个指针p,使这个指针指向变量var。因此可以使用*pvar进行赋值。

另一例子

我们可以练习,考虑一下这个程序的输出。

int array[10];
int *p;
int var;

for(int i = 0; i < 10; i++) array[i]=i;

var = array[4];
printf("%i\n", var);

var = 5[array];
printf("%i\n", var);

var = *(array + 6);
printf("%i\n", var);

p = &array[7];
var = *p;
printf("%i\n", var);

p = array;
var = *p;
printf("%i\n", var);

p = &var;
*p = *(array + 3);
printf("%i\n", var);

输出:

4
5
6
7
0
3

对应的代码:
点击下载


引用和推荐的阅读:

https://stackoverflow.com/a/7...

https://www.tutorialcup.com/c...


罗济高
1 声望1 粉丝