矩阵访问 Ansi C

发布于 2025-01-03 14:26:01 字数 530 浏览 1 评论 0原文

为什么主函数中的最后一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

爱已欠费 2025-01-10 14:26:01

使用 *(matrice[i * dimColonne] + j) 代替。

Use *(matrice[i * dimColonne] + j) instead.

似最初 2025-01-10 14:26:01

为什么主函数中的最后一个 printf 没有将值 10 打印到屏幕上?

因为matrice是一个数组的数组...
并且 matrice[whatever] 是一个数组(在大多数情况下“衰减”为指向其第一个元素的指针),

*matrice[whatever] 是第一个元素的内容数组matrice[whatever] 的元素。

Why the last printf in the main function doesn't print to the screen the value 10?

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 array matrice[whatever].

娜些时光,永不杰束 2025-01-10 14:26:01

在您的代码中,您有:

matrice[i*dimColonne+j]

由于 i0 ,因此计算结果为

matrice[j]

由于 j3 这意味着

matrice[3]

当您打印时*matrice[3] 相当于打印 matrice[3][0],因为 matrice[3] 是一个数组。并且数组会衰减为指向其第一个元素的指针。

但你根本不想这样做。您应该简单地编写matrice[i][j]并让编译器完成工作。

In your code you have:

matrice[i*dimColonne+j]

Since i is 0 this evaluates to

matrice[j]

Since j is 3 this means

matrice[3]

When you print *matrice[3] that is equivalent to printing matrice[3][0] because matrice[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.

一枫情书 2025-01-10 14:26:01

请更改

printf("%d",*matrice[i*dimColonne+j]);  

为简单

printf("%d", matrice[i][j]);

如果您所担心的只是打印出正确的值, 。毕竟,这就是您分配的方式。

如果您这样做是为了了解数组下标如何工作的练习,那么您需要记住几件事。

首先,除非它是 sizeof 或一元 & 运算符的操作数,或者是用于初始化声明中的另一个数组的字符串文字,类型的表达式“T 的 N 元素数组”将被替换为(“衰减为”)“指向 T 的指针”类型的表达式,其值将是数组的第一个元素。表达式matrice是一个类型为“int的30元素数组的20元素数组”的数组表达式;在大多数情况下,它将转换为“指向 int 的 30 元素数组的指针”或 int (*)[30] 类型的表达式。类似地,表达式matrice[i]是“30-element array of int”类型的表达式,并且在大多数情况下它会被转换为“30-element array of int”类型的表达式指向int”或int *的指针。

下面是一个方便记住所有这些的表格:

Declaration: T a[N];

Expression              Type              Decays to
----------              ----              ---------        
         a              T [N]             T *
        &a              T (*)[N]
        *a              T 
      a[i]              T

Declaration: T a[M][N];

Expression              Type              Decays to
----------              ----              ---------
         a              T [M][N]          T (*)[N]
        &a              T (*)[M][N]    
        *a              T [N]             T *
      a[i]              T [N]             T *
     &a[i]              T (*)[N]         
     *a[i]              T
   a[i][j]              T

其次,下标操作 a[i] 定义为 *(a + i);也就是说,您根据基地址的 i元素不是字节)计算地址您的数组并取消引用结果。例如,如果 aint 数组,则 *(a + i) 将为您提供 i 的值a 之后的第整数。如果 an 是 struct foo 的数组,则 *(a + i) 将为您提供第 i 的值 a 之后的 struct。指针算术始终考虑基类型的大小,因此您无需担心偏移量中的字节数。

相同的逻辑适用于多维数组,您只需为每个维度递归应用规则:

    a[i][j] ==   *(a[i] + j) ==    *(*(a + i) + j)
 a[i][j][k] == *(a[i][j]+ k) == *(*(a[i] + j) + k) == *(*(*(a + i) + j) + k)  

请注意,您几乎不需要手动执行这些取消引用;编译器知道数组访问是什么样的,并可以相应地优化代码。在适当的情况下,手动写出取消引用可能会导致代码比使用下标运算符慢。

您可以像这样对二维数组进行索引,就好像它是一维数组一样:

a[i*rows + j] = val;

但我不会(表达式的类型不完全匹配)。请注意,您将 i 乘以数,而不是列数。

Change

printf("%d",*matrice[i*dimColonne+j]);  

to simply be

printf("%d", matrice[i][j]);

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 of T" will be replaced with ("decay to") an expression of type "pointer to T", and its value will be the address of the first element of the array. The expression matrice is an array expression of type "20-element array of 30-element array of int"; in most circumstances, it will be converted to an expression of type "pointer to 30-element array of int", or int (*)[30]. Similarly, the expression matrice[i] is an expression of type "30-element array of int", and in most cirumstances it will be converted to an expression of type "pointer to int", or int *.

Here's a handy table to remember all of this:

Declaration: T a[N];

Expression              Type              Decays to
----------              ----              ---------        
         a              T [N]             T *
        &a              T (*)[N]
        *a              T 
      a[i]              T

Declaration: T a[M][N];

Expression              Type              Decays to
----------              ----              ---------
         a              T [M][N]          T (*)[N]
        &a              T (*)[M][N]    
        *a              T [N]             T *
      a[i]              T [N]             T *
     &a[i]              T (*)[N]         
     *a[i]              T
   a[i][j]              T

Second, the subscripting operation a[i] is defined as *(a + i); that is, you compute an address based on i number of elements (NOT BYTES) from the base address of your array and dereference the result. For example, if a is an array of int, then *(a + i) will give you the value of the i'th integer after a. If an is an array of struct foo, then *(a + i) will give you the value of the i'th struct after a. 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:

    a[i][j] ==   *(a[i] + j) ==    *(*(a + i) + j)
 a[i][j][k] == *(a[i][j]+ k) == *(*(a[i] + j) + k) == *(*(*(a + i) + j) + k)  

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:

a[i*rows + j] = val;

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.

时常饿 2025-01-10 14:26:01

您也可以像这样打印它:

char *matrixAsByteArray = (char *) matrice;
char *startIntAddr = matrixAsByteArray + i * dimColonne * sizeof(int) + j * sizeof(int);

int outInt = *startIntAddr | *(startIntAddr + 1) << 8 | *(startIntAddr + 2) << 16 | *(startIntAddr + 3) << 24;
printf("%d", outInt);

它的作用是首先将矩阵转换为字节数组,然后获取所需整数的起始地址,然后根据读取的前四个字节重建整数那个地址。

这有点矫枉过正,但却是解决问题的一个有趣的方法。

You could also print it like this:

char *matrixAsByteArray = (char *) matrice;
char *startIntAddr = matrixAsByteArray + i * dimColonne * sizeof(int) + j * sizeof(int);

int outInt = *startIntAddr | *(startIntAddr + 1) << 8 | *(startIntAddr + 2) << 16 | *(startIntAddr + 3) << 24;
printf("%d", outInt);

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文