二维数组就是本质上是以数组作为数组元素的数组,即“数组的数组”
例如:int a[2][3] = { {80,75,92}, {61,65,71}};
这就是一个二维数组
他的意思就是a数组里面有两个一维数组,每个一维数组里面又存放了三个int类型元素
二维数组的定义
- 数据类型 数组名[二维数组中一维数组的个数][二维数组中一维数组内的元素个数]
- 其中"一维数组的个数"表示当前二维数组中包含多少个一维数组
- 其中"一维数组的元素个数"表示当前二维数组中每个一维数组元素的个数
二维数组的初始化
初始化分为两种:
- 定义的同时初始化
int a[2][3]={ {80,75,92}, {61,65,71}};
- 先定义后初始化
int a[2][3];
a[0][0] = 80;
a[0][1] = 75;
a[0][2] = 92;
a[1][0] = 61;
a[1][1] = 65;
a[1][2] = 71;
按行分段赋值:int a[2][3]={ {80,75,92}, {61,65,71}};
按行连续赋值:int a[2][3]={ 80,75,92,61,65,71};
二维数组的应用场景很广
可以用来做五子棋,俄罗斯方块,象棋,推箱子之类的游戏
二维数组的遍历
二维数组的遍历需要用到for循环嵌套,可以分开来遍历假如int arr[3][3];
说明这个二维数组有3个一维数组,三个一维数组中都存有3个int类型的元素
内循环控制每个一维数组中的元素
二维数组的存储
-
和一维数组一样
往每个元素中存储数据从高地址开始存储
给数组分配存储空间从内存地址大开始分配
给数组元素分配空间, 从所占用内存地址小的开始分配
二维数组与函数
- 和一位数组一样, 只看形参是基本类型还是数组类型
- 如果是基本类型在函数中修改形参不会影响实参
地址传递
二维数组作为函数参数,在被调函数中不能获得其有多少行,需要通过参数传入
二维数组作为函数参数,在被调函数中可以计算出二维数组有多少列
void test(char cs[2][3])
{
size_t col = sizeof(cs[0]); // 输出3
printf("col = %zd\n", col);
}
字符串是位于双引号中的字符序列
在内存中以“\0”结束,所占字节比实际多一个
在C语言中没有专门的字符串变量,通常用一个字符数组来存放一个字符串。
当把一个字符串存入一个数组时,会把结束符‘\0’存入数组,并以此作为该字符串是否结束的标志。
有了‘\0’标志后,就不必再用字符数组 的长度来判断字符串的长度了
字符串的输出:可以使用printf函数和scanf函数一次性输出输入一个字符数组中的字符串
- 使用的格式字符串为“%s”,表示输入、输出的是一个字符串
- %s的本质就是根据传入的name的地址逐个去取数组中的元素然后输出,直到遇到\0位置
- 输出
char chs[] = "lnj";
printf("%s\n", chs);
- 输入
char ch[10];
scanf("%s",ch);
注意点:
对一个字符串数组, 如果不做初始化赋值, 必须指定数组长度
ch最多存放由9个字符构成的字符串,其中最后一个字符的位置要留给字符串的结尾标示‘\0’
当用scanf函数输入字符串时,字符串中不能含有空格,否则将以空格作为串的结束符
字符串常用方法
- 使用输入输出的字符串函数,在使用前应包含头文件"stdio.h"
- 使用其它字符串函数则应包含头文件"string.h"
字符串输出函数:puts
格式: puts(字符数组名)
功能:把字符数组中的字符串输出到显示器。即在屏幕上显示该字符串。
优点:
自动换行
可以是数组的任意元素地址
缺点:
不能自定义输出格式, 例如 puts("hello %i")
char ch[] = "lnj";
puts(ch); //输出结果: lnj
字符串输入函数:gets
格式: gets (字符数组名)
功能:从标准输入设备键盘上输入一个字符串。
char ch[30];
gets(ch); // 输入:lnj
puts(ch); // 输出:lnj
可以看出当输入的字符串中含有空格时,输出仍为全部字符串。说明gets函数并不以空格作为字符串输入结束的标志,而只以回车作为输入结束。这是与scanf函数不同的。
利用sizeof计算字符串长度
char name[] = "it666";
int size = sizeof(name);// 包含\0
printf("size = %d\n", size); //输出结果:6
利用系统函数
格式: strlen(字符数组名)
功能:测字符串的实际长度(不含字符串结束标志‘\0’)并作为函数返回值。
char name[] = "it666";
size_t len = strlen(name2);
printf("len = %lu\n", len); //输出结果:5
字符串连接函数:strcat
格式: strcat(字符数组名1,字符数组名2)
功能:把字符数组2中的字符串连接到字符数组1中字符串的后面,并删去字符串1后的串标志 "\0"。本函数返回值是字符数组1的首地址。
char oldStr[100] = "welcome to";
char newStr[20] = " lnj";
strcat(oldStr, newStr);
puts(oldStr); //输出: welcome to lnj"
这个方法有一个注意点就是字符数组1足够长,可以装下字符数组2里面的数组元素
字符串拷贝函数:strcpy
格式: strcpy(字符数组名1,字符数组名2)
功能:把字符数组2中的字符串拷贝到字符数组1中
字符串结束标志"\0"也一同拷贝。
char oldStr[100] = "welcome to";
char newStr[50] = " lnj";
strcpy(oldStr, newStr);
puts(oldStr); // 输出结果: lnj // 原有数据会被覆盖
字符串比较函数:strcmp
格式: strcmp(字符数组名1,字符数组名2)
功能:按照ASCII码顺序比较两个数组中的字符串,并由函数返回值返回比较结果。
字符串1等于字符串2,返回值 = 0;
字符串1大于字符串2,返回值 > 0;
字符串1小于字符串2,返回值 < 0。
char oldStr[100] = "0";
char newStr[50] = "1";
printf("%d", strcmp(oldStr, newStr)); //输出结果:-1
char oldStr[100] = "1";
char newStr[50] = "1";
printf("%d", strcmp(oldStr, newStr)); //输出结果:0
char oldStr[100] = "1";
char newStr[50] = "0";
printf("%d", strcmp(oldStr, newStr)); //输出结果:1
字符串数组其实就是定义一个数组保存所有的字符串
字符串数组初始化