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

来源:互联网 发布:人工智能上色 painter 编辑:程序博客网 时间:2024/06/10 18:16

首先我们来看一段程序:

#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个字节。

0 0