数组指针,(*ptr)[] 与 *ptr[] 有何区别?

3

当我试图理解指向这个数组的指针时,遇到了一个奇怪的问题。

#include <iostream>

int main() {
    using namespace std;

    short tell[3]{1, 2, 3};

    short (*pas)[3] = &tell;

    cout << (*pas)[2] << endl;
    cout << *pas[2] << endl;

    cout << endl;

    return 0;
}

这两个输出给出了不同的值。

第一个输出是正确的,为3。

然而,对于第二个输出,似乎返回一个随机数,每次都不同。

这两者之间有什么区别?


1
第二个是未定义行为。第一个等同于pas [0] [2],第二个等同于pass [2] [0] - Marek R
只需使用-Wall启用警告即可。您将会得到以下警告信息:"warning: array subscript 6 is outside array bounds of 'short int [3]' [-Warray-bounds] 11 | cout << *pas[2] << endl;" - JHBonarius
2个回答

3
你声明了一个指向整个数组的指针。
short (*pas)[3] = &tell;

所以要获取指向的对象(数组),您需要像解除引用指针一样对其进行取消引用,例如:
*pas

现在,这个表达式产生一个对数组tell的左值引用。因此,您可以使用下标运算符来访问数组的元素。

cout << (*pas)[2] << endl;

后缀下标运算符的优先级高于一元运算符*
也就是说,这个表达式:
*pas[2]

等价于下面的表达式

*( pas[2] )

这意味着您正在尝试访问超出已分配数组的对象(数组),导致未定义行为。

如果您有一个二维数组,例如:

short tell[3][3] =
{ { 1, 2, 3 },
  { 4, 5, 6 },
  { 7, 8, 9 }
};

并且像这样初始化指针pas

short (*pas)[3] = tell;

表达式pass[2]将产生数组的第三个元素,即{ 7, 8, 9 }。在这种情况下,您可以再应用一个下标运算符来访问数组的一个元素,例如:

pass[2][2]

该段落包含值为9

上述表达式也可以不使用下标运算符进行重写,如下所示:

*( *( pass + 2 ) + 2 )

1
一个简单的例子可以是:

int *ptr[10];

这是一个包含10个int*指针的数组,与您所想象的不同,它不是指向包含10个整数的数组的指针。
int (*ptr)[10];

这是一个指向包含10个整数的数组的指针。

我认为它与int *ptr;相同,因为两者都可以指向数组,但给定的形式只能指向包含10个整数的数组。

您还可以查看this的示例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接