作为C新手,我对二维数组感到有点困惑。
如果我想表示一个包含3行和5列的矩阵,我想正确的声明是:
char a[3][5];
那么,这是一个由3个字符串组成的3个指针数组还是什么?
为什么每当我尝试循环通过它时,它似乎会读取错误的结果?
int x, y;
for( x=0; x<3; x++ ){
for( y=0; y<3; y++ ){
printf( "%c", a[x][y] );
}
}
是否有以下等效和正确的方法来初始化它?
char a[3][5] = {
{1,0,0,0,1},
{1,0,0,0,1},
{1,0,0,0,1},
};
char a[3][5] = {1,0,0,0,1,
1,0,0,0,1,
1,0,0,0,1};
感谢您最近的解释。
修改
抱歉打字错误,代码未复制。顺便说一句,我继续让他们读起来就像他们以垂直方式阅读,而不是水平阅读。
同样在本教程http://www.cplusplus.com/doc/tutorial/arrays/的示例中,它以一种不向我前进的方式读取数组,因为它似乎适用于5x3,高度宽度,y x,cols 行结构而不是3x5,宽度高度,x y。行 cols one:
#define WIDTH 5
#define HEIGHT 3
int jimmy [HEIGHT][WIDTH];
int n,m;
int main ()
{
for (n=0;n<HEIGHT;n++)
for (m=0;m<WIDTH;m++)
{
jimmy[n][m]=(n+1)*(m+1);
}
return 0;
}
答案 0 :(得分:4)
只是因为它是什么,不是什么。
char a[3][5];
没有涉及指针。像这样的多维数组是......的数组数组,依此类推。在您的情况下,您有一个包含5个字符的3个数组的数组。使用typedef执行此操作时会更清楚。
typedef char T[5];
T a[3];
无论如何都不涉及任何指针。如果要访问这3个数组的第一个数组,可以这样做:
a[0];
它会返回一个char[5]
类型的对象。通常,您没有注意到这一点,因为通常您会索引所有维度。因此a[0]
返回的数组是下一个索引的下标,例如a[0][1]
。 [1]
将应用于a[0]
返回的数组,正如我们之前发现的那样,类型为char[5]
。
那么,这是一个由3个字符串组成的3个指针数组还是什么?
让我们创建该类型,看看它与上面的不同之处。一旦获得基本声明符,创建它很简单:
*D
D[N]
D只是一个现有的另一个声明者。现在让我们继续吧。首先你说array of 3 pointers to 5 arrays of chars...
。我想你的意思是array of 3 pointers to arrays of 5 chars
。首先,创建array of 5
,如
D1[5]
现在,让我们用pointer to
声明符替换D1:
(*D2)[5]
我们必须插入括号,因为下标运算符[N]
比解除引用运算符*
绑定得更好,否则它将被读作*(D2[5])
,这不是我们想要的。现在我们有pointer to array of 5
。
现在让我们做array of 3
。将D2
替换为D3[3]
会产生以下结果:
(*D3[3])[5]
太好了,现在我们得到了array of 3 pointer to array of 5
。只需将该声明符所附的基类型生成完整的声明:
char (*D3[3])[5];
这当然是一个完全不同的东西:)你可以用它来存储指向你的另一个类型为array of 3 arrays of 5 char
的数组的指针。让我们将指向a
的第一个子数组的指针存储到D3[0]
中。我们之前发现a[0]
的类型为char[5]
。我们可以将指向该数组的指针存储到D3[0]
,因为D3
是一个指向char[5]
的指针数组,真是巧合!
D3[0] = &a[0]; // works!
我希望这个小练习向你展示了指针和数组之间的一些关系。干杯!
答案 1 :(得分:2)
您的结果错误,因为您使用x
两次(看起来像复制/粘贴错误)。尝试
int x, y;
for (x = 0; x < 3; x++) {
for (y = 0; y < 5; y++) {
printf("%c", a[x][y]); // Emil H says "%d" might be more useful
}
}
编辑:我不确定该教程有什么令人困惑的。它完全等同于你的代码,除了不打印数组,它将每个元素设置为(row * column)(行和列都是一个,因此是+ 1)。
答案 2 :(得分:2)
我发现您的代码存在一些问题。首先(从上面复制):
int x, y;
for( x=0; x<3; x++ ){
for( x=0; x<3; x++ ){
printf( a[x][y] );
}
}
在您的内部循环中,您似乎想要使用y
而不是x
,并且您希望y
从0..5开始。目前,您正在重复变量x。此外,您的printf()语句有问题。这是一些更正的代码:
int x, y;
for( x=0; x<3; x++ ){
for( y=0; y<5; y++ ){
printf("%d\n", a[x][y] );
}
}
其次,初始化阵列时,您的代码几乎正确。这是更正后的版本:
char a[3][5] = {
{1,0,0,0,1},
{1,0,0,0,1},
{1,0,0,0,1}
};
(我在最后一行数据后删除了,
- 这是语法错误。)
您发布的第二种语法不正确(没有花括号的语法)。
答案 3 :(得分:1)
int x, y;
for( x=0; x<3; x++ ){
for( x=0; x<3; x++ ){
printf( a[x][y] );
}
}
您需要更改第二个for循环以引用“y”而不是“x”。
希望有所帮助。答案 4 :(得分:1)
教程中的图像是数据的绝佳表示: alt text http://www.cplusplus.com/doc/tutorial/arrays/bidimensional_arrays3.gif
从示例中,嵌套的for
循环逐行遍历(左 - >右)数组,并为每列填充一个值。
答案 5 :(得分:1)
当您可能想要“%d”时使用“%c”这样的小错误,这些并不是您真正想要得到的答案我谦虚地想。你说你对数组有点困惑,并且还提到你希望看到指针作为包含数组的数组的数组元素。你
数组数组定义中的最后一个逗号不是语法错误。允许从C99开始。
真正清除事物的是知道数组不是指针。确实,数组名称可以用作常量指针(对第一个元素),并且指针可以像数组一样被索引。但是,这并不意味着数组和指针是相同的。他们不是。
您询问程序中的符号“a”实际上是什么。它是一个数组数组。存储器布局可以像三线部分的长线切割一样可视化,但仍然是连续线。然后以相同的方式将这些中的每一个切成五个部分。寻址一个元素时,必须使用两个索引;首先是你想要的五元素数组,然后是你想要的第五个元素。
内存布局不像行和列网格。内存由一个标量处理,因此它是线性的。指针运算可能是您可以研究的下一步,并查看指针的增量如何工作。
答案 6 :(得分:0)
你以错误的方式使用printf。尝试:
printf("%d", a[x][y]);
我不确定您是否要使用%c或%d。如果要打印该号码,请使用%d。如果要打印实际字符,请使用%c。
答案 7 :(得分:0)
char a [3] [5];
那么,这是一个由3个指针组成的数组 5个字符阵列还是什么?
是的,就是这样。虽然你也可以把它作为连续的15个字符来操作。
按照惯例,大多数人会认为它代表一个有3行5列的矩阵(我认为),但是数据结构本身并不需要它。您可以轻松地使用它来表示5行和3列。或者3组,每组包含5个元素,但彼此之间没有任何有意义的关系。
用于执行矩阵操作的特定库将具有此约定。