欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > C语言基础:第09天笔记

C语言基础:第09天笔记

2025/11/22 16:15:56 来源:https://blog.csdn.net/qq_63504030/article/details/146552814  浏览:    关键词:C语言基础:第09天笔记

内容提要

  • 数组

    • 字符数组

  • 综合案例:学生成绩管理系统

数组

字符数组

字符串拼接

语法:

 strcat(字符串1,需要拼接的字符串2);        char name[] = "张三";

解释:

①这里的字符串,可以是字符串常量,也可以是字符数组或者字符指针。

②这里需要将字符串2拼接到字符串1中,所以需要字符串1有足够大的空间去容纳字符串2

引入:

 #include <string.h>

案例:

  • 需求:将两个字符串拼接为一个字符串

  • 代码:

     /*************************************************************************> File Name:    demo01.c> Author:       > Description:  > Created Time: 2025年03月13日 星期四 09时47分53秒************************************************************************/​#include <stdio.h>#include <string.h>​int main(int argc,char *argv[]){//创建一个数组,用来接收字符串常量,控制台输入char name[20];​printf("请输入您的名字:\n");//通过键盘录入fgets(name,sizeof(name) / sizeof(name[0]),stdin);//通过显示器输出fputs(strcat(name,"你好"),stdout);//带""的字符串时,内存加一个\0printf("\n");return 0;}

    注意:

    字符串1必须是字符数组,长度必须是够大,以便于能够容纳被链接的字符串。

    ②连接后系统将自动取消 字符串1后面的结束符 \0

    字符串2 可以是字符数组名,也可以是字符串常量,如:strcat(s1"def");srrcat(s1s2);

字符串拷贝

语法:

 strcpy(数组名,字符串);

解释:简单来说,类似于将一个字符串赋值给一个字符数组

引入:

 #include <string.h>

说明:这个函数适合给字符串赋值

 char str[20] = "张三";            //正确char str[20]; str = "张三";       //错误char str[20]; strcpy(str,"张三"); //正确

案例:

  • 需求:录入名字,赋值给一个字符数组

  • 代码:

     /*************************************************************************> File Name:    demo02.c> Author:       > Description:  > Created Time: 2025年03月13日 星期四 10时26分54秒************************************************************************/​#include <stdio.h>#include <string.h>​int main(int argc,char *argv[]){char name[20];​printf("请输入名字\n");fgets(name,sizeof(name) / sizeof(name[0]),stdin);​//重新赋值strcpy(name,"谢谢回顾");​printf("同学的名字是%s\n",name);​return 0;}​
    
字符串比较

语法:

 strcmp(字符串1,字符串2);

字符串:字符串常量、字符数组、字符指针

引入:

#include <string.h>

功能:如果是英文,比较两个字符串对应位置字符ASCII的大小(字典顺序比较)

返回值:

  • 若字符串1等于字符串2,返回0

  • 若字符串1大于字符串2,返回正数(>0)

  • 若字符串1小于字符串2,返回负数(<0)

说明:

①执行这个函数时,自左到右逐个比较对应字符的ASCII的值,直到发现了不同字符或者字符串结束符\0为止

②对字符串不能用数值型比较符,比如:“abc” = "abc" ,比较是错误的

③字符串1和字符串2可以是字符数组,也可以是字符指针或者字符串常量

案例:

  • 需求:通过控制台输入用户名和密码,并进行校验

  • 代码:

    /*************************************************************************> File Name:    demo03.c> Author:       > Description:  > Created Time: 2025年03月13日 星期四 11时15分44秒************************************************************************/#include <stdio.h>
    #include <string.h>int main(int argc,char *argv[])
    {//用户登录案例//创建两个字符数组,用来接收控制台输入的用户名和密码char username[20],password[8];printf("--------------用户登录-------------\n");printf("请输入您的用户名:\n");scanf("%s",username);printf("请输入您的密码:\n");scanf("%s",password);//校验if(!strcmp(username,"admin") && !strcmp(password,"123456")){printf("登录成功!\n");}else{printf("用户名或者密码错误!\n");}return 0;
    }
    

字符串长度

语法:

strlen(字符串);

引用:

#include <string.h>

注意:返回字符串中包含字符的实际个数,不含\0

案例:

  • 需求:字符串长度案例

  • 代码:

    /*************************************************************************> File Name:    demo04.c> Author:       > Description:  > Created Time: 2025年03月13日 星期四 11时30分56秒************************************************************************/#include <stdio.h>
    #include <string.h>int main(int argc,char *argv[])
    {//测试数据1char s1[] = {'h','i','\0','h','i','\0'};printf("数组长度:%lu,字符串长度:%lu\n",sizeof(s1)/sizeof(s1[0]),strlen(s1));//测试数据2char s2[] = "hi\0hi\0";printf("数组长度:%lu,字符串长度:%lu\n",sizeof(s2)/sizeof(s2[0]),strlen(s2));//测试数据3char s3[] = {'h','e','l','l','o'};printf("数组长度:%lu,字符串长度:%lu\n",sizeof(s3)/sizeof(s3[0]),strlen(s3));//测试数据4char s4[] = "hello";printf("数组长度:%lu,字符串长度:%lu\n",sizeof(s4)/sizeof(s4[0]),strlen(s4));return 0;
    }
    
  • 代码:

    /*************************************************************************> File Name:    demo05.c> Author:       > Description:  > Created Time: 2025年03月13日 星期四 14时27分46秒************************************************************************/#include <stdio.h>
    #include <ctype.h>int main(int argc,char *argv[])
    {//创建一个数组char string[100];//创建两个变量;用来标记遍历输出字符是否为空格,默认是,0-是,1-不是,num记录单词个数int world = 0;int num = 0;//创建一个变量char c;//通过控制台输入fgets(string,sizeof(string)/sizeof(string[0]),stdin);//遍历for (int i = 0; (c = string[i])!= '\0'; i++){//如果取出的字符是空格,就设置word为0if (isspace(c))//字符是空格{//标记word = 0world = 0;}else//字符{//如果上一个字符是空格,就需要统计if(world == 0){//更改word = 1world = 1;//统计num++;}}}printf("%s中有%d个单词\n",string,num);return 0;
    }
    

    运行结果:

综合案例:学生成绩管理系统

需求:

  1. 存储最多50名学生的信息(不使用结构体)

  2. 每个学生包含:

    • 学号(字符数组)

    • 姓名(字符数组)

    • 3门课程成绩(一维数组)

  3. 实现功能菜单:

    • 添加学生信息

    • 显示所有学生信息

    • 计算学生平均分

    • 查找最高分科目

    • 退出系统

代码:

/*************************************************************************> File Name:    scores_mg.c> Author:       > Description:  综合案例:学生成绩管理系统> Created Time: 2025年03月13日 星期四 15时13分43秒************************************************************************/#include <stdio.h>
#include <string.h>// 定义符号常量
#define MAX_STU 50     // 学生数量
#define NAME_LEN 20    // 学生名字最大长度
#define ID_LEN 8       // 学生学号最大长度
#define COURSE_NUM 3    // 学生课程数量// 全局数组实现数据存储
char stu_id[MAX_STU][ID_LEN];        //学号
char stu_name[MAX_STU][NAME_LEN];    //姓名     //二维数组
int  scores[MAX_STU][COURSE_NUM];      //成绩
int  stu_count = 0;                  //当前实际学生数/*** 成绩录入* */
int get_valid_score(const char* course) //这里可以理解为一个不能改变值的字符串
{//用来接收控制台输入的成绩int score;while(1){printf("请输入%s成绩(0-100):",course);//对成绩校验if(scanf("%d",&score) == 1 && score >=0 && score <= 100){return score;}//校验不通过//清理缓冲while(getchar() != '\n');printf("成绩输入有误!\n");}
}/*** 添加学生*/
void add_student()
{//添加前,需要校验数组是否已满if (stu_count >= MAX_STU){printf("添加学生的人数已经达到最大值!\n");return;  //跳出函数,后续代码不会再执行}printf("\n--- 添加第%d个学生 ---\n",stu_count +1);//输入学号printf("请输入学号:\n");scanf("%s",stu_id[stu_count]);// 需要清除缓冲while(getchar() != '\n');//输入姓名printf("请输入姓名:\n");scanf("%[^\n]",stu_name[stu_count]);// 匹配除了\n以外的输入// 输入成绩scores[stu_count][0] = get_valid_score("语文");scores[stu_count][1] = get_valid_score("数学");scores[stu_count][2] = get_valid_score("英语");stu_count++;}/*** 显示所有学生信息*/
void show_all()
{// 非空校验if (stu_count == 0){printf("暂无学生信息!\n");return;}// 格式化输出数据printf("\n%s\t%s\t%s\t%s\t%s\t\n","学号","姓名","语文","数学","英语") ;//表格数据for (int i = 0; i < stu_count; i++){// 获取学号和姓名printf("%s\t%s\t",stu_id[i],stu_name[i]);// 获取成绩for (int j = 0; j < COURSE_NUM; j++){printf("%d\t",scores[i][j]);}printf("\n");}printf("\n");
}/*** 计算平均分*/
void calc_avg()
{//非空校验if (stu_count == 0){printf("暂无学生信息!\n");return;}//创建一个数组,用来接收控制台输入的学号char target_id[ID_LEN];printf("请输入要查询的学号:\n");scanf("%s",target_id);// 遍历数组,通过学号在stu_id数组中找到对应下标for (int i = 0; i < stu_count; i++){//字符判断strcmpif (!strcmp(stu_id[i],target_id))//匹配学号{float sum = 0;  //计算总分//通过下标在stu_scores数组中匹配对应成绩for(int j = 0; j < COURSE_NUM; j++){sum += scores[i][j];//计算总分}printf("学生%s的平均分%.2f\n",stu_name[i],sum/COURSE_NUM);return;}}//数据匹配不上printf("未找到该学生!\n");}/*** 查看最高分*/
void find_max()
{//创建一个变量,记录最高分int max_score = -1;// 创建一个变量,记录最高分课程char max_course[NAME_LEN];//创建一个变量,记录学生姓名char max_stu[NAME_LEN];//遍历数组for (int i = 0; i < stu_count; i++)  // 遍历学生{for(int j = 0; j < COURSE_NUM; j++) //遍历学生对应课程{if(scores[i][j] > max_score) // 求最高成绩{max_score = scores[i][j];//最高分对应的学生名字strcpy(max_stu,stu_name[i]);//最高分对应课程名称switch(j){case 0: strcpy(max_course,"语文");break;case 1: strcpy(max_course,"数学");break;case 2: strcpy(max_course,"英语");break;}}}}//输出if(max_score != -1) printf("最高分记录:%s的%s获得%d分\n",max_stu,max_course,max_score);elseprintf("没有匹配!\n");
}/***入口*/
int main(int argc,char *argv[])
{// 定义一个变量,用来接收用户输入的选项int choice;while(1){//设计头printf("==============================\n");printf("=    学生成绩管理系统 v1.0   =\n");printf("==============================\n");printf("1.添加学生信息\n");printf("2.显示所有学生信息\n");printf("3.查看平均分\n");printf("4.查看最高分\n");printf("5.退出系统\n");printf("请选择操作:");//过滤非法输入int result = scanf("%d",&choice);if(result != 1){//清空缓冲while(getchar()!='\n');printf("请输入1-5的数字!\n");continue;}//校验输入switch(choice){case 1:// 添加学生信息add_student();break;case 2:// 显示所有学生信息show_all();break;case 3:// 查看平均分calc_avg();break;case 4:// 查看最高分find_max();break;case 5:printf("系统已经退出!\n");return 0; // 退出main函数,其实就是进程结束default:printf("无效输入\n");}}return 0;
}

中文字符在内存中存储?

在C语言中,中文字符通常使用多字节编码(如UTE-8或GBK)进行存储。由于中文字符的编码长度通常大于1个字节,因此它们在内存中的存储方式与单字节字符(如ASCII字符)有所不同。以下是中文字符在内存中存储的详细说明:

字符编码

中文字符的编码方式决定了它们在内存中的存储形式。常见的编码方式包括:

  • UTE-8:变长编码,每个中文字符通常占用3个字节。

  • GBK:周定长度编码,每个中文字符占用2个字节。

内存存储

在C语言中,中文字符是以字节序列的形式存储在内存中的。例如:

  • 使用UTE-8编码时,中文字符“你”的编码是 BxE4 0xBD 0xAB ,占用3个字节。

  • 使用GBK编码时,中文字符"你"的编码是 Bxc4 BxE3 ,占用2个字节。

    在内存中,这些字节按照编码顺序连续存储

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com