c - 将指向多维数组的指针作为参数传递
问题描述
我是初学者,正在尝试了解多维数组的工作原理
请看这段代码:
#include<stdio.h>
void getData(int c;int *a,int r,int c)
{
for(int i=0;i<r;i++)
for(int j=0;j<c;j++)
scanf("%d",(*(a+i)+j)); //warning
return;
}
void putData(int c;int *a,int r,int c)
{
for(int i=0;i<r;i++)
for(int j=0;j<c;j++)
printf("%d",*(*(a+i)+j)); //error
printf("\n");
}
int main(void)
{
int r1,r2,c1,c2;
printf("Enter order of A:\n");
scanf("%d %d",&r1,&c1);
printf("Enter order of B:\n");
scanf("%d %d",&r2,&c2);
int a[r1][c1],b[r2][c2];
getData((int *)a,r1,c1);
getData((int *)b,r2,c2);
putData((int *)b,r2,c2);
}
我无法理解指针如何传递给函数以及错误的原因。但我想如果我能理解指针是如何工作的,那么我可能能够调试它。请帮忙!谢谢!
编辑:我真的很想了解指针如何与寻址和东西一起工作。因此,如果有某种追踪,它可能会对我有所帮助
解决方案
当您将 VLA 作为参数(或任何二维数组)传递时,您必须至少传递每行的元素数,以便您可以为您的 VLA(二维数组)声明一个完整的类型。
虽然你可以通过:
void getData (int r, int c, int a[r][c])
你也可以通过:
void getData (int r, int c, int (*a)[c])
(由于第一级间接转换为指针,请参阅:C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3) - 并注意例外情况)
c
之前必须包含在参数列表中, a
否则 for 的类型a
将不完整,因为c
尚未定义。
虽然您可以将 -- don't 写成*(*(a + i) + j)
等效的指针表示法a[i][j]
,但它的可读性较差(但完全等效)。
总是,总是,总是验证每一个输入。否则,您可能会在输入或匹配失败之后调用未定义的行为,例如scanf
printf("Enter order of A:\n");
if (scanf ("%d %d", &r1, &c1) != 2) { /* validate EVERY input */
fputs ("error: invalid input (r1, c1).\n", stderr);
return 1;
}
总而言之,你可以这样做:
#include <stdio.h>
#include <stdlib.h> /* for EXIT_FAILURE */
void getData (int r, int c, int (*a)[c])
{
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++)
if (scanf ("%d", &a[i][j]) != 1) {
fputs ("error: invalid input a[i][j].\n", stderr);
exit (EXIT_FAILURE);
}
}
void putData (int r, int c, int (*a)[c])
{
for (int i = 0; i < r; i++) {
for(int j = 0; j < c; j++)
printf (" %2d", a[i][j]); /* more readable */
/* printf (" %2d", *(*(a + i) + j)); */
putchar ('\n'); /* use putchar for a single char, instead of printf */
}
}
int main(void)
{
int r1, r2, c1, c2;
printf ("Enter order of A:\n");
if (scanf ("%d %d", &r1, &c1) != 2) { /* validate EVERY input */
fputs ("error: invalid input (r1, c1).\n", stderr);
return 1;
}
printf ("Enter order of B:\n");
if (scanf ("%d %d", &r2, &c2) != 2) { /* validate EVERY input */
fputs ("error: invalid input (r2, c2).\n", stderr);
return 1;
}
int a[r1][c1], b[r2][c2];
getData (r1, c1, a);
getData (r2, c2, b);
puts ("a");
putData (r1, c1, a);
puts ("\nb");
putData (r2, c2, b);
}
(注意:包含stdlib.h
forEXIT_FAILURE
宏,并注意代码中的额外间距——有助于老年人的眼睛)
示例使用/输出
$ echo "2 3 2 3 1 2 3 4 5 6 7 8 9 10 11 12" | ./bin/scanfvla
Enter order of A:
Enter order of B:
a
1 2 3
4 5 6
b
7 8 9
10 11 12
如果您还有其他问题,请仔细查看并告诉我。
推荐阅读
- javascript - 通过正则表达式从对象中删除键
- wordpress - 将自定义字段移动到另一个 wordpress 站点
- javascript - 为什么我的 div 可以在较小的屏幕上拖动,但是当我在较大的屏幕上检查它时,我不再能够拖动它?
- excel - EXCEL - 列表中的数组公式匹配
- javascript - JavaScript - 作为函数参数的数组在每个 for 循环中都会更改
- r - 如何从行中提取列并将输出保存为变量 dplyr
- python - I am trying to get rid of rows using multiple values, but I am getting an error
- c++11 - 无法编译 unodered_sets 的比较
- java - 混合挥发性和非挥发性
- integer - 如何测试非常大的整数是否只有 2s、3s 和 7s 的素数?