C语言 根据我的编译器,我使用指针不正确地设置值为2D数组.然而,我不确定我到底做错了什么



下面是我的代码片段:

void initialize_matrices(int* a, int* b, int* c);
void fill_matrix(int* matrix);
void add_matrices(int* a, int* b, int* c);
void print_sum_matrix(int* c);

int main()
{
int a[3][3];
int b[3][3];
int c[3][3];
//Q2: define pointers (5)
//Define pointers ap, bp, and cp to the matrices that are defined above
int (*ap)[3][3] = &a; //giving the pointers a location to point to.
int (*bp)[3][3] = &b;
int (*cp)[3][3] = &c;
initialize_matrices(ap, bp, cp);
printf("Matrix a:n");
fill_matrix(ap);
printf("Matrix b:n");
fill_matrix(bp);
add_matrices(ap, bp, cp);
print_sum_matrix(cp);
return 0;
    }
//Q3: initialize (10)
//loop through the matrices and set each integer value to 0 using pointers
   void initialize_matrices(int* a, int* b, int* c)
 {
for (int i = 0; i < 3; i++) //rows
{
    for (int j = 0; j < 3; j++) //columns
    {
        *a[i][j] = 0;   //accessing & changing the address that the pointer is pointing to?
        *b[i][j] = 0;
        *c[i][j] = 0;
    }
}
}

我向朋友征求意见,他们告诉我把*a[I][j] = 0改为a[I * 3 + j] = 0。这是真的吗?如果是的话,我为什么要这么做?根据我的理解,指针"指向"的值或至少指针指向的地址的值可以用我上面写的代码修改。

在Q1中,aint[3][3],本质上是一个3x3的整数矩阵。在您的计算机内存中,这是在单个连续内存块中的9 (3x3=9)个整数。

Q2中ap是指向int[3][3]的指针。

所以当你想通过a在矩阵中设置一个值时,你可以像a[i][j] = 0;那样做,但是通过ap你可以像(*ap)[i][j] = 0;那样做。注意,你需要在*ap周围加上括号,否则索引([i][j])将首先发生。

然而,在Q3中,当您想将int[3][3]传递给函数,然后更改它时,它会变得有点棘手。我们需要传递一个指针,以便能够修改现有的矩阵。

所以我们可以写(再次注意括号,它们很重要)

void initialize_matrices(int (*ap)[3][3], int (*bp)[3][3], int (*cp)[3][3]) {
    ...
    (*ap)[i][j] = 0;
    ...
}

我们将函数命名为initialize_matrices(ap, bp, cp);initialize_matrices(&a, &b, &c);

或者写成

void initialize_matrices(int *aq, int *bq, int *cq) {
    ...
    aq[j*3 + i] = 0;
    ...
}

在这种情况下,我们必须像initialize_matrices((int *)&a, (int *)&b, (int *)c)一样调用函数——我们将将指向int[3][3]的指针转换为指向整数的指针(可能是序列中的第一个,就像我们的情况一样)。

这是可能的,因为,正如我前面提到的,int[3][3]是内存中由9个整数组成的连续块。当你做(*ap)[i][j] = 0;时,计算机实际上是自动进行数学运算来确定要设置哪一个,但是当你扔掉关于二维数组的信息时,它就不能再这样做了,所以你必须自己做,用[column_index*ROW_LENGTH + row_index]。

为了说明情况:

Offset : 2D Access : 1D Access
00     : a[0][0]   : 0x3 + 0 <--- my ap and aq would both point to here, but have different types
01     : a[0][1]   : 0x3 + 1
02     : a[0][2]   : 0x3 + 2
============ <- end of row 0, visual aid only, memory addresses are consecutive
03     : a[1][0]   : 1x3 + 0
04     : a[1][1]   : 1x3 + 1
05     : a[1][2]   : 1x3 + 2
============ <- end of row 1
06     : a[2][0]   : 2x3 + 0
07     : a[2][1]   : 2x3 + 1
08     : a[2][2]   : 2x3 + 2
============ <- end of row 2, end of matrix

如果允许您定义initialize_matrices()函数,那么我建议使用第一个版本,因为您可能会发现它更容易理解。

只要把类型弄对,指向数组的指针和指向int的指针是不一样的。

你的函数只是不使用二维矩阵,因为你的接口是错误的。比如

void fill_matrix(int matrix[3][3]);

相当于

void fill_matrix(int matrix[][3]);

void fill_matrix(int (*matrix)[3]);

(但是这种"重写"只发生在函数参数上)

现在从这里开始,纠正程序中的其他类型

相关内容

最新更新