为什么main函数中的最后一个printf没有将值10打印到屏幕上?我知道在ANSI C中,静态分配的矩阵以这种方式在内存中排列:矩阵:矩阵[0][0]、矩阵[0][1]、...、矩阵[0][ColumnsDimension-1]、矩阵[1][0]等
#include <stdio.h>
#include <stdlib.h>
#define dimRighe 20
#define dimColonne 30
int main()
{
int matrice[dimRighe][dimColonne];
int i,j;
for(i=0;i<dimRighe;i++)
for(j=0;j<dimColonne;j++)
matrice[i][j] = i+j;
matrice[0][3] = 10;
i = 0; j = 3;
printf("%d",*matrice[i*dimColonne+j]);
return 0;
}
5条答案
按热度按时间olmpazwi1#
请改用
*(matrice[i * dimColonne] + j)
。zour9fqk2#
为什么main函数中的最后一个printf没有将值10打印到屏幕上?
因为
matrice
是一个数组的数组…matrice[whatever]
是一个数组(在大多数情况下,它会“衰减”为指向其第一个元素的指针)*matrice[whatever]
是数组matrice[whatever]
的第一个元素的内容。7vux5j2d3#
在您的代码中,您有:
由于
i
是0
,因此计算结果为由于
j
是3
,这意味着当你打印
*matrice[3]
的时候,就相当于打印matrice[3][0]
,因为matrice[3]
是一个数组,数组会衰减到指向它第一个元素的指针。但是你根本不想这样做,你应该简单地写
matrice[i][j]
,让编译器来完成这项工作。n3h0vuf24#
变更
简单地说
如果你所担心的只是打印出正确的值。毕竟,这就是你如何赋值的。
如果您是为了了解数组下标是如何工作的,那么有几件事需要记住。
首先,除非它是
sizeof
或一元&
运算符的操作数,或者是用于初始化声明中另一个数组的字符串文字,否则类型为“T
的N元素数组”的表达式将被替换为(“decay to”)类型为“pointer toT
”的表达式,它的值将是数组第一个元素的地址。表达式matrice
是类型为“30个元素的20个元素的数组”的数组表达式。int
“的元素数组;在大多数情况下,它将被转换成类型为“指向int
的30元素数组的指针”或int (*)[30]
的表达式。类似地,表达式matrice[i]
是类型为“指向int
的30元素数组“的表达式,并且在大多数情况下,它将被转换成类型为“指向int
的指针“或&
的表达式。这里有一个方便的表格来记住所有这些:
其次,下标运算
a[i]
被定义为*(a + i)
;也就是说,根据i
个 * 元素 * 计算地址(NOT BYTES)并取消引用结果。例如,如果a
是int
的数组,那么*(a + i)
将给予a
之后的第i
个整数的值。如果an是struct foo
的数组,那么*(a + i)
将给予你a
之后的第i
个结构体的值。指针算法总是考虑基类型的大小,所以你不需要担心偏移量中的 * 字节数 *。同样的逻辑也适用于多维数组,你只需要对每个维度递归地应用规则:
请注意,您应该 * 几乎从来没有 * 必须手动执行这些解引用;编译器知道数组访问是什么样子的,并可以相应地优化代码。在适当的情况下,手动写出取消引用可能会导致比使用下标操作符更慢的代码。
你可以像索引一维数组一样索引二维数组,如下所示:
但是我不会这样做(表达式的类型并不完全匹配)。请注意,您将
i
乘以 * 行数 *,而不是列数。inn6fuwd5#
你也可以这样打印:
首先,它将矩阵转换为字节数组,然后,它获取所需整数的起始地址,然后从该地址读取的前四个字节重建整数。
这是一个有点矫枉过正,但有趣的解决方案的问题。