你如何解释下面这行代码?
int (*arrayABC)[10];
在我的教科书中,它说我们有一个指向整数数组第 0 个元素的指针。
不过我不太明白。
我的解释:我们有一些变量,它的值是某个地址。该地址就是 UNNAMED 整数数组的第 0 个元素的地址。基本上我们有一个指向第 0 个元素的指针。
那么为什么要有一个指向指针的指针呢?
这是一个指向数组的指针。它不是指向指针的指针。数组和指针是不同的。数组有一个地址,但数组is不是地址。数组是一系列连续的元素。
此指针指向整个数组而不仅仅是第一个元素,就像
float *
指向整个浮点数而不仅仅是第一个字节一样。
如果您有例如:
int foo[10];
int (*arrayABC)[10] = &foo;
那么表达式
(*arrayABC)
和 foo
是相同的。例如。 foo[3]
与 (*arrayABC)[3]
相同。
如果你有一个类型为
T
的对象,那么指向该对象的指针的声明如下
T obj;
T *ptr = &obj;
现在让我们按以下方式定义类型
T
typedef int T[10];
因此上面的代码
T obj;
T *ptr = &obj;
可以使用 typedef 定义重写
int obj[10];
int (*ptr)[10] = &obj;
在这两种情况下,当
T
是某种抽象类型并且 T
是 int[10]
的别名时,ptr 是指向对象的指针。在最后一种情况下,ptr
是一个指向10
类型的int
元素数组的指针。即ptr
指向的对象具有数组类型。数组和指针是不同的类型。
尝试以下简单的演示程序
#include <stdio.h>
int main( void )
{
typedef int T[10];
T a;
T *pa = &a;
printf( "%zu\n", sizeof( *pa ) );
int b[10];
int ( *pb )[10] = &b;
printf( "%zu\n", sizeof( *pb ) );
}
它的输出是
40
40
如您所见,这两个值都等于 10 个元素的整数数组的大小。所以指针指向数组。
如果你写
int *arrayABC[10];
您将获得一个由 10 个类型为
int *
的指针组成的数组。
如果你写
int (*arrayABC)[10];
您将获得一个指向 10 个整数的数组的指针。
在我的教科书中,它说我们有一个指向整数数组第 0 个元素的指针。
你的教科书……措辞很糟糕,我们就这样吧。它是一个指向
int
的 10 元素数组的指针。
我可以看到这本书是从哪里来的。鉴于声明
int (*a)[10];
表达式 *a
将具有类型
int [10]
(
int
的 10 元素数组)。但是,除非该表达式是
sizeof
或一元
&
运算符的操作数,否则它将从
int [10]
类型转换(“衰减”)为
int *
,并且表达式的值将是数组的第一个元素:
Expression Type "Decays" to Value
---------- ---- ----------- -----
*a int [10] int * Address of first element of the array;
equivalent to `&(*a)[0]`.
因此,如果我调用类似的函数
foo( *a );
函数
实际接收到的将是指向所指向数组的第一个元素的指针(其类型将是int *
,而不是
int **
)。所以实际上,是的,
a
经常会导致表现为指向数组第一个元素的指针;然而,它的type不是“指向
int
的指针”,并且类型很重要。给定:int (*a)[10];
int **b;
然后你会得到以下不同的行为:
sizeof *a vs. sizeof *b
a + i vs b + i (also applies to a++ vs b++)
[]
有更高的“优先级”
int *A[7]; // [] then *
int (*A)[7]; // * then []
因此,如果您想要单个指针,请使用
()
将其设置为高“优先级”
int *(*A[4])[7];
[4] of * to
[7] of * to
int
int *(*(*A)[4])[7]; // single pointer to
int *(* [4])[7]; // array of pointers to
int * [7]; // array of pointers to
int ; // PROFIT!!!