深入理解指针、指向数组的指针和数组名的的区别

首先我们来看一段程序:

#include <stdio.h>

int main(int argc,char *argv[])
{
        int numbers[5] = {1, 2, 3, 4, 5};
        printf("&numbers: %p\n", &numbers);
        printf("&numbers+1: %p\n", &numbers+1);
        printf("numbers: %p\n", numbers);
        printf("numbers+1 :%p\n", numbers+1);

        int *p = numbers;
        printf("sizeof(&numbers): %d\n", sizeof(&numbers));
        printf("sizeof(numbers): %d\n", sizeof(numbers));
        printf("sizeof(*numbers): %d\n", sizeof(*numbers));

        printf("sizeof(*p): %d\n", sizeof(*p));
        printf("sizeof(p): %d\n", sizeof(p));

        return 0;
}

这段程序的输出结果:

下面来分析输出结果:

我们先来分析 numbers 和 &numbers:

  1.首先,用%p将 numbers 和 &numbers打印出来,它们的地址自然都是一样的,因为它们都等于数组的首地址。 但是,我们将它们的地址+1后打印出来,结果却大相径庭。那么,这是为什么呢?

  其实,虽然 numbers 和 &numbers 都代表数组首地址, 但是它们所指向元素的类型却是不一样的。&numbers 所指向的类型是int [5] 型的数组,占据5*sizeof(int) = 20 个字节。而numbers 指向的类型是 numbers[0] 这种 int 类型数组的成员,注意,是成员不是整个数组!它的 大小只有 sizeof(int) = 4 个字节。所以它们的地址+1后, 与原地址相差分别为20和4。

 

 2.接下来,我用 sizeof 对 &numbers, numbers, *numbers 求长度。结果分别为8,20,4。经过分析, &numbers 是一个地址,在64位下经 sizeof 输出为8, 这个并无疑问。

但是,sizeof(numbers) 结果等于20, 却与上面的分析相悖,其实这里有个很重要的点就是, 数字名并不是指针! 虽然数组名可以在很多时候作为指针来使用,如上文中所说

numbers 指向类型为 int的数组成员, 但是在用于 sizeof 时, numbers 是作为它的本身数组名来使用, 它指向的实体其实是一种数据结构,这个结构就是数组。所以 numbers

进行求长度操作,等价于对数组求长度,结果自然是20。而后面对 sizeof(*numbers) 等价于 sizeof(*(numbers+0)),即对 numbers[0] 求长度,它的结果是sizeof(int) = 4。

  总而言之,我们一定要认识到,数组名不是指针!虽然数组名很多时候可以作为指针来使用(如在上文1中),但要在进行 sizeof 这种操作时, 数组名本来的意义就体现了,

它所代表的就是数组这种数据结构。

 

 3.另外还有一种错误的认识,就是想要求数组长度时,千万不能对指向数组的指针求长度!

程序中指针变量p指向数组首地址, sizeof(*p) 等价于 sizeof(numbers[0],结果为 sizeof(int) =4。

而 sizeof(p) 呢, p是一个指针变量,对一个指针变量求长度,更不能代表对数组求长度,它的结果在64位下就是一个地址的长度,为8个字节。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值