1
头图
  1. a 通过数组名可以直接获得数组的地址
  2. &a 使用取地址符同样也可以获取数组的地址
  3. &a[0] 取数组首元素地址也可以取得数组的地址
#include <stdio.h>

int main(void) {
    int a[6] = {1, 2, 3, 4, 5,6};
    printf("a: %p\n",a);         
    printf("&a: %p\n",&a);       
    printf("&a[0]: %p\n",&a[0]);  
}

/* 
*   a: 0061FF08    
*   &a: 0061FF08   
*   &a[0]: 0061FF08
*/

它们编译输出的值都是一模一样的,看似没有什么问题,但是在实际的运算当中可能就会遇到一些意想不到的问题了,比如以下的代码:

int main(void) {
    int a[6] = {1, 2, 3, 4, 5, 6};
    
    printf("a: %p\n",a);         // 0061FF08
    printf("&a: %p\n",&a);       // 0061FF08
    printf("&a[0]: %p\n",&a[0]);  // 0061FF08
    

    printf("a + 1: %p\n",a + 1);        
    printf("&a + 1: %p\n",&a + 1);      
    printf("&a[0] + 1: %p\n",&a[0] + 1); 
}

给每一个地址都+1,a + 1,&a + 1,&a[0] + 1,进行一个简单的地址运算,编译输出:

a: 0061FF08
&a: 0061FF08
&a[0]: 0061FF08

a + 1: 0061FF0C
&a + 1: 0061FF20
&a[0] + 1: 0061FF0C

这时候就会发现运算的结果并不一样,为什么&a + 1和其他两个不相等呢?
明明取得的地址都是一样的,都是+1,但是结果却不相等。

其实&aa&a[0] 取地址是有区别的,虽然都可以取得相同的数组地址,但是它们类型并不相同。

&a 的类型是指向整个数组的指针,因此&a + 1将会指向整个数组的下一个位置,即a数组后面的内存空间。

a&a[0] 的类型都是指向数组首元素的指针,因此a + 1、&a[0] + 1都会指向数组的下一个元素的地址,即a数组中的第2个元素的地址。

因此,虽然取得的数组地址相同,但是它们的步长不同,导致了指向的位置不同

解析:
1.a 和 &a[0]取地址的类型是一样的,a + 1 和 &a[0] + 1 ,都是指向数组中第2个元素的地址,第1个元素的地址是0061FF08,int型数组相相邻元素地址之间相差4个字节,因此第2个元素的地址就是0061FF0C,这里的步长是4。

2.&a是指向整个数组的指针,&a + 1会指向整个数组的下一个位置,因此步长应该是整个数组的大小,在这里a数组的大小是24,数组地址0061FF08 + 24 ,最后算得0061FF20。

到这里就已经真相大白......在实际的使用当中,我们应该分不同的情况选择取数组地址的方式,通常都是使用a和a[0]的方式,这两种方式一样,如果使用&a就应该注意了。

有趣的坑我来踩,免费的关注点一个吧~


屠龙少年
1 声望1 粉丝

学习两年半的嵌入式练习生。