以下声明的区别是什么:
int* arr1[8];
int (*arr2)[8];
int *(arr3[8]);
理解更复杂的声明的一般规则是什么?
以下声明的区别是什么:
int* arr1[8];
int (*arr2)[8];
int *(arr3[8]);
理解更复杂的声明的一般规则是什么?
当前回答
在指向整数的指针中,如果指针是递增的,那么它将移动到下一个整数。
在指针数组中,如果指针增加,则跳转到下一个数组
其他回答
最后两个的答案也可以从C中的黄金法则中扣除:
使用后声明。
int (* arr2) [8];
如果你解引用arr2会发生什么?你得到一个8个整数的数组。
int * (arr3 [8]);
如果从arr3中取一个元素会怎样?你得到一个指向整数的指针。
这也有助于处理指向函数的指针。以sigjuice为例:
Float *(*x)(void)
解引用x会发生什么?你得到一个不带参数调用的函数。当你调用它时会发生什么?它将返回一个指向浮点数的指针。
不过运算符优先级总是很棘手。然而,使用圆括号实际上也会令人困惑,因为声明紧随使用之后。至少,对我来说,直觉上arr2看起来像一个8个指向int型的指针的数组,但实际上是相反的。只是需要一些时间去适应。如果你问我,有足够的理由总是在这些声明中添加注释:)
编辑:示例
顺便说一下,我偶然发现了以下情况:一个函数有一个静态矩阵,并使用指针算术来查看行指针是否出界。例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUM_ELEM(ar) (sizeof(ar) / sizeof((ar)[0]))
int *
put_off(const int newrow[2])
{
static int mymatrix[3][2];
static int (*rowp)[2] = mymatrix;
int (* const border)[] = mymatrix + NUM_ELEM(mymatrix);
memcpy(rowp, newrow, sizeof(*rowp));
rowp += 1;
if (rowp == border) {
rowp = mymatrix;
}
return *rowp;
}
int
main(int argc, char *argv[])
{
int i = 0;
int row[2] = {0, 1};
int *rout;
for (i = 0; i < 6; i++) {
row[0] = i;
row[1] += i;
rout = put_off(row);
printf("%d (%p): [%d, %d]\n", i, (void *) rout, rout[0], rout[1]);
}
return 0;
}
输出:
0 (0x804a02c): [0, 0]
1 (0x804a034): [0, 0]
2 (0x804a024): [0, 1]
3 (0x804a02c): [1, 2]
4 (0x804a034): [2, 4]
5 (0x804a024): [3, 7]
Note that the value of border never changes, so the compiler can optimize that away. This is different from what you might initially want to use: const int (*border)[3]: that declares border as a pointer to an array of 3 integers that will not change value as long as the variable exists. However, that pointer may be pointed to any other such array at any time. We want that kind of behaviour for the argument, instead (because this function does not change any of those integers). Declaration follows use.
(附注:请随意改进此示例!)
根据经验,右一元操作符(如[]、()等)优先于左一元操作符。因此,int *(*ptr)()[];将是指向一个函数的指针,该函数返回一个指向int的指针数组(在括号之外尽快获得正确的操作符)
在指向整数的指针中,如果指针是递增的,那么它将移动到下一个整数。
在指针数组中,如果指针增加,则跳转到下一个数组
按照K&R的建议,使用cdecl程序。
$ cdecl
Type `help' or `?' for help
cdecl> explain int* arr1[8];
declare arr1 as array 8 of pointer to int
cdecl> explain int (*arr2)[8]
declare arr2 as pointer to array 8 of int
cdecl> explain int *(arr3[8])
declare arr3 as array 8 of pointer to int
cdecl>
反之亦然。
cdecl> declare x as pointer to function(void) returning pointer to float
float *(*x)(void )
我认为我们可以使用简单的规则。
example int * (*ptr)()[];
start from ptr
PTR是指向的指针 向右走。它是")"现在向左,它是"(" 出来向右走”()“所以 指向一个不接受参数" go left "并返回一个" go right "指向的指针的函数 由整数“向左”组成的数组。