**(iptr+3)
如果 iptr 是一个数组指针,那么和之间有什么区别吗*iptr[3]
5 回答
不,而且,令人惊讶的是(或不是),也等同于*(3[iptr])
.
对编译器来说,不,没有区别。两种形式最终都访问相同的元素。
但是,如果您正在为编译器编写代码,那么您就找错了受众。你的代码应该写得好像下一个维护它的人是一个知道你住在哪里的精神病患者。
换句话说,代码的可读性和可维护性,让编译器自己担心优化(a)。为此,我总是更喜欢这种array[index]
形式,*(array+index)
因为前者阐明了意图:访问数组元素。
(a)当然,与大多数规则一样,也有例外。但是,与大多数例外情况一样,它们很少而且相差甚远,因此该建议成立。
**(iptr+3)
和*iptr[3]
之间没有什么相同的
*iptr[3]
是表示数组中地址为 no-3 的元素的指针
**(iptr+3)
就像 iptr 比它的 **(6) 大 3
由于指针算法,它是相同的。
假设您有一个自定义类型
typedef struct
{
/* add some parameters here */
} MyStruct;
然后创建一个这种类型的向量
MyStruct xMyStructArray[20];
例如,当您要访问第三个元素时,可以通过以下方式之一进行:
MyStruct xValue = xMyStructArray[2]; // index starts from zero
MyStruct xValue = xMyStructArray + 2;
xMyStructArray 单独被视为指向第一个数组元素的指针。
xMyStructArray == &(xMyStructArray[0])
C/C++ 在连续的内存单元中创建一个数组,当您使用 [] 运算符时,您告诉它访问该数组的相应单元,从对应于第一个数组元素地址的指针地址开始。所以它知道你的类型的大小,并去正确的地址。
指针算法的工作原理相同。当您将 1 与指针相加时,编译器会检查与该指针对应的类型的大小,然后转到与该类型兼容的内存中的下一个位置。
两者都是一样的,编译器只会将iptr[3]
and3[iptr]
视为*(iptr+3)
and *(3+iptr)
。
int a[5][10] = {0};
考虑这个二维数组。这里的a[i][j]
意思*(*(a+i) + j)
,所以我们也可以写like i[a][j]
which表示*(*(i + a) + j)
。
但是i[j][a]
是错误的,因为它会被视为*(*(i + j)+a)
哪个是错误的。*(i+j)
将导致崩溃(未定义的行为)。