【发布时间】:2017-02-12 00:39:40
【问题描述】:
我遇到过类似以下的 C 代码:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *a = malloc(200*sizeof(int));
int i;
for (i = 0; i < 200; i++)
{
a[i] = i;
}
int (*b)[10] = (void*) a;
printf("\nsizeof(int):\t%d\n", sizeof(int));
printf("\nb[0]:\t%d\n", b[0]);
printf("\na:\t%d\n", a);
printf("\nb[19]:\t%d\n", b[19]);
printf("\na+190:\t%d\n", a+190);
printf("\nb[0][8]:\t%d\n", b[0][8]);
printf("\nb[19][9]:\t%d\n", b[19][9]);
return 0;
}
根据我的理解,int (*b)[10] = (void*) a; 行试图将指针b(它应该指向一个10 个整数的数组)分配给数组a 的起始地址作为空指针类型转换。我本来希望b[i] 与i=0..9 的a[i] 保存相同的数据(对于b,除0 到9 之外的任何索引都会导致一些未定义的行为)。但是,该程序会产生类似于以下示例的输出:
sizeof(int): 4
b[0]: 9768976
a: 9768976
b[19]: 9769736
a+190: 9769736
b[0][8]: 8
b[19][9]: 199
很明显,b 已经变成了一个包含 20 个指针的数组,每个元素指针都指向 a 数组的唯一部分,每个部分对应 10 个整数(或 40 个字节)。有人可以解释一下int (*b)[10] = (void*) a; 到底是做什么的吗?具体来说,类型转换(void *) 如何帮助将整个a 分布到b 的多个元素中?如果没有 (void *) 演员表,上述代码将无法编译。
【问题讨论】:
-
“我本来希望 b 是一个只能访问 a 的前 10 个元素的指针” - 那么您是否还期望
int *b = (void *)a;只能访问一个int? -
没有。我想我在那句话中没有很好地表达自己。我将编辑我的问题以更好地解释我的意思。
-
b[0]是一个由前 10 个整数组成的数组,b[1]是接下来的 10 个整数,以此类推 -
正确。这就是我从我发布的输出中得出的结论。我只是不确定这在
int (*b)[10] = (void*) a;语句中是如何工作的。我在在线搜索中找不到其他此类示例。这似乎是一种为大型数组块创建单独指针的方法,这是我之前没有遇到过的。 -
原理和
int *b = (void *)a一样,只是你指向的是10个整数而不是1个整数。
标签: c arrays pointers void-pointers