目录
思维导图:
学习目标:
- 一周掌握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;
}