我在C中的2D数组上一直在做各种各样的问题。每个问题就像在我头上碰到另一个椰子,因为每个问题都使用不同的方法。例如,有些人使用"采取2D数组(如[2] [4]),现在这创建了两个数组,其中一个数组的大小为2,包含每行2D数组的地址(就像这个有两行,每个都有四个值)&#34 ;.While其他方法视为连续的1D数组表示。现在使用哪种方法。一个合适的记忆图将是一个很大的帮助。下面是锻炼的样本问题。
int main()
{
unsigned int x[4][3] = {{1, 2, 3}, {4, 5, 6},
{7, 8, 9}, {10, 11, 12}};
printf("%u, %u, %u", x+3, *(x+3), *(x+2)+3);
}
output:2036,2036,2036
现在,如果它是第一个方法,那么x + 3和*(x + 3)的地址是一样的呢?
答案 0 :(得分:4)
C语言中的内置数组总是使用" second"方法(根据您的编号),没有例外。每次声明1D,2D,3D或者其他-D数组时,就像在示例代码中一样,该数组在内存中作为连续的内存块布局 - 作为"组合的一维数组"尺寸(即所有尺寸倍增)。
"第一"方法只能用于"手动"组装好的阵列(所谓的"锯齿状的"或者#34;参差不齐的#34;阵列)。该语言不会使用这种方法来表示explcitly声明的多维数组。
但是,使用%u
格式说明符打印指针值是未定义的行为。停止这样做。函数printf
提供%p
格式用于打印指针。
在x + 3
表达式中,x
类型的对象unsigned [4][3]
隐式衰减为unsigned (*)[3]
类型的值 - 指向x[0]
子阵列的指针。根据指针算术规则,x + 3
是unsigned (*)[3]
类型的值,指向x[3]
子数组。
同样的事情最初发生在*(x + 3)
表达式中,除了x + 3
(再次指向x[3]
子阵列)被*
运算符取消引用并变为{ {1}}子阵列本身。在x[3]
参数的上下文中,此子阵列立即衰减为print
类型的值,指向unsigned *
。
因此,即使x[3][0]
和x + 3
的结果具有不同的类型,它们仍指向内存中完全相同的位置。这就是指针值在数字上看起来相同的原因。
在下面的简单例子中会发生同样的事情
*(x + 3)
输出将显示两个指针的相同数值。你的例子有点复杂,但实质上是相同的。