指向数组的指针究竟如何?

时间:2015-06-25 10:23:12

标签: c arrays pointers

任何人都可以解释如何打印这些值以及为什么p和* p返回相同的值。

#include <stdio.h>

int main(){
    int arr[] = {1,2,3,4};
    int (*p)[4];

    p = &arr;

    printf("%u %u %u %u %u", arr, &p, p, *p, **p);
    p++;
    printf("\n%u %u %u %u %u", arr, &p, p, *p, **p);

    return 0;
}
我机器上的

输出如下:

2686768 2686764 2686768 2686768 1

2686768 2686764 2686784 2686784 2686792

2 个答案:

答案 0 :(得分:1)

你的例子很乱,但指针算术一般都很混乱,对类型不尊重。从类型理论的角度来看,你的例子没有意义。

arr指向数组的第一个元素。请注意,arr[i]相当于*(arr+i)arr是一个类型为int的4元素数组。

p是指向int类型的4元素数组的指针。

您将p的地址分配给&arr,其地址与arr相同(但类型不同,请参阅下文)。

然后你把它打印出来,这意味着:

  • arr是数组第一个元素的地址
  • &pp
  • 的地址
  • p&arr(整个数组)的地址,arr的地址,是数组中第一个元素的地址
  • *parr的地址,它是数组中第一个元素的地址
  • **p正在尝试取消引用*p,这是解除引用arr,实际上是数组的第一个元素

增加p++之后:arr&p不会改变,其余的会改变

来自C Book

  

我们已经强调过,在大多数情况下,数组的名称是   转换成第一个元素的地址;一个值得注意的例外   当它是sizeof的操作数时,如果它是必不可少的   与malloc有关的事情就是工作。另一种情况是数组名称   是&amp;的操作数。运营商地址。在这里,它被转换   进入整个数组的地址。有什么区别?即使   你认为地址在某种程度上是“相同的”,关键   区别在于它们有不同的类型。对于n的数组   类型为T的元素,则第一个元素的地址具有类型   '指向T';整个数组的地址都有类型'指针指向   类型为T'的n个元素的数组;显然非常不同。这是一个   例子:

int ar[10];
int *ip;
int (*ar10i)[10];       /* pointer to array of 10 ints */

ip = ar;                /* address of first element */
ip = &ar[0];            /* address of first element */
ar10i = &ar;            /* address of whole array */

答案 1 :(得分:1)

  

printf(“%u%u%u%u%u”,arr,&amp; p,p,* p,** p);

  • arr是数组本身。当在这样的表达式中使用数组名称时,它会衰减到指向第一个元素的指针,因此您将获得该元素的地址。
  • &p是存储数组指针的地址。您将此视为与其他地址相同的唯一原因是因为您正在运行优化代码。禁用优化或将p声明为static volatile,您将看到更改。
  • p是数组的地址,当然与第一个元素的地址相同。
  • *p为您提供一个数组类型,然后衰减为指向第一个元素的指针。这与arr相同。
  • **p为您提供数组中第一个元素的内容。

p++将通过指针算法的规则增加指针。因此p指向的地址将增加它所指向的大小,这是一个4个整数的数组,每个4个字节大(假设为32位)。因此,p现在将指向有效内存之外,如果您尝试访问它,则会发生任何事情。