这里真的很想好好讲讲,我发现有些教材、网课甚至线下课在这里基本没有细细讲解用法,而是就是用一堆sizeof打印二维数组的大小,看内存栈,但是没有教具体实际怎么去用(个人感觉字符串那里也是,教的都是一些内存上的东西,没有讲解具体用法)。
其实这一块最重要的就是语法,要不轻轻松松爆内存。
什么是二维数组
就是一个数组,但是有两个维度,可以按照矩阵理解,一个管列一个管行
int a[3][4] 定义了一个数字矩阵,有3行4列
char a[3][4] 定义了一个字符矩阵,有3行4列(注意不是字符串,每个元素只能是一个字母,字符串开个坑先)
指针与数组
有两个东西,怎么区分?看用途
数组的指针
指向用,比如我有一个矩阵,我不想破坏他,想用一个数组的指针指向他然后进行打印操作或者其他操作,取值或者赋值但是不直接更改原先二维数组,这时候就是数组的指针
int (*p)[4] //用来指向一个包含四个元素的数组
举个例子
#include <stdio.h>
int main()
{
int a[3][4], i, j;
int(*p)[4]; // 定义p为指针,指向一个长度为4的整型数组
p = a;
/********** Begin *********/
// 使用指向数组的指针输入二维数组的值
for(i = 0; i < 3; i++) {
for(j = 0; j < 4; j++) {
printf("Enter element [%d][%d]: ", i, j);
scanf("%d", &p[i][j]);
}
}
// 使用指向数组的指针输出二维数组的值
for(i = 0; i < 3; i++) {
for(j = 0; j < 4; j++) {
printf("%d ", p[i][j]);
}
printf("\n");
}
/********** End **********/
return 0;
}
这里我不想直接修改a(虽然也行,但是有个指向数组的指针这样可以方便动态分配、指针运算、函数参数传递、避免类型不匹配),就弄了个p指针,专门指向有四个元素的数组(这样就安全了),这个int (*p)[4]相当于把矩阵切成三行,指针运算p=p+1就可以跳过一个行,比没有p指针跳过行方便多了
指针数组
一个数组,里面存放的全是指针,所以用途是存放指针,比如有四个字符串(四个指针),我想把他们再汇总,就用指针数组,这个数组里面存放四个指针,分别指向四个句子
int *p[4] //可以存放四个指针
举个例子,还是矩阵
#include <stdio.h>
int main() {
// 定义三个数组
int array1[4] = {1, 2, 3, 4};
int array2[4] = {5, 6, 7, 8};
int array3[4] = {9, 10, 11, 12};
// 定义一个指针数组,每个元素都是一个指向 int 的指针
int *ptrArray[3];
// 将指针数组的每个元素指向对应的数组
ptrArray[0] = array1;
ptrArray[1] = array2;
ptrArray[2] = array3;
// 使用指针数组遍历并打印每个数组的内容
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
printf("%d ", ptrArray[i][j]); // 使用 ptrArray[i][j] 访问元素
}
printf("\n");
}
return 0;
}
这里相当于 先定义了每个行向量,然后再拼在一起(指针数组主要起汇总作用)
怎么创建
个人建议:
数字、字母二维矩阵 用 数组的指针指着创建(实在懒直接对创建的二维矩阵操作也不是不行)
字符串(一段话) 用 指针数组
这里就讲解用数组的指针创建的方法,字符串的回头再说
首先要定义一个二维数组(开辟个空间,所以指针写法就不行了)
int a[3][4], i, j;
然后就是弄个数组指针指向a
int(*p)[4]; // 定义p为指针,指向一个长度为4的整型数组
p = a;
对于数、字符,输入输出都好说,双循环就行,一般外层循环管行,内层循环管列
因为p指向a,所以这种写法也可以,看着也方便
这个就是指针运算的写法,在这个问题上有些复杂*(p+i)表示行的移动,+j表示列的移动
怎么遍历
也是双层循环,两种写法
总结
二维数组这里牵扯指针知识,有些写法等价,有些却不等价,需要琢磨一段时间,主要还是思考这东西我定义的到底是什么,后面也会作为重点着重讲解,这一块一定要大量的习题
然后这是上面两个东西的区分图
以上均是本人理解,如有不对欢迎各位大佬评论区指出~