根据我的编译器,我错误地使用了指针来设置二维数组的值。但是,我不确定我到底做错了什么
According to my compiler, I am using pointers incorrectly for setting values to 2D arrays. However, I am not sure what exactly I am doing wrong
这是我的代码片段:
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,是吗?如果是这样,为什么我必须这样做?据我了解,指针的值是 "pointing to" 或者至少指针指向的地址的值可以用我上面写的代码修改。
在 Q1 中,a
是一个 int[3][3]
,本质上是一个 3x3 整数矩阵。在您的计算机内存中,这是单个连续内存块中的 9 (3x3=9) 个整数。
在 Q2 中 ap
是指向 int[3][3]
的指针。
所以当你想通过 a
在矩阵中设置一个值时,你可以像 a[i][j] = 0;
那样做,但是通过 ap
你可以像 (*ap)[i][j] = 0;
那样做 注意你需要在 *ap
周围加上括号,否则索引 ([i][j]
) 将首先发生。
然而,在第 3 季度,当您想将 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]);
(但是这个 "rewriting" 只发生在函数参数上。)
现在从这里开始,更正程序中的其他类型。
这是我的代码片段:
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,是吗?如果是这样,为什么我必须这样做?据我了解,指针的值是 "pointing to" 或者至少指针指向的地址的值可以用我上面写的代码修改。
在 Q1 中,a
是一个 int[3][3]
,本质上是一个 3x3 整数矩阵。在您的计算机内存中,这是单个连续内存块中的 9 (3x3=9) 个整数。
在 Q2 中 ap
是指向 int[3][3]
的指针。
所以当你想通过 a
在矩阵中设置一个值时,你可以像 a[i][j] = 0;
那样做,但是通过 ap
你可以像 (*ap)[i][j] = 0;
那样做 注意你需要在 *ap
周围加上括号,否则索引 ([i][j]
) 将首先发生。
然而,在第 3 季度,当您想将 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]);
(但是这个 "rewriting" 只发生在函数参数上。)
现在从这里开始,更正程序中的其他类型。