Matrix Access Ansi C.

时间:2012-02-06 19:58:15

标签: c matrix ansi

为什么主函数中的最后一个printf不会向屏幕打印值10? 我知道在ANSI C中,静态分配的矩阵以这种方式排列在内存中:  matrix:matrix [0] [0],matrix [0] [1],...,matrix [0] [ColumnsDimension-1],matrix [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 个答案:

答案 0 :(得分:3)

改为使用*(matrice[i * dimColonne] + j)

答案 1 :(得分:1)

  

为什么main函数中的最后一个printf不会向屏幕打印值10?

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

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

答案 2 :(得分:1)

在您的代码中,您有:

matrice[i*dimColonne+j]

由于i0,因此评估为

matrice[j]

由于j3,这意味着

matrice[3]

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

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

答案 3 :(得分:1)

更改

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

只是

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

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

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

首先,除了它是sizeof或一元&运算符的操作数,或者是一个字符串文字用于初始化声明中的另一个数组时,表达式为“N-element” T“数组将被替换为(”decay to“)类型为”T指针“的表达式,其值将是数组第一个元素的地址。表达式matrice是类型为“20个元素的30个元素数组int”的数组表达式;在大多数情况下,它将转换为“指向30个元素数组int”或int (*)[30]的类型的表达式。类似地,表达式matrice[i]是“{-1}}的30个元素数组”类型的表达式,并且在大多数情况下,它将被转换为“指向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

其次,下标操作int *定义为a[i];也就是说,您根据数组基址的*(a + i)元素 NOT BYTES )计算地址,取消引用结果。例如,如果ia的数组,那么int会在{{{}}之后为您提供*(a + i)'整数的值1}}。如果a是i的数组,那么a将在struct foo之后为您提供*(a + i)'结构的值。指针arithemtic总是考虑基类型的大小,因此您不必担心偏移中的字节的数量。

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

i

请注意,几乎从不必须手动执行这些解除引用;编译器知道数组访问的样子,并可以相应地优化代码。在适当的情况下,手动写出解除引用可能导致较慢的代码比使用下标运算符。

您可以将二维数组索引为就像它是一维数组一样:

a

但我不会(表达式的类型不能完全匹配)。请注意,您将 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) 乘以的数量,而不是列数。

答案 4 :(得分:-1)

你也可以这样打印:

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);

首先,它将矩阵转换为字节数组,然后,它获取所需整数的起始地址,然后重建从该地址读取的前四个字节中的整数。

这有点矫枉过正,但这个问题很有趣。