矩阵访问 Ansi C
为什么主函数中的最后一个 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;
}
Why the last printf in the main function doesn't print to the screen the value 10?
I know that in ANSI C, statically allocated matrix are arranged in memory in this way:
matrix: matrix[0][0], matrix[0][1],...,matrix[0][ColumnsDimension-1],matrix[1][0], etc
#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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用
*(matrice[i * dimColonne] + j)
代替。Use
*(matrice[i * dimColonne] + j)
instead.因为
matrice
是一个数组的数组...并且
matrice[whatever]
是一个数组(在大多数情况下“衰减”为指向其第一个元素的指针),而
*matrice[whatever]
是第一个元素的内容数组matrice[whatever]
的元素。Because
matrice
is an array of arrays ...and
matrice[whatever]
is an array (which in most circunstances "decays" to a pointer to its first element)and
*matrice[whatever]
is the contents of the first element of the arraymatrice[whatever]
.在您的代码中,您有:
由于
i
是0
,因此计算结果为由于
j
是3
这意味着当您打印时
*matrice[3]
相当于打印matrice[3][0]
,因为matrice[3]
是一个数组。并且数组会衰减为指向其第一个元素的指针。但你根本不想这样做。您应该简单地编写
matrice[i][j]
并让编译器完成工作。In your code you have:
Since
i
is0
this evaluates toSince
j
is3
this meansWhen you print
*matrice[3]
that is equivalent to printingmatrice[3][0]
becausematrice[3]
is an array. And an array decays to a pointer to its first element.But you don't want to do it this way at all. You should simply write
matrice[i][j]
and let the compiler do the work.请更改
为简单
如果您所担心的只是打印出正确的值, 。毕竟,这就是您分配的方式。
如果您这样做是为了了解数组下标如何工作的练习,那么您需要记住几件事。
首先,除非它是
sizeof
或一元&
运算符的操作数,或者是用于初始化声明中的另一个数组的字符串文字,类型的表达式“T
的 N 元素数组”将被替换为(“衰减为”)“指向T
的指针”类型的表达式,其值将是数组的第一个元素。表达式matrice
是一个类型为“int
的30元素数组的20元素数组”的数组表达式;在大多数情况下,它将转换为“指向int
的 30 元素数组的指针”或int (*)[30]
类型的表达式。类似地,表达式matrice[i]
是“30-element array ofint
”类型的表达式,并且在大多数情况下它会被转换为“30-element array ofint
”类型的表达式指向int
”或int *
的指针。下面是一个方便记住所有这些的表格:
其次,下标操作
a[i]
定义为*(a + i)
;也就是说,您根据基地址的i
个元素(不是字节)计算地址您的数组并取消引用结果。例如,如果a
是int
数组,则*(a + i)
将为您提供i 的值
整数。如果 an 是a
之后的第struct foo
的数组,则*(a + i)
将为您提供第i
的值a
之后的 struct。指针算术始终考虑基类型的大小,因此您无需担心偏移量中的字节数。相同的逻辑适用于多维数组,您只需为每个维度递归应用规则:
请注意,您几乎不需要手动执行这些取消引用;编译器知道数组访问是什么样的,并可以相应地优化代码。在适当的情况下,手动写出取消引用可能会导致代码比使用下标运算符慢。
您可以像这样对二维数组进行索引,就好像它是一维数组一样:
但我不会(表达式的类型不完全匹配)。请注意,您将
i
乘以行数,而不是列数。Change
to simply be
if all you're worred about is printing out the right value. After all, that's how you assigned it.
If you're doing this as an exercise to understand how array subscripting works, then there are several things you need to remember.
First, except when it is the operand of the
sizeof
or unary&
operators, or is a string literal being used to initialize another array in a declaration, an expression of type "N-element array ofT
" will be replaced with ("decay to") an expression of type "pointer toT
", and its value will be the address of the first element of the array. The expressionmatrice
is an array expression of type "20-element array of 30-element array ofint
"; in most circumstances, it will be converted to an expression of type "pointer to 30-element array ofint
", orint (*)[30]
. Similarly, the expressionmatrice[i]
is an expression of type "30-element array ofint
", and in most cirumstances it will be converted to an expression of type "pointer toint
", orint *
.Here's a handy table to remember all of this:
Second, the subscripting operation
a[i]
is defined as*(a + i)
; that is, you compute an address based oni
number of elements (NOT BYTES) from the base address of your array and dereference the result. For example, ifa
is an array ofint
, then*(a + i)
will give you the value of thei
'th integer aftera
. If an is an array ofstruct foo
, then*(a + i)
will give you the value of thei
'th struct aftera
. Pointer arithemtic always takes the size of the base type into account, so you don't need to worry about the number of bytes in the offset.The same logic applies to multidimensional arrays, you just apply the rule recursively for each dimension:
Note that you should almost never have to do these dereferences manually; a compiler knows what an array access looks like and can optimize code accordingly. Under the right circumstances, writing out the dereferences manually can result in slower code than using the subscript operator.
You can index into a 2-d array as if it were a 1-d array like so:
but I wouldn't (the types of the expressions don't match up cleanly). Note that you multiply
i
by the number of rows, not columns.您也可以像这样打印它:
它的作用是首先将矩阵转换为字节数组,然后获取所需整数的起始地址,然后根据读取的前四个字节重建整数那个地址。
这有点矫枉过正,但却是解决问题的一个有趣的方法。
You could also print it like this:
What this does is first, it converts your matrix to an array of bytes, then, it gets the starting address of the integer you need, and then it reconstructs the integer from the first four bytes read from that address.
This is a bit overkill, but a fun solution to the problem.