2 c++ arrays pointers declaration implicit-conversion
int q[10]={0};
cout << q << endl;
cout << &q << endl;
cout << &q[0] << endl;
Run Code Online (Sandbox Code Playgroud)
输出是
0x7fffd4d2f860
0x7fffd4d2f860
0x7fffd4d2f860
Run Code Online (Sandbox Code Playgroud)
现在当我这样做时->
int *r=q; // allowed
int *r=&q[0] // allowed
int *r=&q // not allowed
Run Code Online (Sandbox Code Playgroud)
为什么在本质上是同一件事时不允许第三次赋值?
如果你有一个数组声明如下
T a[N];
Run Code Online (Sandbox Code Playgroud)
哪里T是某种类型说明符,那么指向数组的指针将被声明为
T ( *p )[N] = &a;
Run Code Online (Sandbox Code Playgroud)
一般规则如下。如果您有一个多维数组(包括一维数组),例如
T a[N1][N2][N3];
Run Code Online (Sandbox Code Playgroud)
那么这个声明你可以重写
T ( a[N1] )[N2][N3];
Run Code Online (Sandbox Code Playgroud)
要获得指向数组第一个元素的指针,只需按以下方式替换括号中的内容
T ( *p )[N2][N3] = a;
Run Code Online (Sandbox Code Playgroud)
如果你想得到一个指向整个数组的指针,那么重写数组的声明,如
T ( a )[N1][N2][N3];
Run Code Online (Sandbox Code Playgroud)
并进行替换
T ( *p )[N1][N2][N3] = &a;
Run Code Online (Sandbox Code Playgroud)
将此与标量对象的声明和指向它的指针进行比较。
例如
T obj;
Run Code Online (Sandbox Code Playgroud)
您可以像这样重写声明
T ( obj );
Run Code Online (Sandbox Code Playgroud)
现在要获得指向您可以编写的对象的指针
T ( *p ) = &obj;
Run Code Online (Sandbox Code Playgroud)
当然在这种情况下括号是多余的,上面的声明相当于
T *p = &obj;
Run Code Online (Sandbox Code Playgroud)
至于这个代码片段
int q[10]={0};
cout << q << endl;
cout << &q << endl;
cout << &q[0] << endl;
Run Code Online (Sandbox Code Playgroud)
和它的输出
0x7fffd4d2f860
0x7fffd4d2f860
0x7fffd4d2f860
Run Code Online (Sandbox Code Playgroud)
然后在表达式中使用的数组指示符在极少数例外情况下被转换为指向它们的第一个元素的指针。
所以实际上这两个表达式q和&q[0]在这些语句中
cout << q << endl;
cout << &q[0] << endl;
Run Code Online (Sandbox Code Playgroud)
是等价的。另一方面,数组本身的地址是数组占用的内存范围的地址。在范围的开头是数组的第一个元素。所以这三个表达式给出了相同的结果:数组占用的内存范围的地址。