文章转载请注明出处,加上原文链接,谢谢!
什么是二维数组?
E.g. int array[2][3]={{1,2,3},{4,5,6}}
示例数组是一个初始化的 二维数组。定义一个 二维数组和一个普通的一维数组类似,同样包含三要素: 数据类型, 数组名,数组大小。大部分人会说两者的区别在于第三要素 —— 数组大小方面多了一个方括号“[]”,使得二维数组能自由的定义 行数 与 列数 的数量多少。但在笔者看来,矩阵(Matrix)—— 这一数学概念可以完美的阐述两者的区别:
一维数组(int array[]) ——
A
1
×
n
A_{1 \times n}
A1×n? 二维数组(int array[][]) ——
A
m
×
n
A_{m \times n}
Am×n?
二维数组和一维数组的表述形式虽然不同,但两个数组在计算机内存里的存储方式是一致的,即 所有数据都是按顺序存储在连续的内存空间内。这一点可自行探究。
二维数组的使用有诸多细节,这里博主再补充一点:参数传递。运用二维数组进行函数传递参数时 行数可以不用填写,但列数必须填写。
演示代码:print_array_double.c
#include <stdio.h>
void printArrayDouble(int array[][3])
{
int i, j;
for(i = 0; i < 2; i++){
for(j = 0; j < 3; j++){
printf("%d ", array[i][j]);
}
putchar('\n');
}
}
int main()
{
int array[2][3] = {{1,2,3}, {4,5,6}};
printArrayDouble(array);
return 0;
}
点击此处,阅读笔者关于“一维数组”的博文。
二维数组的取值技巧总结
演示代码:value_array_double.c
#include <stdio.h>
int main()
{
int a[2][3] = {{1,2,3},{4,5,6},};
int i,j;
printf("a[2][3]: \n");
for(i = 0; i < 2; i++){
for(j = 0; j < 3; j++){
printf("%d ", a[i][j]);
}
putchar('\n');
}
putchar('\n');
printf("a[0][0] : %d\n", a[0][0]);
printf("*(*(a+0)) : %d\n", *(*(a+0)));
printf("**a : %d\n", **a);
printf("p of a[0][0]: %p\n", a);
printf("a[1][1] : %d\n", a[1][1]);
printf("*(a[1]+1) : %d\n", *(a[1]+1));
printf("*(*(a+1)+1)): %d\n", *(*(a+1)+1));
printf("p of a[1][2]: %p\n", *(a+2));
printf("a[1][0] : %d\n", a[1][0]);
printf("a[0]+1 : %d\n", *(*(a+1)));
printf("p of a[1][0]: %p\n", a+1);
return 0;
}
运行结果:
a[0][0] : 1
*(*(a+0)) : 1
**a : 1
p of a[0][0]: 0x7ffcbd065d40
a[1][1] : 5
*(a[1]+1) : 5
*(*(a+1)+1)): 5
p of a[1][2]: 0x7ffcbd065d58
a[1][0] : 4
a[0]+1 : 4
p of a[1][0]: 0x7ffcbd065d4c
二维数组取值形式与含义总结:
表现形式 | 含义 |
---|
a | 二维数组名,指向一维数组a[0],即第零行1首地址。 | a[0] ,
?
\ast
?(a+0),
?
\ast
?a | 第零行第零列元素首地址。 | a[0][0],
?
\ast
?(
?
\ast
?(a+0)),
?
?
\ast\ast
??a | 第零行第零列元素的数值。 | a+1,&a[1] | 第一行首地址。 | a[1],
?
\ast
?(a+1) | 第一行第零列元素a[1][0]元素的地址。 | a[1]+2,
?
\ast
?(a+1)+2,&a[1][2] | 第一行第二列元素a[1][2]的地址。 |
?
\ast
?(a[1]+2),
?
\ast
?(
?
\ast
?(a+1)+2,a[1][2] | 第一行第二列元素a[1][2]的值。 |
?
\ast
?注意:二维数组元素的取值方式相比一维数组虽然略有繁琐,但以数学形式理解无非都是存储数据的矩阵而已。配合以上代码理解将事半功倍。
二维数组的遍历
|运用指针遍历二维数组
指针遍历的代码:double_array_pointer.c
#include <stdio.h>
int main()
{
int array[2][3] = {{1,2,3},{4,5,6}};
int i, j;
int *p = NULL;
p = &array[0][0];
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
printf("%d ", *p++);
}
putchar('\n');
}
return 0;
}
|数组指针遍历二维数组
演示代码:arrayDouble_arrayPointer.c
#include <stdio.h>
int main()
{
int i,j;
int array[2][3] = {{1,2,3},{4,5,6}};
int (*p)[3] = NULL;
p = array;
printf("for循环遍历:\n");
for(i = 0; i < 2; i++){
for(j = 0; j < 3; j++){
printf("%d ", array[i][j]);
}
putchar('\n');
}
putchar('\n');
printf("数组指针遍历:\n");
for(i = 0; i < 2; i++){
for(j = 0; j < 3; j++){
printf("%d ", *(*(p+i)+j));
}
putchar('\n');
}
return 0;
}
?
\ast
?注:对于优先级混乱的读者,只需牢牢记住三个字符的优先级为 () > [] >
?
\ast
?,从大到小逐次递减。
引申 —— 函数指针数组
演示代码:fun_pointer_array.c
#include <stdio.h>
#include <stdlib.h>
int getMax(int data1, int data2)
{
return data1 > data2 ? data1:data2;
}
int getMin(int data1, int data2)
{
return data1 < data2 ? data1:data2;
}
int getSum(int data1, int data2)
{
return data1 + data2;
}
int main()
{
int a = 10, b = 20;
int ret;
int (*pfunc[3])(int , int ) = {getMax, getMin, getSum};
for(int i=0; i<3; i++){
ret = (*pfunc[i])(a, b);
printf("ret = %d\n", ret);
}
return 0;
}
?
\ast
?注:该段代码来自陈立臣教师新版C语言教学视频。
参考资料
文章更新记录
- 文章整体框架搭好。「2022.11.2 11:27」
- “什么是二维数组?”一节完成。「2022.11.2 16:40」
- “二维数组的取值技巧总结”一节完成。「2022.11.3 10:30」
- 第一节“参数传递”补充完毕。「2022.11.3 16:23」
- “函数指针数组”一节更新完毕。「2022.11.3 16:56」
|