目录
思维导图:
学习目标:
学习内容:
1. 数组
1.1 对数组元素的常规操作
1.1.1 逆序
1.1.2 挑选数据
1.1.3 排序
1. 冒泡排序
2. 选择排序
2. 二维数组
2.1 二维数组的概念
2.1.1. 定义格式
2.2.2.初始化
2.2 二维数组的相关操作
2.2.1. 输入输出
2.2.2 求和、均值、最值
2.2.3 转置
3. 字符数组
3.1 一维字符数组
3.1.1. 定义格式
3.1.2. 字符数组初始化
1.单字符处理字符数组
2. 字符串的形式初始化
3.2 strlen
3.3 strcpy
3.4 strcat
3.5 stcmp
例如:
课内练习:
课外作业:
思维导图:
学习目标:
- 一周掌握C基础知识
学习内容:
1. 数组
1.1 对数组元素的常规操作
1.1.1 逆序
所谓逆序,就是将数据进行首尾交换,例如,数组原型:1,2,3,4,5。逆序后的数组为:5,4,3,2,1。
总结套路:
1、需要进行首尾交换的次数是 MAX/2 (MAX表示数组的长度)
2、交换双方:arr[i] arr[MAX-1-i]
3、交换三部曲
例如:
//将数组进行逆序
for(int i=0; i<MAX/2; i++) //只需遍历前一半数组
{ //交换三部曲
int temp = score[i];
score[i] = score[MAX-1-i];
score[MAX-1-i] = temp;
} //输出逆序后的数组
printf("逆序后的结果为:");
for(int i=0; i<MAX; i++) {
printf("%d\t", score[i]);
}
putchar(10);
1.1.2 挑选数据
int k=0;
for(i=0;i<MAX;i++)
{
if(score[i]>=90){
arr[k]=score[i];
k++;
}
}
for(i=0;i<MAX;i++)
{
printf("%d\t",arr[i]);
}
1.1.3 排序
1. 冒泡排序
将较大或者较小的数据,经由交换后,慢慢“浮到”数组顶端,如同水中的气泡一样,故名冒泡排序 原理:不断进行相邻的两个数据进行比较,如果满足条件,则进行交换,每一轮都会将一个最值数据"浮到"对应位置 对于每一轮重复上述操作,直到所有数据排序结束
例如:
for(i=0;i< MAX-1;i++){
for(int j=0;j<MAX-i-1;j++){
if(score[j]>score[j+1]){
int temp=score[j];
score[j]=score[j+1];
score[j+1]=temp;
}
}
}printf("排序后的结果为:");
for(i=0;i<MAX;i++)
{
printf("%d\t",score[i]);
}
2. 选择排序
将要排序的序列分为已排序序列和待排序序列 不断从待排序序列中找到最值,放入已排序序列的最后位置,随着待排序序列不断减少,已排序序列不断增长 直到待排序序列没有元素,排序结束。
例如:
int maxj=0;
for(i=0;i<MAX;i++)
{
maxj=i;
for(int j=i+1;j<MAX;j++){
if(score[maxj] < score[j]){
maxj=j;
}
}
if(maxj != i){
int temp=score[i];
score[i]=score[maxj];
score[maxj]=temp;
}
}
printf("排序后的结果为:");
for(i=0;i<MAX;i++)
{
printf("%d\t",score[i]);
}
2. 二维数组
2.1 二维数组的概念
2.1.1. 定义格式
数据类型 数组名[常量1][常量2];
2.2.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.2 二维数组的相关操作
2.2.1. 输入输出
对于二维数组而言,是有行有列的元素集合,需要使用双重循环来进行定位横标和纵标
在双重循环中,找到任意一个元素 arr[i][j] 来对其进行输入输出
例如:
#include <stdio.h>
#define M 3
#define N 4
int main(int argc, char const *argv[])
{
int i=0,j=0;
int s[M][N];
for(int i=0;i<M;i++){
for(int j=0;j<N;j++){
printf("请输入第%d行第%d列的元素:",i+1,j+1);
scanf("%d",&s[i][j]);
}
printf("\n");
}
printf("数组分别是:\n");
for(int i=0;i<M;i++){
for(int j=0;j<N;j++){
printf("%d\t",s[i][j]);
}
printf("\n");
}
2.2.2 求和、均值、最值
1、整体求和就是将任意一个元素进行累加
2、求每一行的和:将每一行的数据进行累加,求出结果后,可以放入一个新数组
3、求整体最值:先将第一个当做最值,然后遍历所有的元素,进行比较,给定比较条件后,适当更新最值
4、求每一行的最值:在外层循环内,先将当前行的第一个当做最值,然后遍历当前行的所有数据,进行比较和更新
例如:
int a[3]={0};
for(i=0;i<M;i++){
for(j=0;j<N;j++){
a[i]+=s[i][j];
}
}
printf("每一行的和分别是:\n");
for(i=0;i<M;i++){
printf("%d\t",a[i]);
}
printf("\n");
int max=s[0][0];
int maxi=0;
int maxj=0;
for ( i = 0; i < M; i++)
{
for (j = 0;j < N; j++)
{
if(max<s[i][j]){
max = s[i][j];
maxi = i+1;
maxj = j+1;
}
}
}
printf("最大值为第%d行,第%d列,值为%d",maxi,maxj,max);
printf("\n");
int max1={0};
for(i=0;i<M;i++){
max1=s[i][0];
for ( j = 0; j < N; j++)
{
if (max1 < s[i][j])
{
max1 = s[i][j];
}
}
printf("第%d行的最大值为:%d\n", i+1,max1);
}
printf("\n");
2.2.3 转置
1、所谓转置,就是将二维数组行列互换
2、完成转置,需要使用一个新数组
3、转置核心代码:brr[j][i] = arr[i][j]
例如:
int brr[N][M] = {0};
for(int i=0; i<M; i++) //外行
{
//找到当前行的任意一个元素
for(int j=0; j<N; j++)
{
//在此处找到了任意一个元素 arr[i][j]
brr[j][i] = s[i][j];
}
}
//输出转置后的结果
printf("上述二维数组转置后的结果如下:\n");
for(int i=0; i<N; i++)
{
for(int j=0; j<M; j++)
{
printf("%d\t", brr[i][j]);
}
printf("\n");
}
3. 字符数组
3.1 一维字符数组
3.1.1. 定义格式
char 数组名[常量];
3.1.2. 字符数组初始化
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 strlen
格式:#include <string.h> size_t strlen(const char *s);
功能:计算字符串的长度,不包括结尾的'\0'
参数:要计算长度的字符串的首地址
返回值:计算的结果
3.3 strcpy
格式:#include <string.h> char *strcpy(char *dest, const char *src);
功能:将src指向的字符串复制到dest指向的缓冲区里
参数: dest:目标字符串 src :源字符串
返回值: 同dest
注意: 要保证dest足够大,否则会出现越界访问的问题!!!
3.4 strcat
格式:#include <string.h> char *strcat(char *dest, const char *src);
功能:将src指向的字符串追加到dest指向的字符串后面 回复覆盖 dest 结尾的 '\0'
参数:
dest:目标字符串
src :源字符串
返回值: 同dest
注意:要保证 dest 足够大
3.5 stcmp
格式:#include <string.h> int strcmp(const char *s1, const char *s2);
功能:比较两个字符串
参数: s1 和 s2 就是要参与比较的两个字符串 //是逐个比较两个字符串中字符的ascii码
返回值:
>0 s1>s2
==0 s1==s2
<0 s1<s2
例如:
#include<stdio.h>
#include<string.h>
int main(int argc, const char *argv[])
{
//定义两个字符数组初始化字符串
char str1[20] = "hello world";
char str2[] = "I Love China";
//测试strlen
int len = strlen(str2); //求字符串2的实际长度
printf("len = %d\n", len); //12
int size = sizeof(str2); //求字符串所占字符数组的长度
printf("size = %d\n", size); //13
size = sizeof(str1); //求字符数组1的大小
printf("size = %d\n", size); //20
//比较两个字符串的大小
if(strcmp(str1, str2) >0)
{
printf("%s大\n", str1);
}else if(strcmp(str1, str2) < 0)
{
printf("%s小\n", str1);
}else
{
printf("一样大\n");
}
//完成两个字符串的赋值,将str2赋值给str1
strcpy(str1, str2); // str1 = str2
printf("拷贝后:str1 = %s, str2 = %s\n", str1, str2);
//完成两个字符串的连接, 将str2连接到str1后面
strcat(str1, str2);
printf("连接后:str1 = %s, str2 = %s\n", str1, str2);
return 0;
}
课内练习:
杨辉三角
解析:
课外作业:
1.提示并输入一个字符串,统计该字符串中字母、数字、空格以及其他字符的个数
解析:
#include<stdio.h>>
#include<string.h>
int main(int argc, char const *argv[])
{
char s[1001]={0};
int i=0;
int zimu=0;
int kg=0;
int dight=0;
int other=0;
printf("请输入字符串:");
gets(s);
while (s[i] != '\n' && s[i] != '\0') {
if((s[i]>='A' && s[i]<='Z') || (s[i]>='a' && s[i]<='z')){
zimu++;
}else if (s[i]>='0' && s[i]<='9')
{
dight++;
}else if (s[i] == ' ')
{
kg++;
}else
{other++;}
i++;
}
printf("该字符串中字母有%d个、数字有%d个、空格有%d个,其他字符有%d个",zimu,dight,kg,other);
return 0;
}
2.提示并输入一个字符串,求出该字符串中所有数字的总和
解析:
#include<stdio.h>>
#include<string.h>
int main(int argc, char const *argv[])
{
char s[1001]={0};
int i=0;
int sum=0;
printf("请输入字符串:");
gets(s);
while (s[i] != '\n' && s[i] != '\0') {
if (s[i]>='0' && s[i]<='9')
{
sum=sum+(s[i]- '0');
}
i++;
}
printf("%d",sum);
return 0;
}
3.定义一个4*3的二维整形数组,完成对二维数组的输入、输出。并将该二维数组中每一行的最值放入到一个一维数组中,并对该一维数组进行升序排序后输出。
解析:
#include <stdio.h>
int main(int argc, char const *argv[])
{
int s[4][3]={0};
int a[4]={0};
int i=0,j=0;
int temp=0;
for(i=0;i<4;i++){
for ( j = 0; j < 3; j++)
{
printf("请输入第%d行第%d列的元素:",i+1,j+1);
scanf("%d",&s[i][j]);
}
printf("\n");
}
printf("数组分别是:\n");
for(i=0;i<4;i++){
for ( j = 0; j < 3; j++)
{
printf("%d\t",s[i][j]);
}
printf("\n");
}
for(i=0;i<4;i++){
a[i]=s[i][0];
for(j=0;j<3;j++){
if(a[i] < s[i][j]){
a[i]=s[i][j];
}
}
}
printf("该一维数组进行升序排序后输出为:");
for(i=1;i<4;i++){
for(j=0;j<4-i;j++){
if(a[j] > a[j+1]){
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
for(i=0;i<4;i++)
{
printf("%d\t",a[i]);
}
printf("\n");
return 0;
}
4.提示并输入两个一维整形数组,求这两个数组的交集。
解析:
#include <stdio.h>
#include <string.h>
#define M 30
int main(int argc, const char *argv[])
{
int arr[M]={0};
int brr[M]={0};
int crr[M]={0};
int N=0;
int count=0;
printf("请输入两个一维数组的长度:\n");
scanf("%d",&N);
printf("请输入第一个数组的数字:\n");
for(int i=0;i<N;i++){
printf("第%d个:",i+1);
scanf("%d",&arr[i]);
putchar(10);
}
printf("请输入第二个数组的数字:\n");
for(int i=0;i<N;i++){
printf("第%d个:",i+1);
scanf("%d",&brr[i]);
putchar(10);
}
int k=0;
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
if(arr[i]==brr[j]){
crr[k]=arr[i];
k++;
count++;
break;
}
}
}
int temp=0;
for(int i=0;i<N;i++){
for(int j=i+1;j<N;j++){
if(crr[i]==crr[j]){
for(temp = j;temp<N-1;temp++)
crr[temp]=crr[temp+1];
j--;
N--;
}
}
}
printf("两个数组的交集为:\n");
for(int i=0;i<N;i++){
if (count == 0) {
printf("没有交集。\n");
}else
printf("%d\t",crr[i]);
}
putchar(10);
// 如果交集中没有元素,输出相应的信息
return 0;
}
5.完成注册和登录功能:使用两个一维字符数组存储账户和密码
注册:完成对账号和密码的输入
登录:将登录账号和密码跟注册的账号和密码进行匹配,如果相等,则登录成功,否则,登录失败
解析:
#include<stdio.h>
int main(int argc, const char *argv[])
{
//定义变量存储菜单选项
int menu = 0;//定义变成存储注册账号和密码,以及登录账号和密码
char sign_usrName[20] = ""; //注册账号
char sign_pwd[20] = ""; //注册密码
char login_usrName[20] = ""; //登录账号
char login_pwd[20] = ""; //登录密码while(1)
{
printf("\t\t======XXX管理系统========\n");
printf("\t\t1、注册\n");
printf("\t\t2、登录\n");
printf("\t\t0、退出\n");printf("请输入操作码:");
scanf("%d", &menu);
getchar(); //吸收回车//对操作码多分支选择
switch(menu)
{
case 1:
{
//提示用户输入账号和密码
while(1)
{
printf("请输入注册账号:");
gets(sign_usrName);
printf("请输入注册密码:");
gets(sign_pwd);//判断账号和密码是否合格
if( !(strlen(sign_usrName)>=6 && strlen(sign_pwd)>=6) )
{
printf("注册失败,请重新注册\n");
continue;
}
break; //表示注册成功
}}
break;
case 2:
{
//提示并输入登录账号和密码
printf("请输入登录账号:");
gets(login_usrName);
printf("请输入登录密码:");
gets(login_pwd);//判断是否登录成功
if(strcmp(sign_usrName,login_usrName)==0 && strcmp(sign_pwd,login_pwd)==0)
{
printf("登录成功\n");
exit(0); //退出程序
}else
{
printf("账号或密码错误\n");
}}
break;
case 0:goto END;
default:printf("您输入的功能有误,请重新输入\n");
}}
END:
return 0;
}