int (*ptr)[10];
我期待ptr
成为一个10
整数指针数组。
我不明白它是如何指向10
整数数组的指针。
ptr
是“指向 10 个 int 数组的指针”类型。在您的声明中,它未初始化,因此它不指向任何对象。让它指向一个数组:
int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
// initialize in the declaration:
int (*ptr) [10] = &arr;
// or after:
int (*ptr) [10];
ptr = &arr;
指向 10 s 数组的指针int
意味着指向 10 个元素的数组,不多也不少,或者如果您有一个 2D 数组,则指向此类数组的给定行,前提是它正好有 10 列.
int
指向,的指针数组int *ptr[10]
就是这样,它有 10 个指向int
和指向每个指针的指针,您可以分配一个 的地址int
,它可以是数组的一部分,也可以不是数组的一部分。
示例 1:
int (*ptr)[10];
int arr[10];
ptr = &arr; //correct, arr has 10 elements
int arr2[12];
ptr = &arr2; //not correct, arr2 does not have 10 elements
这样的指针可用于指向行数不确定但列数固定的二维数组。
示例 2:
int arr[5][10];
ptr = arr; //correct, pointer to the 1st row of a 2D array with 10 cols
ptr++; //now points to the second row
int arr2[5][12];
ptr = arr2; //not correct, incompatible pointer, has too many cols
示例 3:
int(*ptr)[3];
int arr[2][3] = {{1, 2, 3}, {4, 5, 7}};
ptr = arr;
printf("%d", ptr[1][2]); //array indexing is identical as using arr[1][2]
指针数组与指向数组的指针
当需要动态分配/释放内存时,指向数组的指针的优势就来了:
具有 4 行和 5 列的二维数组的示例:
int (*ptr)[5];
ptr = calloc(5, sizeof *ptr); //simple assignment
free(ptr); //simple deallocation
int *ptr[5];
for (int i = 0; i < 5; i++) //each pointer needs it's own allocation
ptr[i] = calloc(5, sizeof **ptr);
for (int i = 0; i < 5; i++) //each pointer needs to be freed
free(ptr[i]);
另一方面,如果你有一个指针数组,你可以有一个不均匀的数组,也就是说第一行可以有 10 个int
,但第二行可以有 20 个:
int *ptr[5];
for (int i = 0; i < 5; i++)
ptr[i] = calloc( i + 1, sizeof **ptr);
在上面的示例中,二维数组的第一行空间为 1 int
,第二行空间为 2 ,第三行空间为 3 ,依此类推。
I like to read it like this: (great answers already posted)
int (*ptr) [10];
^ a pointer
^ to an array of 10
^ ints
vs
int* ptr[10];
^ array of 10
^ pointer to int
声明给出了如何使用变量的“图片”。1 int (*ptr) [10]
表示“当(*ptr)[i]
在表达式中使用时,它是一个int
。” 由此,我们可以推导出 的类型ptr
:
(*ptr)[i]
是int
,(*ptr)
必须是 的数组int
。(*ptr)
是 的数组int
,*ptr
必须是 的数组int
。*ptr
是 的数组int
,ptr
必须是指向 的数组的指针int
。1 Kernighan 和 Ritchie,C 编程语言,1978 年,第 90 页。
In both expressions and declarations, the postfix operators []
and ()
have higher precedence than unary *
. Because of this, the declarations
T *a[N]; // a is an array of pointer to T
T *f(); // f is a function returning pointer to T
are parsed as
T *(a[N]); // result of a[i] will be dereferenced
T *(f()); // result of f() will be dereferenced
If you want a pointer to an array or a pointer to a function, you must explicitly group the *
operator with whatever the pointer expression will be:
T (*a)[N]; // result of *a will be subscripted
T (*f)(); // result of *f will be executed
The pointer does not have to be a simple identifier - you can have a function that returns a pointer to an array:
T (*f())[N]; // result of *f() will be subscripted
or an array of pointers to functions
T (*a[N])(); // result of *a[i] will be executed