二维数组
定义
二维数组本质上是一个行列式的组合,也就是说二维数组是有行和列两部分构成。二维数组数据是通过行列进行解读。
二维数组可被视为一个特殊的一维数组,相当于二维数组又是一个一维数组,只不过它的元素是一维数组。
语法
类型 数组名[行数][列数]
举例:
int arr[3][3] = {{1,2,3},{4,5,6},{7,8,9}};//等价于以下写法 int arr[][] = {{1,2,3},{4,5,6},{7,8,9}};//柔性数组 int arr[3][] = {{1,2},{4,5,6},{7}};//等价于{{1,2,0},{4,5,6},{7,0,0}}
应用场合
主要应用于数据有行列要求的情况。
特殊写法
下标可以是整型表达式,如:
a[2-1][2*2-1]
下标可以是已经有值的变量或数组元素,如:
a[2*x-1][b[3][1]]
数组元素可以出现在表达式中,如:
b[1][2]=a[2][3]/2
初始化
-
分行给二维数组赋初值
int arr[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
-
可将所有数据写在一个花括号内,按照排列顺序对元素赋值。
int arr[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};//等价于上面的写法
-
可以对部分元素赋初值,其余未赋值部分自动填充
0|\0|0.0...
int a[3][4] = {{1},{5,6},{9}} // 等价于 int a[3][4] = {{1,0,0,0},{5,6,0,0},{9,0,0,0}}
-
若对全部元素赋初值,自定义数组时可以省略第1维数组的长度说明,第2维数组的长度必须指明。
int a[][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
-
在分行赋初值时,也可以省略第1维的长度。
int a[][4] = {{1,2,3},{0},{0,10}};// 等价于 int a[][4] = {{1,2,3,0},{0,0,0,0},{0,10,0,0}}
案例
案例1:
/** * 案例:二维数组的遍历 */ #include <stdio.h> int main() { int arr[][3] = {{1},{2,4},{5,6,7}};// 经过论证:二维数组我们必须指明第2维的数组的长度 //获取行的大小 int length = sizeof(arr) / sizeof(arr[0]);//如果是二维数组,第1维的长度,应该是如左侧这样获取 printf("length:%d\n",length); //遍历二维数组,需要使用双层for循环,外层遍历行,内存遍历每一行的列 for(int row = 0;row < length;row++) { //获取列的总大小 int len = sizeof(arr[row]) /sizeof(int); for(int col = 0;col <len;col++) { //获取列元素 printf("%3d",arr[row][col]);//意思是获取数组arr 第row第col列 } printf("\n"); } return 0; } /************************ length:3 1 0 0 2 4 0 5 6 7 **************************/
案例2:
/* 需求:二维数组案例-矩阵的转置(就是将一个2行3列的数组转换为3行2列的数组) */ #include <stdio.h> int main() { //准备2个数组,存放转前和转后的数据 int arr_before[2][3] = {1,2,3,4,5,6}; int arr_after[3][2] = {0};//初始化,每一列上都是0 //遍历arr_before for(int i = 0;i < sizeof(arr_before)/sizeof(arr_before[0]);i++) { for(int j = 0;j < sizeof(arr_before[i])/sizeof(int);j++) { //转置 arr_after[j][i] = arr_before[i][j]; } } //遍历arr_after for(int i = 0;i < sizeof(arr_after)/sizeof(arr_after[0]);i++) { for(int j = 0;j < sizeof(arr_after[i])/sizeof(int);j++) { //输出 printf("%4d",arr_after[i][j]); } printf("\n"); } } /**************************** 1 4 2 5 3 6 *****************************/
案例3:
/* 需求:有一个3×4的二维数组a,要求编程序求出其中值最大的那个元素的值,以及其所在的行号和列号。 */ #include <stdio.h> int main() { // 准备一个二维数组 int arr[3][4] = {{1,2,3,4},{9,8,7,6},{-10,10,-5,2}}; // 创建变量,用保存最大值、行号、列号 int max = arr[0][0],row = 0,col = 0; // 遍历集合 for(int i = 0;i < sizeof(arr)/sizeof(arr[0]);i++) { for(int j = 0;j < sizeof(arr[i])/sizeof(arr[i][0]);j++) { // 判断最大值 if(arr[i][j] > max) { max = arr[i][j]; row = i; col = j; } } } printf("max = %d,row = %d,col = %d\n",max,row,col); return 0; } /***************************** max = 10,row = 2,col = 1 ******************************/
字符数组
概念
元素类型为char字符型的数组,字符数组往往是用来存储字符串数据的。需要注意的一点是,我们C语言中的字符是字节字符。
字节字符:也就是一个字符占1个字节
测试题:
char a = 'A' //正确 char b = '1' //正确 char c = 65 //正确 这是ASCII码编码值,对应的值是'A' char d = "A" //错误 这是字符串中的写法,也就是char数组的写法,char d[1] = 'A' char e = '马' //错误 中文一个字符超过一个字节
语法
char 数组名[容量] char 数组名[行容量][列容量]
字符数组的语法就是之前所学一维数组和二维数组的语法,只不过数据类型是char而已。
注意:
如果我们的char数组初始化的时候,没有完全赋完值的时候,空出来的地方使用 \0 进行填充。
字符案例
案例1:
/* 需求:字符数组案例-输出一个字符串(I LOVE YOU!) */ #include <stdio.h> int main() { //准备一个测试字符串I LOVE YOU! char arr[11] = {'I',' ','L','O','V','E',' ','Y','O','U','!'}; //通过一个for循环进行遍历输出 for(int i = 0;i < sizeof(arr)/sizeof(char);i++) { printf("%c",arr[i]); } printf("\n"); return 0; }
案例2:
/* 需求:字符数组案例-输出一个用字符串组成的菱形图案 */ #include <stdio.h> int main() { //准备数据 char arr[][5]={{' ',' ','*'},{' ','*',' ','*',' '},{'*',' ',' ',' ','*'},{' ','*',' ','*',' '},{' ',' ','*'}}; //遍历数组 for(int i = 0;i < sizeof(arr)/sizeof(arr[0]);i++) { for(int j = 0;j < sizeof(arr[i])/sizeof(char);j++) { //打印菱形 printf("%c",arr[i][j]); } //内层循环每结束一轮,就是一行 printf("\n"); } printf("\n"); return 0; } /********************************** * * * * * * * * ***********************************
字符串和字符串结束标志
说明
-
C语言规定,字符串以字符'\0'作为结束标志
-
编译系统对字符串常量自动加一个'\0'作为结束标志
-
程序中往往通过判断'\0'来检测字符串是否结束
-
'\0'的ASCII码为0,不是一个可显示的字符,是“空操作符”,什么都不做,不会增加有效字符,仅是一个供判别的标志
字符数组的多样表示
我们的char数组可以以数组的方式一个个输出每个字符;我们的char数组也可以以字符串的方式整体
进行输出所有字符。具体如下面案例:
/* 需求:字符数组->字符串 */ #include <stdio.h> int main() { //字符串第1种表示 char s1[] = {'h','e','l','l','o',' ','w','o','r','l','d'}; //字符串第2种表示 char s2[] = {"hello world"}; //字符串第3种表示 char s3[] = "hello world"; //测试,使用字符串的方式打印 printf("%s\n",s1); printf("%s\n",s2); printf("%s\n",s3); return 0; } /********************************************** hello world hello world hello world ***********************************************/
注意:
-
字符串的长度与字符数组的长度从不一定相同。
-
利用字符串常量可以对字符数组进行初始化,但不能用字符串常量为字符数组赋值。
//正确写法:利用字符串常量给字符数组初始化 char b[15] = "china"; //错误写法:利用字符串常量给字符数组赋值 char b[15]; b[15] = "china"
字符串的基础操作
字符串输入
scanf("%s",数组名);
案例:
/* *需求:字符数组-字符串的输入输出 */ #include <stdio.h> int main() { //创建一个变量,用来存放人的名字 char name[20]; printf("请输入您的姓名:\n"); scanf("%s",name);//如果是字符串,这里不是变量地址,是变量名 printf("您的姓名:%s\n",name); return 0; } /********************************** 请输入您的姓名: 皮卡 您的姓名:皮卡 ***********************************/
注意:采用scanf进行字符串输入,要求字符串中不能存在空格,否则字符串遇到空格会结束。
-
fgets(数组名,数组容量,stdin);
说明:采用fgets进行字符串输入,可获取所有输入的字符串,包含 \n
,在实际的字符串处理时,我们
可能需要处理 \n
案例:
/* *需求:字符数组-字符串的输入输出 */ #include <stdio.h> int main() { //创建一个变量,用来存放人的名字 char name[20]; printf("请输入您的姓名:\n"); fgets(name,sizeof(name)/sizeof(char),stdin);//输入,返回地址 // scanf("%s",name); puts(name);//输出 // printf("您的姓名:%s\n",name); return 0; } /******************************* 请输入您的姓名: 马 杰克 马 杰克 *******************************/
注意:
-
如果输入的字符串不包含
空格
和换行
,可以使用scanf() | fgets();
-
如果输入的字符串需要包含
空格
和换行
,只能使用fgets(); -
经过对比,我们发现,在字符串的输入中,fgets()更好;
字符串输出
puts(数组名)
案例:
/* * 需求:字符数组-字符串的输入输出 */ #include <stdio.h> int main() { // 创建一个变量,用来存放人的名字 char name[20]; printf("请输入您的姓名:\n"); scanf("%s",name); puts(name);// 输出 问题?字符串如何拼接 printf("您的姓名是:%s\n",name); return 0; } /**************************************** 请输入您的姓名: 马杰克 马杰克 您的姓名是:马杰克 *****************************************/
-
printf("%s",数组名);
案例:
/* * 需求:字符数组-字符串的输入输出 */ #include <stdio.h> int main() { // 创建一个变量,用来存放人的名字 char name[20]; printf("请输入您的姓名:\n"); scanf("%s",name); printf("您的姓名是:%s\n",name); return 0; } /********************************* 请输入您的姓名: 马杰克 您的姓名是:马杰克 ***********************************/
字符串拼接
-
strcat(数组名,"需要拼接的字符串")
注意:需要引入#include <string.h>
/* *需求:字符数组-字符串的输入输出 */ #include <stdio.h> #include <string.h> int main() { //创建一个变量,用来存放人的名字 char name[20]; printf("请输入您的姓名:\n"); fgets(name,sizeof(name)/sizeof(char),stdin);//输入,返回地址 printf("%s\n",strcat(name,"走着!"));//输出 puts(strcat(name,"跑着!")); return 0; } /************************************ 请输入您的姓名: 马杰克 马杰克 走着! 马杰克 走着!跑着! ************************************/
字符串拷贝
-
strcpy(数组名,字符串)
注意:需要引入<string.h>库
说明:这个方法适合给字符串赋值用。
char str[16]="马杰克" // 初始化,正确 char str[16];str[16]="马杰克" // 赋值,错误! char str[16];strcpy(str,"马杰克")// 赋值,正确,结果:马杰克
案例:
/* * 需求:字符数组-字符串的输入输出 */ #include <stdio.h> #include <string.h> int main() { // 创建一个变量,用来存放人的名字 char name[20]; printf("请输入您的姓名:\n"); scanf("%s",name); strcpy(name,"你好"); printf("%s\n",name);// 输出 return 0; } /*********************** 请输入您的姓名: 马杰克 你好 *************************/
字符串比较
-
strcmp(字符串1,字符串2);
注意:
-
需要引入
<string.h>
-
返回的结果是boolean
案例:
/* * 需求:字符数组-字符串的输入输出 */ #include <stdio.h> #include <string.h> int main() { // 创建一个变量,用来存放人的名字 char username[20]; printf("请输入您的账户:\n"); scanf("%s",username); if(strcmp(username,"admin")) { printf("账户输入错误!\n"); } else { printf("账户输入正确!\n"); } return 0; } /********************************* 请输入您的账户: admin 账户输入正确! 请输入您的账户: admin1 账户输入错误! ***********************************/
获取字符串长度
-
strlen(字符串)
注意:
-
需要
<string.h>
-
返回字符串长度
案例:
/* * 需求:字符数组-字符串的输入输出 */ #include <stdio.h> #include <string.h> int main() { // 创建一个变量,用来存放人的名字 char username[20]; printf("请输入您的账户:\n"); scanf("%s",username); // 获取字符串长度 unsigned long len = strlen(username); if(strcmp(username,"admin")) { printf("账户输入错误!%lu\n",len); } else { printf("账户输入正确!%lu\n",len); } return 0; } /******************************** 请输入您的账户: admin 账户输入正确!5 请输入您的账户: admin1 账户输入错误!6 **********************************/
以上就是C语言学习第15天笔记,有什么问题还请指正,谢谢!
标签:arr,15,int,C语言,char,数组,printf,字符串 From: https://blog.csdn.net/weixin_64313142/article/details/140914082