笔记
一(昨天数组延续)
1.3对数组元素的常规操作
输入输出 | 所谓对数组进行输入输出,其实就是对任意一个元素进行重复性的输入输出,重复性的动作我们使用循环解决 注意:C语言不允许对数组外的其他数组整体进行输入输出,只能找到数组元素,对单个元素进行操作 |
求和值、均值 | 所谓求和值,就是将所有任意值进行累加,需要定义一个变量存储总和,但是要求,在使用之前必须清零 所谓均值,就是将数据总和除以总个数,均值不需要循环求 |
求最值 | 套路:将数组中的第一个先设置成当前的最值,然后拿当前的最值与数组中的任意一个元素进行比较,如果比较过程中,不满足条件,则跟新最值,直到所有数据都跟最值比较一遍后,得到最值 |
查找 | 存在性查找:当数组中出现要查找的数据时,立即结束本次查找 统计性查找:将数组全部元素进行遍历一遍,统计出要查找的个数 |
逆序 | 所谓逆序,就是将数据进行收尾交换 套路:1.需要进行首尾交换的次数是MAX/2(MAX 表示数组的长度) 2.交换双方a[i] <==>a[MAX-1-i](因为数组的第一项下标为零尾项为MAX-1) 3.交换三部曲 |
挑选数据 | 1.需要对数据进行筛选,给定筛选条件 2.需要使用一个新的数组,来存放筛选后的结果 |
排序 | 1.排序的概念:将一组数据按照关键字进行升序或降序的方式从新排列的过程称为排序 2.本课程讲述两种排序方式:冒泡排序,选择排序 |
冒泡排序 | 将较大或较小的数据,经由交换后,慢慢“浮到”数组顶端,如同水中的气泡一样,故名冒泡排序 原理:不断进行临近的两个数据进行比较,如果满足条件,则进行交换,每一轮都将一个最值数据“浮到”对应位置对于每一轮重复上述操作,直到排序结束 |
选择排序 | 将要排序的序列分为已排序序列和待排序序列 不断从待排序序列中找到最值,放入已排序序列的最后位置,随着待排序序列不断减少,已排序序列不断增长知道待排序序列没有元素,排序结束 |
示例:(以一个班级成绩为例)
#include<stdio.h>
#define MAX 10//宏定义一个常亮
int main(int argc, char const *argv[])
{
//定义一个数组,用于存储班级所有成员的成绩
int score[MAX] = {0};//部分赋值,后续成员会用零补齐
//输入部分
for (int i=0;i<MAX;i++)
{
printf("请输入第%d个学生的成绩:",i+1);
scanf("%d",&score[i]);
}
//输出部分
printf("班级所有成员的成绩为:\n");
for (int i=0;i<MAX;i++)
{
printf("%d\t",score[i]);
}
putchar(10);//换行符
//求和、均值
int sum=0;//记录总和
double avg=0;//记录均值
for (int i=0;i<MAX;i++)
{
sum+=score[i];
}
avg=1.0*sum/MAX;//sum avg为整型,avg为浮点型,要整型计算为浮点型要在计算中加入浮点型
printf("总和为:%d,均值为:%.2lf\n",sum,avg);
//最值
int max=0;//记录最大值
int maxi=0;//记录最大值所在的下标
//假设最大值为第一位,用第一位与其他值对比找到最大值
max=score[0];
maxi=0;
for (int i=0; i<MAX;i++)
{
if(max < score[i])
{
max=score[i];
maxi=i;
}
}
printf("成绩最高的是第%d位,成绩是%d分\n",maxi+1,max);
//查找
int search=0;//记录要查找值
int flag=0;//记录查找的值有几个
printf("请输入你要查找的值:\n");
scanf("%d",&search);
for (int i=0;i<MAX;i++)
{
if(score[i]==search)
{
flag++;
}
}
if(flag==0)
printf("未找到您要查找的值\n");
else
printf("查找到%d位\n",flag);
//逆序
for (int i=0;i<MAX/2;i++)
{
int temp=score[i];
score[i]=score[MAX-i-1];
score[MAX-i-1]=temp;
}
printf("逆序结果为\n");
for (int i=0;i<MAX;i++)
{
printf("%d\t",score[i]);
}
putchar(10);
//筛选
//以大于90分为例
int brr[MAX]={0};//记录筛选数据
int k =0;
for (int i=0;i<MAX;i++)
{
if(score[i]>=90)
{
brr[k]=score[i];//将满足条件的数据放入新数组
k++;//继续记录下一个数组元素
}
}
printf("大于90分的值为:\n");
for (int i=0;i<k;i++)
{
printf("%d\t",brr[i]);
}
putchar(10);
//排序
//以冒泡升序为例
for (int i=1;i<MAX;i++)//外层循环控制躺数
{
for(int j=0;j<MAX-i;j++)//内层循环控制元素,下标从零开始
{
if(score[j]>score[j+1])
{
int temp = score[j];
score[j]=score[j+1];
score[j+1]=temp;
}
}
}
printf("排序结果为:\n");
for (int i=0;i<MAX;i++)
{
printf("%d\t",score[i]);
}
putchar(10);
return 0;
}
二.二维数组
2.1引入目的
1)当写程序时,需要同时定义多个相同类型的一维数组时,可以选择二维数组来完成
2)所谓二维数组,就是多个一维数组的集合
3)二维数组也是变量的集合,是一个有行有列的容器
2.2二维数组的概述
定义格式 | 数据类型 数组名[常量1][常量2] 常量1:表示定义数组时数组的行数,也可以理解成一维数组的个数 常量2:表示定义数组时的列数,也可以理解成每个一维数组的长度 |
使用格式 | 1.数组名[行标]:表示下标为“行号”的那个一维数组的数组名 2.数组名[行标][列标]:表示下标为[行标][列标]的一个变量 |
二维数组的初始化 | 1.按行初始化:定义数组时,每一个一维数组的值使用一个花括号括起来 int arr[3][4] = {{1,2,3,4},{5,6,7,8},{9,9,9,9}}; 2.按行部分初始化:每个一维数组中,可以不填满,没有初始化的部分用0补齐 int arr[3][4] = {{1,2},{8}}; //1,2,0,0 8,0,0,0 0,0,0,0 3.按数组排列初始化:数组存储数据时,默认是按顺序存储,第一行存储满了,存第二行 int arr[3][4] = {1,2,3,4,5,6,7,8,9}; //1,2,3,4 5,6,7,8 9,0,0,0 4.特殊初始化:定义二维数组并初始化时,可以不指定第一维的大小,由初始化总个数除以列数向上取整,得到行数 int arr[][4] = {1,2,3,4,5,6}; //1,2,3,4 5,6,0,0 5.注意:定义二维数组时,无论任何时候,第二维都不能省略 |
2.3二维数组的相关操作
输入输出 | 对于二维数组而言,是有行有列的元素集合,需要使用双重循环来进行定位横标和纵标,在双重循环中,任意一个元素arr[i][j]来对其进行输入输出 |
求和,均值,最值 | 1.整体求和就是将任意一个元素进行累加 2.求每一行的和:将每一行的数据进行累加,求出结果,可以放入一个新数组 3.求整体最值:先将第一个当作最值,然后遍历所有的元素。进行比较,给定比较条件后,适当更新最值 |
转置 | 1.所谓转置,就是将二维数组行列互换 2.完成转置,需要使用一个新的数组 3.转置核心代码:brr[i][j]=arr[j][i] |
示例:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define M 3
#define N 4
int main(int argc, const char *argv[])
{
//输入部分
int arr[M][N];
for (int i=0;i<M;i++)
{
for (int j=0;j<N;j++)
{
printf("请输入%d行,%d列的元素:\n",i+1,j+1);
scanf("%d",&arr[i][j]);
}
}
putchar(10);
//输出部分
printf("数组的值为:\n");
for (int i=0; i<M;i++)
{
for (int j=0; j<N;j++)
{
printf("%d\t",arr[i][j]);
}
putchar(10);
}
//求和,均值,最值
int sum[M]={0};//用于存储每行的和
int SUM;//用于存储总的和
double avg[M]={0};//用于存储每行的均值
double AVG;//用于存储总的均值
int max[M]={0};//用于存储每行的最大值
int MAX;//用于存储总的最大值
MAX=arr[0][0];
for (int i=0;i<M;i++)
{
max[i]=arr[i][0];
for (int j=0;j<N;j++)
{
if(max[i]<arr[i][j])
{
max[i]=arr[i][j];
}
sum[i]+=arr[i][j];
}
if(MAX<max[i])
{
MAX=max[i];
}
SUM+=sum[i];
avg[i]=sum[i]*1.0/N;
printf("第%d行的和为%d,均值为%0.2lf,最大值为%d\n",i+1,sum[i],avg[i],max[i]);
}
AVG=SUM*1.0/(M*N);
printf("全部数组的和为%d,均值为%0.2lf,最大值为%d\n",SUM,AVG,MAX);
//转置
int brr[N][M];//用于存储转置后的数组
printf("转置后的数组为:\n");
for(int i=0;i<N;i++)
{
for (int j=0;j<M;j++)
{
brr[i][j]=arr[j][i];//将行列互换
printf("%d\t",brr[i][j]);
}
putchar(10);
}
return 0;
}
三.字符数组
3.1引入目的
1)所谓字符数组,就是存放字符的数字
2)但是,字符数组主要解决字符串的问题,这是字符数组引入的目的
3)字符串:用双引号括起来的0个或多个字符称为字符串,字符串默认有结束标识‘\0’
4)C语言中,没有专门用于处理字符串的变量,所有有关字符串的操作,都要基于字符数组来完成
5)字符数组,也分为一维字符数组、二维字符数组
3.2一维字符数组
3.2.1概述
定义格式 | char 数组名[常量] |
字符数组初始化 | 1.但字符处理字符数组 全部初始化:char arr[5] = {'h','e','l','l','o'} 部分初始化:char arr[5] = {'h','e','l'} //没有初始化的部分用0('\0')补齐 特殊初始化:char arr[] = {'h','e','l','l','o'} //此时字符数组的长度为5 2.字符串的形式初始化 整体初始化:char arr[10]={"hello"}; //或者 char arr[6]="hello" 特殊字符串初始化:char arr[]="ni hao" //此时,数字的实际长度7但是,字符串实际长度为6 |
3.2.2相关操作
由于对于字符数组的操作都是直接使用的是数组名,而数组名又是第一个元素的地址,所以,针对于字符数组处理字符串的不同操作,需要使用不同的函数来完成
输入输出 | 1.单字符的输入输出:跟整形数组一致,需要使用循环找到任意一个元素对其进行操作 2.字符串的输入输出:需要将字符数组看成一个整体,不需要使用循环完成 3.对于字符串的输入输出函数 puts();输出 gets();输入 |
求字符串实际长度 | strlen(数组名); 计算字符数组的长度 返回值为int型 |
字符串的赋值 | strcpy(数组1,数组2); 将数组2的字符串拷贝到数组1中 |
字符串的连接 | strcat(数组1,数组2); 将数组2的字符串连接到数组1后面 |
字符串的比较 | strcmp(数组1,数组2); 比较两着大小(依靠字母的ASCII吗 码值,从前向后比较) 返回值为:>0 <0 =0 |
作业
1.提示并输入一个字符串,统计该字符串中字母、数字、空格以及其他字符的个数
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
char arr[100]={0};
int len;
int ch_ar=0,in_t=0,k_g=0,other=0;
printf("请输入一个字符串\n");
gets(arr);
len=strlen(arr);
for (int i=0;i<len;i++)
{
if((arr[i]>='a'&&arr[i]<='z')||(arr[i]>='A'&&arr[i]<='Z'))
ch_ar++;
else if(arr[i]>='0'&&arr[i]<='9')
in_t++;
else if(arr[i]==' ')
k_g++;
else
other++;
}
printf("该字符串中字母有%d个,数字有%d个,空格有%d个,其他字符有%d个\n",ch_ar,in_t,k_g,other);
return 0;
}
2.提示并输入一个字符串,求出该字符串中所有数字的总和
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
char arr[100]={0};
int len;
int sum;
printf("请输入一个字符串\n");
gets(arr);
len=strlen(arr);
for (int i=0;i<len;i++)
{
if(arr[i]>='0'&&arr[i]<='9')
{
sum+=(int)arr[i]-48;
}
}
printf("该字符串中数字的和为%d\n",sum);
return 0;
}
3.定义一个4*3的二位整型数组,完成对二维数组的输入输出。并将该二维数组中的每一行的最值放入到一个一维数组中并对该一维数组进行升序排序后输出
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define M 4
#define N 3
int main(int argc, const char *argv[])
{
int arr[M][N];
for (int i=0;i<M;i++)
{
for (int j=0;j<N;j++)
{
printf("请输入%d行,%d列的元素:\n",i+1,j+1);
scanf("%d",&arr[i][j]);
}
}
putchar(10);
printf("数组的值为:\n");
for (int i=0; i<M;i++)
{
for (int j=0; j<N;j++)
{
printf("%d\t",arr[i][j]);
}
putchar(10);
}
int max[M]={0};
int MAX=0;
for (int i=0;i<M;i++)
{
max[i]=arr[i][0];
for (int j=0;j<N;j++)
{
if(max[i]<arr[i][j])
{
max[i]=arr[i][j];
}
}
}
for(int i=1;i<M;i++)
{
for(int j=0;j<M-i;j++)
{
if(max[j]>max[j+i])
{
int temp=max[j];
max[j]=max[j+1];
max[j+1]=temp;
}
}
}
printf(":各行最大值升序后为\n");
for(int i=0;i<M;i++)
{
printf("%d\n",max[i]);
}
return 0;
}
4.提示并输入两个一维整形数组,求这两个数组的交集
#include<stdio.h>
int main(int argc, char const *argv[])
{
int arr[100]={0};
int brr[100]={0};
int crr[100]={0};
int count=0;
int len_a,len_b;
printf("请输入第一个整型数组的个数:\n");
scanf("%d",&len_a);
getchar();
printf("请输入第一个整型数组:\n");
for(int i=0;i<len_a;i++)
{
scanf("%d",&arr[i]);
getchar();
}
printf("请输入第二个整型数组的个数:\n");
scanf("%d",&len_b);
getchar();
printf("请输入第二个整型数组:\n");
for(int i=0;i<len_b;i++)
{
scanf("%d",&brr[i]);
getchar();
}
printf("两个数组的交集为:\n");
for (int i = 0; i <len_a ; i++)
{
for(int j=0;j<len_b;j++)
{
if(arr[i]==brr[j])
{
crr[count]=arr[i];
printf("%d\t",crr[count]);
count++;
}
}
}
putchar(10);
return 0;
}
5.完成注册和登录功能:使用两个一维字符数组存储账号和密码
注册:完成账号和密码的输入
登入:将登入的账号密码和注册的账号密码进行匹配,如果相等,则登入成功,否则登入失败
#include<stdio.h>
#define M 100
#define N 100
int main(int argc, char const *argv[])
{
char zhang_hao[M];
char mi_ma[M];
char zhang_hao_zc[M][N];
char mi_ma_zc[M][N];
int flag=0,num=0,flag1=0,flag2=0;
while(1)
{
printf("1.注册\n");
printf("2.登入\n");
printf("3.退出\n");
printf("请选择你需要的选项:\n");
scanf("%d",&num);
getchar();
switch(num)
{
case 1:
printf("请注册你的账号:\n");
scanf("%s",zhang_hao_zc[flag]);
getchar();
printf("请注册你的密码:\n");
scanf("%s",mi_ma_zc[flag]);
getchar();
flag++;
printf("注册成功!\n");
break;
case 2:
printf("请输入你的账号:\n");
scanf("%s",zhang_hao);
getchar();
for(int i=0;i<flag;i++)
{
if(strcmp(zhang_hao,zhang_hao_zc[i])==0)
{
printf("请输入你的密码:\n");
scanf("%s",mi_ma);
getchar();
if(strcmp(mi_ma,mi_ma_zc[i])==0)
{
printf("登入成功!\n");
flag2=1;
}
else
printf("密码错误!\n");
}
}
if (flag2==0)
printf("账号错误!\n");
break;
case 3:
flag1=1;
break;
case 4:
for(int i=0;i<flag;i++)
{
printf("第%d位的账号为:%s\n",i+1,zhang_hao_zc[i]);
printf("\t\t密码为:%s\n",mi_ma_zc[i]);
}
break;
}
if(flag1==1)
break;
}
return 0;
}