注意&arr
是完整的 3 维 char 数组的地址,而arr
指向第一个元素是 2 维 char 数组。如下图所示:
0xbf8ce2c6
+------------------+ ◄-- arr = 0xbf8ce2c6
| 0xbf8ce2f0 |
| +------------------+ ◄-- arr + 1 = 0xbf8ce2f0
| | 0xbf8ce31a | |
| | +------------------+ ◄-- arr + 2 = 0xbf8ce31a
| | 0xbf8ce344 | | |
| | | +------------------+ ◄-- arr + 3 = 0xbf8ce344
| | 0xbf8ce36e | | | |
| | | | +------------------+ ◄-- arr + 4 = 0xbf8ce36e
| | | | | | | | | |
+---|---|---|--|---+ | | | | Each are 7*6, 2-Dimensional
| | | | | | | | Consists Of 42 bytes
+---|---|--|-------+ | | |
| | | | | |
+---|--|-----------+ | |
| | | |
+--|---------------+ |
| |
+------------------+
The diagram show:
1. How a 3-dimensional can be interpreted as series of 2-dimensional arrays
2. Here (arr + i) points to a 2-D array
3. Notice difference between: (arr + i + 1) - (arr + i) = 0x2a = 42, where i = [0, 4]
类型&arr
是char(*)[5][7][6]
char 3D-array 的地址[5][7][6]
。&arr
和之间的价值差异&arr + 1
是5 * 7 * 6 * sizeof(char)
= 210
。
因为 的大小char[5][7][6]
是5 * 7 * 6 * sizeof(char)
。
在您的代码&arr
中指向 3-D 数组和&arry + 1
下一个 3-D 数组(在我们的代码中不存在)。
在codepade检查此工作代码:
int main()
{
char arr[5][7][6];
printf(" &arr : %p", &arr);
printf(" &arr+1: %p", &arr + 1);
return 0;
}
输出:
&arr : 0xbf5dd7de
&arr+1: 0xbf5dd8b0
(&arr + 1) - (&arr)
= 0xbf5dd8b0 - 0xbf5dd7de
= 0xd2
=之间的区别210
。
在您的第二个 printf 中:
printf("%d\n", (char *)(&arr + 1) - (char *)&arr);
您将 type 的地址类型转换char(*)[5][7][6]
为 plain (char*)
,并且因为 sizeofchar[5][7][6]
是210
两个地址都是 210 远。(记住sizeof(char) == 1
)。这就是输出的原因:210
现在正如我在第一个语句中所说,arr
是第一个元素的地址,它是一个二维字符数组。类型arr
是char(*)[7][6]
。现在有一个元素(大小为 的二维数组6 * 7 * sizeof(char) = 42
)。
(注意:您可以将 3-D 数组视为一维数组,其中每个元素都是一个二维数组)。
在您的第三个 printf 中:
printf("%d\n", (unsigned)(arr + 1) - (unsigned)arr);
您将类型转换为无符号值(但不是地址/指针类型)。arr + 1
和之间的区别arr
是42 * sizeof(char)
= 42
(即等于 的大小char[7][6]
)。所以 printf 语句输出:42
.
注意: 您应该阅读sizeof (int) == sizeof (void*)? ,因为您正在将地址类型转换为值。并且这种转换没有完全定义。(我的解释是你的输出和我给出的输出)。
如需进一步说明,请在codepade上查看以下工作代码:
int main()
{
char arr[5][7][6];
printf(" arr : %p\n", arr);
printf(" arr+1: %p", arr + 1);
return 0;
}
输出是:
arr : 0xbf48367e
arr+1: 0xbf4836a8
(arr + 1) - (arr)
取= 0xbf4836a8
- 0xbf48367e
= 0x2a
=之间的差异42
。
最后打印:
printf("%d\n", (unsigned)(p + 1) - (unsigned)p);
&arr+1
只需取和&arr
=之间的差异210
(类似于第二个 printf),因为p
它是指向 3-D 字符数组 (= &arr
) 的指针。而且您正在将其类型转换为值类型(不是指针类型)。
另外,(只是为了理解目的而添加,我想读者会发现它有帮助),
arr
让我们了解 sizeof 运算符和使用运算符之间的另一个区别,&arr
这将有助于您更深入地理解概念。对于第一次阅读:sizeof
操作员
将sizeof
运算符应用于数组标识符时,结果是整个数组的大小,而不是数组标识符所表示的指针的大小。
在codepade检查此工作代码:
int main()
{
char arr[5][7][6];
printf(" Sizeof(&arr) : %lu and value &arr: %p\n", sizeof(&arr), &arr);
printf(" Sizeof(arr) : %lu and value arr : %p\n", sizeof(arr), arr);
printf(" Sizeof(arr[0]): %lu and value a[0]: %p\n",sizeof(arr[0]), arr[0]);
return 0;
}
它的输出:
Sizeof(&arr) : 4 and value &arr: 0xbf4d9eda
Sizeof(arr) : 210 and value arr : 0xbf4d9eda
Sizeof(arr[0]): 42 and value a[0]: 0xbf4d9eda
正如我在图表中所示,arr
指向二维数组的第一个元素。所以因为arr
= (arr + 0)
。现在使用*
取消引用运算符 at(arr + 0)
给出地址 so 的值*(arr + 0) = arr[0]
。
- 注意
sizeof(arr[0])
给出 42
= 7 * 6 * sizeof(char)
。这在概念上证明了一个 3 维数组,但值得注意的是 2 维数组的数组。
因为上面在我的回答中很多时候我都写过:“size of char[5][7][6]
is 5 * 7 * 6 * sizeof(char)
。” 所以我在@codepade下面添加了一个有趣的代码:
int main(){
printf(" Char : %lu \n", sizeof(char));
printf(" Char[5] : %lu \n", sizeof(char[6]));
printf(" Char[5][7] : %lu \n", sizeof(char[7][6]));
printf(" Char[5][7][6]: %lu \n", sizeof(char[5][7][6]));
return 1;
}
输出:
Char : 1
Char[5] : 6
Char[5][7] : 42
Char[5][7][6]: 210