我目前正在学习如何在c
中操作多维数组我有以下代码
int t[2][2] = {
{12, 14},
{16, 18}
};
int * p = t[0];
printf("%d\n", *(p + 2));
并打印16
。
但我的问题是,我正在访问第一个只包含两个int元素的数组的第三个元素,这种访问的行为是否未定义?
我理解访问一维数组的超出索引的行为是未定义的。例如
int ar[] = {11, 22};
printf("%d\n", ar[2]); //behaviour undefined
但多维数组也是如此吗?
答案 0 :(得分:2)
C将多维数组存储为连续的存储区。但是你所做的仍然是我在前面第一行所说的,它仍然是未定义的行为。
可能看起来很奇怪,但您可以阅读this来查看更多信息。
事情在C
中,2d数组的概念是通过使用数组的数组实现的,其中数组的每个元素都是数组。
所以想一想,
p
是指向第一个数组的衰减指针。当您访问p[2]
但您可能获得相关输出时,它仍然是未定义的行为。
t
是一个数组,其每个元素都是一个数组(t[0],t[1]
)。
现在t[0]
是一个数组,当分配给p
时会被衰减并指向第一个元素。现在您访问未定义行为的p[2]
,因为您正在访问有效索引为0
和1
的数组。
你可能觉得很奇怪 - 在C
工作的事情并不总是意味着它被标准定义和备份。在同一个说明中,这似乎是合乎逻辑的事情,但它并不是最明确的做事方式。
答案 1 :(得分:0)
请理解p [2] [2]是用于数组偏移计算的语法糖,并且实际上只有一个连续(线性)内存的单维数组。
它确实比那更微妙,但这将有助于您在开始时理解。
你可以声明一个指向整数数组的指针数组,并分别分配(或分配一次并计算指针),但是这会更晚出现。
答案 2 :(得分:0)
c中的多维数组以行主格式存储在内存中。意思是,您的示例数组将存储为[12,14,16,18]。这意味着当你访问p加2的内存中的点时,你真正发生的事情是你在内存中的p的最开始,然后在开始的p之后的数据类型的大小的2倍。这使得指针指向p中的第3个元素,即16。