在C/C++中,除了类型信息之外,数组和指针具有相似的语义。
例如,给定一个3D阵列
int buffer[5][7][6];
位置[2][1][2]处的元素可以通过以下方式访问: 缓冲区[2][1][2] “或者 *(*(*(缓冲区+2)+1)+2) .
遵守以下声明
T *p; // p is a pointer to an object of type T
当指针 P 指向T类型的对象,表达式 *p 是T型的。例如 缓冲区 是由5个二维数组组成的数组类型。表达式的类型 *缓冲区 是“数组的数组(即二维数组)”。
基于上述概念,翻译表达 *(*(*(缓冲区+2)+1)+2) 一步一步地讲清楚。
- 缓冲器 –5个二维数组的数组,即其类型为“5个二维数组的数组”。
- 缓冲区+2 –5个二维阵列中第三个元素的位移。
- *(缓冲区+2) –解引用,即其类型现在是二维数组。
- *(缓冲区+2)+1 –位移以访问7个一维阵列中的第二个元素。
- *(*(缓冲区+2)+1) –解引用(访问),现在是表达式的类型“ *(*(缓冲区+2)+1) “是一个整数数组。
- *(*(缓冲区+2)+1)+2 –位移,以获得一维整数数组中第三个位置的元素。
- *(*(*(缓冲区+2)+1)+2) –访问第三位置的元素(整体表达式类型为 智力 现在)。
编译器计算一个“偏移量”来访问数组元素。“偏移量”是基于“偏移量”数组计算的。在上述情况下, 偏移量=2*( 7 * 6 ) + 1 * ( 6. ) + 2 .那些在 蓝色 颜色是维度, 请注意,偏移计算中不使用较高的尺寸 .在编译时,编译器知道数组的维数。使用偏移量,我们可以访问如下所示的元素,
element_data = *( (int *)buffer + offset );
并非总是可以在编译时声明数组的维度。有时我们需要将缓冲区解释为多维数组对象。例如,当我们处理在运行时确定尺寸的3D图像时,通常的数组下标规则就不能使用。这是因为在编译时缺少固定的维度。考虑下面的例子,
int *base;
哪里 基础 指的是代表三维尺寸图像的大图像缓冲区 长x宽x高 其中l、b和h是变量。如果我们想访问位置(2,3,4)处的元素,我们需要计算元素的偏移量
偏移量=2*(b x h)+3*(h)+4 元素位于 基准+偏移 .
进一步概括,给定起始地址(例如 基础 )大小不一的[ 长x宽x高 ]维度,我们可以在任意位置访问元素( a、 b,c )通过以下方式,
数据=*(基数+a*( b x h )+b*( H )+c); //请注意,我们没有使用更高的维度 L .
相同的概念可以应用于任意数量的维度。我们不需要更高的维度来计算多维数组中任何元素的偏移量。 这就是我们将多维数组传递给函数时忽略高维的原因 .只有当程序员迭代有限数量的高维元素时,才需要高维。
一个C/C++谜题,预测以下程序的输出
int main() { char arr[5][7][6]; char (*p)[5][7][6] = &arr; /* Hint: &arr - is of type const pointer to an array of 5 two dimensional arrays of size [7][6] */ printf ( "%d" , (&arr + 1) - &arr); printf ( "%d" , ( char *)(&arr + 1) - ( char *)&arr); printf ( "%d" , (unsigned)(arr + 1) - (unsigned)arr); printf ( "%d" , (unsigned)(p + 1) - (unsigned)p); return 0; } |
输出:
1
210
42
210
幸亏 大学生 指出错误。
— 文基 。如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请发表评论。