如何理解复杂的数组声明指针,以及&

时间:2015-08-06 18:06:48

标签: c++ arrays pointers

以下是两行代码:

int (*parry)[10]   = &arr   // Line # 1
int *(&arrRef)[10] = ptrs   // Line # 2

第1行

parry是一个指向大小为10的int数组的指针。
这是否意味着:

  • parray[1]指向arr
  • 的地址
  • parray[2]指向arr
  • 的地址
  • ...
  • parray[10]指向地址或arr

我何时会使用Line # 1

解决方案:

#include <iostream>
int main(
{
 int arr[10] = { 3, 54  };
 int (*parry)[10] = &arr;
 std::cout << (*parry)[0] << " " << (*parry)[1] << " "  << (*parry)[3] << "  " << parry[4] << std::endl;
 return 0;
}

输出:

  

3,54,0,索引为4的arr的十六进制地址。

似乎parry[0]内的指针是指向与索引关联的arr的指针。所以,parry[0] ---&gt; arr[0]

第2行

arrRef是对大小十个指针的int数组的引用。 arrRef引用了ptrs 这是否意味着:

  • arry[1]是一个int指针? ...
  • arry[10]是一个int指针?

可以使用哪个例子?

4 个答案:

答案 0 :(得分:7)

如有疑问,请参阅Clockwise/Spiral Rule

int (*parry)[10] = &arr;

parry是一个指向10 int s。

数组的指针
int *(&arrRef)[10] = ptrs;

arrRef是对指向int的10个指针的数组的引用。

示例:

int main()
{
   int arr[10];
   int* ptrs[10];

   int (*parry)[10] = &arr;
   int *(&arrRef)[10] = ptrs;
}

答案 1 :(得分:1)

我认为在这个陈述中

//line1// int (*parry)[10] = $arr
                            ^^^  ^^

有一个拼写错误

必须有

//line1// int (*parry)[10] = &arr;
                            ^^^  ^^

假设arrint[10]类型的数组。例如

int arr[10];

这个宣言

int (*parry)[10] = &arr;

声明指向整个数组的指针。

至于此声明

//line2// int *(&arrRef)[10] = ptrs;
                                  ^^^

然后假设ptrs是类型int *[10]的数组。数组的元素具有类型int *。他们是指针。

这个宣言

int * (&arrRef)[10] = ptrs;

声明对此数组的引用。实际上,引用是数组的别名。

在C ++ 2014中,您可以更简单地定义对数组的引用。

例如

decltype( auto )arrRef = ( ptrs );

这是一个示范程序

#include <iostream>


int main()
{
    int a[10];

    decltype( auto )ra = ( a );

    std::cout << sizeof( a ) << std::endl;
    std::cout << sizeof( ra ) << std::endl;

    ra[0] = 10;

    std::cout << a[0] << std::endl;
    std::cout << ra[0] << std::endl;
}    

程序输出

40
40
10
10

答案 2 :(得分:1)

现在我已经清理了你的问题,我可以看到它不是我原先的想法。你说:

  

parray是一个指向大小为10的int数组的指针

很明显你已经找到了顺时针/螺旋/ cdecl的东西。

  

所以它的意思是:...... parray [10]指向arr的地址

首先,C ++中的数组从零开始编制索引,因此如果有10个元素,则可以访问arr[0] .. arr[9]; arr[10]将是第十一个,因此超出界限。

现在,让我们分开你的句子:

  

parray是指针

对,它不是一个数组,它是一个指针。现在,让我们考虑它指向的是什么:

  

一个大小为10的int数组

好的,如果指向,那么*parray必须是(引用)原始数组。

因此,(*parray)[0]是数组的第一个元素,等等。

请注意,您可以通过打印出来并查看所获得的内容,轻松测试您对所有这些的直觉。您可以看到指针,并能够比较地址,或者您将看到整数值,或者您将获得(希望提供信息)编译错误。试试吧!

哦,并且:

  

我何时会使用第1行?

一般情况下,只有你需要重新安置它。例如,如果要根据某些逻辑选择两个不同数组中的一个,然后......在选择的任何一个上执行进一步的逻辑。

接下来,你说

  

arrRef是对十个指针大小的int数组的引用。

正确!

  

arrRef是指ptrs

不,arrRef 指的是一个数组,该数组的大小为10,其10个元素是指向int的指针。 注意这与第一个数组的类型不同!

由于引用可以使用与它们引用的内容相同的语法,因此我们可以使用arrRef作为数组。

所以,arrRef[0]是数组的第一个元素,它是一个指向int的指针。

  

可以使用哪个例子?

使用引用数组的唯一常见原因是避免指针衰减,允许模板推断出元素的数量。

答案 3 :(得分:0)

对于解析C声明,用Kernighan和Ritchie的话来说,记住“语法是试图使声明和使用同意”是很有价值的(K&amp; R,TCPL,5.12)。换句话说,您可以将声明视为表达式,只需按正确的顺序应用运算符即可。这将显示声明的标识符必须具有的类型。

例如,在int (*parry)[10]中,您首先应用*运算符,因为它位于括号中。这表明parray是一个指针。然后应用[]运算符,指示解除引用的结果是一个数组; 10表示元素的数量。获取的元素的类型为int。总结:parray是指向int数组的指针。

C ++中的引用声明无法以这种方式解决,因为实际上没有运算符可以创建引用,或者取消引用;这两个操作都隐含在C ++中。 &符号仅用于表示声明中的引用(可能有些令人困惑,因为在表达式中它用于获取地址)。但是,如果您将声明中的&视为*替换来表示引用而不是指针,那么您仍应该能够解析任何声明。