数组指针未返回预期值

时间:2018-01-24 18:11:10

标签: c arrays pointers

根据不同的主题,我了解到使用'&'使用数组不会返回双指针而是指针数组。

int x[9] = {11, 22,33,44,55,66,77,88,99};
int (*xpt)[9] = &x;    <---This is the focus of this thread.

以下代码编译并执行。

#include <stdio.h>
int main () 
{
    int x[9] = {11, 22,33,44,55,66,77,88,99};
    int (*xpt)[9] = &x;

    printf("xpt[0] = %d\n", xpt[0]);
    printf("xpt[0][0] = %d\n", xpt[0][0]);
    printf("xpt[0][1] = %d\n", xpt[0][1]);
    printf("*xpt[0] = %d\n", *xpt[0]);
    printf("*xpt[1] = %d\n", *xpt[1]);

   return 0;
}

这是输出。

> ./runThis
xpt[0] = 155709776
xpt[0][0] = 11
xpt[0][1] = 22
*xpt[0] = 11
*xpt[1] = 32766

问题与输出有关。 由于xpt是一个数组指针(我假设) xpt [0] 只是显示第一个值11的地址。

我对以下两行有效感到有些惊讶。

  xpt[0][0] = 11
  xpt[0][1] = 22

在考虑之后,它几乎是有意义的,因为我认为 xpt [0] * xpt 可以互换使用,直到以下两行反驳:< / p>

  *xpt[0] = 11
  *xpt[1] = 32766

为什么 * xpt [0] 会返回预期值但不会 * xpt [1]

1 个答案:

答案 0 :(得分:5)

获取数组元素应为(*xpt)[0]。否则你在这里有未定义的行为。因为您正在访问一些不受约束的内存,或者您不应该/或您没有权限。

同样不要被xpt[0][0]感到惊讶,这与我上面所说的相同。

原因是 - *xpt[1]取消引用甚至没有指向数组的任何元素的内存。这是未定义的行为。

123456789XXXXXXXXXX
^        ^
|        |
xpt[0]   xpt[1]

此处1234....表示数组的元素,xpt[1]表示数组之外。

数组下标([])的优先级高于取消引用(*)。因此,当您编写*xpt[1]时,它将首先计算xpt[1],然后尝试获取它的值,这会导致程序中出现未定义的行为。

另外,为了让您更直观地了解如何理解这一点 -  指针操作取决于它指向的内容。这里当你宣布

int (*xpt)[9] = &x;

它说xpt是指向9个元素的int数组的指针。现在,您使用x的地址进行初始化。现在想想它指向的是什么?它是数组对象x。那么如果我们这样做xpt[1]会有什么意义呢?下一个数组对象(如果有)。这就是为什么我们首先到达地址然后取消引用它以获取数组(*xpt),现在使用数组下标来获取正确的元素。

int* xpt = &x

是编译器会抱怨的东西。它将类型int(*)[9]分配给int* - 这是错误的。类型对于指针很重要 - 这就是编译器会抱怨的原因。

您可能会问为什么*xpt[0] 11不是2233等等,这是一件有趣的事情?

事情是xpt[0]xpt指向的数组。数组xpt[0]转换(衰减)到指向数组(xpt[0][0])的第一个元素(xpt[0])的指针,然后解除引用({{1} })它。这就是为什么你把数组的第一个元素作为值。