数据结构 day1

avatar
作者
筋斗云
阅读量:2

目录

思维导图:

学习内容:

1. 结构体

1.1 定义及初始化

1.1.1 定义格式

1.1.2 使用结构体类型定义变量

1.2 结构体访问成员

1.3 结构体变量的输入输出

1.4 结构体数组

1.5 结构体的大小

课外作业:


思维导图:


学习内容:

1. 结构体

1.1 定义及初始化

1.1.1 定义格式

        struct 结构体名称
{
      成员类型1  成员变量1;
      成员类型2  成员变量2;
      。。。
      成员类型n  成员变量n;  
};
注意事项:
        1、struct是定义结构体类型的关键字,不能省略
        2、结构体名称:标识符,符合命名规则,一般建议首字母大写
        3、成员属性使用一对花括号包裹起来
        4、成员类型可以是基本数据类型,也可以是构造数据类型、指针类型
        5、定义结束后,必须加上 分号结尾
        6、举个例子
    struct  Stu
{
    char name[20];         //姓名
    int age;                //年龄
    double score;           //成绩
};

1.1.2 使用结构体类型定义变量

#include<stdio.h>  //定义一个英雄类型 struct Hero {     char name[30];    // 英雄名称     int blood;        //英雄血量     char skill[4][20];    //技能     int kill;            //击杀人头数     int die;             //死亡数量     int assiant;         //辅助数量 } h2;           //定义类型时,顺便定义一个变量  //定义类型顺便定义变量 struct {     char name[20];      //学生姓名     int age;              //年龄     double score;        //成绩 }s1;        //该结构体称为无名结构体     int main(int argc, const char *argv[]) {     //使用自定义类型,定义一个英雄变量     struct Hero h1, h3;              return 0; } 

1.2 结构体访问成员

1>  普通结构体变量访问成员是,使用成员运算符 ‘.’ 来进行,读作 "的"

        例如:s1.name s1.score

2>  结构体指针变量访问成员,使用成员运算符 '->'来进行,读作 '的'

        例如:struct Stu *ptr = &s1; ptr->name ptr->score

3>  在进行成员访问时,访问的最终的类型,就是最后一个成员所表示的结果类型

        例如:s1.name 是字符数组类型, ptr->score 是double类型

4>  当一个结构体类型中的某个成员变量也是一个结构体变量时,如果要进行最深一级的访问,需要使用成员运算符一级一级进行访问

例如:

#include<stdio.h>  //定义生日结构体类型 struct Date {     int year;         //年份     int month;        //月份     int day;          //日期 };  //定义学生类型 struct Stu {     char name[20];       //姓名     double score;        //成绩     struct Date birthday;   //生日 };  /***************主程序**********************/ int main(int argc, const char *argv[]) {     //定义一个学生,并初始化     struct Stu s = {"张三", 99.5, {2000,1,1}};     s.score = 100;        //访问成员更改内容     printf("%s, %.2lf, %d-%d-%d\n",s.name, s.score, s.birthday.year, s.birthday.month, s.birthday.day);     //更改名字     strcpy(s.name , "lisi");     printf("%s, %.2lf, %d-%d-%d\n",s.name, s.score, s.birthday.year, s.birthday.month, s.birthday.day);     printf("*********************************************\n");      struct Stu *ptr = &s;      //定义指针变量指向结构体变量     printf("%s, %.2lf, %d-%d-%d\n", ptr->name, ptr->score, ptr->birthday.year, ptr->birthday.month, ptr->birthday.day);     return 0; }

1.3 结构体变量的输入输出

        通过成员运算符,找到结构体变量的普通成员后,本质上就是一个普通变量的输入输出

例如:

#include<stdio.h>  //定义生日结构体类型 struct Date {     int year;         //年份     int month;        //月份     int day;          //日期 };  //定义学生类型 struct Stu {     char name[20];       //姓名     double score;        //成绩     struct Date birthday;   //生日 };  /***************主程序**********************/ int main(int argc, const char *argv[]) {     struct Stu s1;        //定义一个结构体变量     printf("请输入学生的姓名:");     scanf("%s", s1.name);     printf("请输入学生的成绩:");     scanf("%lf", &s1.score);     printf("请输入学生的出生年月日(用空格隔开):");     scanf("%d%d%d", &s1.birthday.year, &s1.birthday.month, &s1.birthday.day);     printf("%s, %.2lf, %d-%d-%d\n", s1.name, s1.score, s1.birthday.year, s1.birthday.month, s1.birthday.day);     return 0; } 

1.4 结构体数组

1> 结构体数组本质上也是一个数组,只是每个元素是结构体变量

2> 定义格式:strcut 结构体名 数组名[常量];

例如:

#include<stdio.h> //定义结构体类型 struct Hero {     char name[20];       //姓名     int blood;           //血量     int kill;            //斩获人头数     int die;             //死亡次数     int ass;             //辅助次数 };  //宏定义 #define MAX 10    //主程序 int main(int argc, const char *argv[]) {     //定义一个英雄数组     struct Hero hero[MAX];     int size = 0;            //实际使用的个数      //初始化数组     memset(hero, 0, sizeof(hero));      printf("请输入英雄个数:");     scanf("%d", &size);      //循环输入英雄的相关信息     for(int i=0; i<size; i++)     {         printf("请输入第%d个英雄的名称:", i+1);         scanf("%s", hero[i].name);         printf("请输入第%d个英雄的血量:", i+1);         scanf("%d", &hero[i].blood);         printf("请输入第%d个英雄的人头数:", i+1);         scanf("%d", &hero[i].kill);         printf("请输入第%d个英雄的死亡数:", i+1);         scanf("%d", &hero[i].die);         printf("请输入第%d个英雄的辅助数:", i+1);         scanf("%d", &hero[i].ass);         printf("\n");     }      //输出英雄的信息     printf("本局比赛的结果如下:\n");     printf("英雄\t血量\t人头\t死亡\t辅助\n");     for(int i=0; i<size; i++)     {         printf("%s\t%d\t%d\t%d\t%d\n", hero[i].name, hero[i].blood, hero[i].kill, hero[i].die, hero[i].ass);     }       //求出本局的 mvp     struct Hero mvp;          //存放最有价值的英雄     double mvp_value = 0;        //存放数据     double value;               //存放当前英雄的数据     //先将第一个当做最值     mvp = hero[0];      for(int i=0; i<size; i++)     {         //跟任意一个英雄的数据进行比较         value = hero[i].kill*0.8 - hero[i].die*0.2 + hero[i].ass*0.4;         mvp_value = mvp.kill*0.8 - mvp.die*0.2 + mvp.ass*0.4;         if(mvp_value < value)         {             //退位让新             mvp = hero[i];         }     }     printf("本局的mvp为:%s, %d, %d, %d\n", mvp.name, mvp.kill, mvp.die, mvp.ass);       //按斩获人头数进行降序排序     for(int i=1; i<size; i++)     {         for(int j=0; j<size-i; j++)         {             if(hero[j].kill < hero[j+1].kill)             {                 struct Hero temp = hero[j];                 hero[j] = hero[j+1];                 hero[j+1] = temp;             }         }     }      printf("排序后的结果为:\n");     printf("英雄\t血量\t人头\t死亡\t辅助\n");     for(int i=0; i<size; i++)     {         printf("%s\t%d\t%d\t%d\t%d\n",hero[i].name, hero[i].blood, hero[i].kill, hero[i].die, hero[i].ass);     }        return 0; } 

1.5 结构体的大小

1> 结构体变量所占内存空间的大小,是各个成员所占内存空间之和

2> 要遵循字节对齐原则,有两个

        1、结构体中的每个成员,在分配内存时,要以数据类型对齐一次

        2、所有成员分配内存结束后,整体需要对齐一次:

                32位系统以 min(最大字节的成员,4) 对齐

                64位系统以 min(最大字节的成员,8)对齐

3> 在C语言中一个空的结构体类型,占0字节

#include<stdio.h> //一个空的结构体在内存中占0个字节 struct A { };  //定义结构体类型 struct B {     short value_a;     short value_b;      // 1122 };  //定义结构体类型 struct C {     short value_a;     char value_b;          //1120 };  //定义结构体类型 struct D {     char value_b;     short value_a;      //1022  };   //定义结构体类型 struct E {     char value_a;     int value_b;     short value_c;    // 100022223300  };  //定义结构体类型 struct F {     char value_a;     short value_c;        int value_b;         // 10223333  };  //定义结构体类型 struct G {     char *value_a;     short value_c;        int value_b;         //1111111122003333  }; //定义结构体类型 struct H {     int value_b;             char *value_a;     short value_c;   //111100002222222233000000  };  int main(int argc, const char *argv[]) {     printf("sizeof(struct A) = %ld\n", sizeof(struct A));   //0     printf("sizeof(struct B) = %ld\n", sizeof(struct B));   //4     printf("sizeof(struct C) = %ld\n", sizeof(struct C));   //4     printf("sizeof(struct D) = %ld\n", sizeof(struct D));   //4     struct D d;     printf("&d = %p, &d.value_b = %p, &d.value_a = %p\n", \             &d, &d.value_b, &d.value_a);     printf("sizeof(struct E) = %ld\n", sizeof(struct E));   //12     printf("sizeof(struct F) = %ld\n", sizeof(struct F));   //8     printf("sizeof(struct G) = %ld\n", sizeof(struct G));   //16     printf("sizeof(struct H) = %ld\n", sizeof(struct H));   //24             return 0; }

课外作业:

使用结构体完成学生(学号、姓名、性别、成绩)管理系统

1> 使用菜单实现

2> 功能1:完成对学生信息的录入,确定人数,完成输入

2> 功能2:完成对学生信息的输出

3> 功能3:输出成绩最高和最低学生的信息

4> 功能4:输出学生的总成绩和平均成绩

5> 功能5:对学生信息按成绩进行排序,根据传入的升降序,确定排序功能、

6> 功能6:提示并输入要查找的学生名字,查找该名字是否存在于该班级

7> 功能0:退出

解析:

#include<stdio.h> #include<string.h> #define MAX 20 //定义结构体变量 struct stu{     int id;     char names[MAX];     char sex[10];     int  score; }; //菜单 void print_menu(){         printf("\n学生管理系统\n");         printf("功能1:完成对学生信息的录入,确定人数,完成输入\n");         printf("功能2:完成对学生信息的输出\n");         printf("功能3:输出成绩最高和最低学生的信息\n");         printf("功能4:输出学生的总成绩和平均成绩\n");         printf("功能5:对学生信息按成绩进行排序,根据传入的升降序,确定排序功能\n");         printf("功能6:提示并输入要查找的学生名字,查找该名字是否存在于该班级\n");         printf("功能0:退出\n");         printf("请选择操作(0-6):"); } //定义学生录用信息函数 int enterstu(struct stu stu[],int *count){     printf("请输入学生个数:");     scanf("%d",count);                       //输入学生个数     for (int i = 0; i < *count; i++)            // 循环遍历输入各个学生信息     {         printf("输入学生 %d 的姓名:", i + 1);         scanf("%s",stu[i].names);         printf("输入学生 %d 的学号:", i + 1);         scanf("%d",&stu[i].id);          printf("输入学生 %d 的性别:", i + 1);         scanf("%s",stu[i].sex);          printf("输入学生 %d 的成绩:", i + 1);         scanf("%d",&stu[i].score);     } } //打印学生信息函数 void print_stu(struct stu stu[],int count){     printf("姓名\t学号\t性别\t成绩\n");     for (int i = 0; i < count; i++)           // 循环遍历学生信息,打印出来     {         printf("%s\t%d\t%s\t%d\n",stu[i].names,stu[i].id,stu[i].sex,stu[i].score);     } } //求出学生成绩最大最小值函数 void maxminstu(struct stu stu[],int count){     int maxscore=0;             //定义初始值     int minscore=0;              //定义初始值     for (int i = 0; i < count; i++)               {         //判断最大值        if(stu[i].score >stu[maxscore].score)            {                                                               maxscore = i;        }        //判断最小值        if(stu[i].score <stu[minscore].score){            minscore = i;        }     }     //打印输出成绩最大最小值的信息     printf("最高成绩的名字为%s,学号为%d,性别为%s,成绩为%d\n",stu[maxscore].names,stu[maxscore].id,stu[maxscore].sex,stu[maxscore].score);     printf("最低成绩的名字为%s,学号为%d,性别为%s,成绩为%d\n",stu[minscore].names,stu[minscore].id,stu[minscore].sex,stu[minscore].score); } //统计总成绩和平均成绩函数 void sumavestu(struct stu stu[],int count){     float sum=0;     float ave=0;     for (int i = 0; i < count; i++)     {        sum += stu[i].score;                 //累加     }      ave = sum/count;                        //求平均值      printf("学生的总成绩为%.2f,平均成绩为%.2f\n",sum,ave); } //排序函数 void sortstu(struct stu stu[],int count,int flag){	 	if( flag == 1){                              //flag==1;则为升序 		for(int i = 1; i < count; i++){             //交换三部曲 			for(int j = 0; j < count-i; j++){ 				if(stu[j].score < stu[j+1].score){ 					struct stu temp = stu[j]; 					stu[j] = stu[j+1]; 					stu[j+1] = temp; 				} 			} 		} 	}else if(flag == 0 ){             //flag==0;则为降序 		for(int i = 1; i < count; i++){                  //交换三部曲 			for(int j = 0; j < count-i; j++){ 				if(stu[j].score > stu[j+1].score){ 					struct stu temp = stu[j]; 					stu[j] = stu[j+1]; 					stu[j+1] = temp; 				} 			} 		}     }     printf("\n");     print_stu(stu,count);                   //调用打印函数输出结果     printf("\n"); } //查找学生姓名函数 int seachstu(struct stu stu[],int count,char *seach){          for (int i = 0; i < count; i++)     {         if (strcmp(stu[i].names,seach) ==0){                 //判断查找值与输入值是否相当             return 1;                                                               //相等返回1         }     }     return 0;              //否则为0 } int main(int argc, char const *argv[]) {     int menu=0;            struct stu student[MAX];           //定义学生结构体数组     int stucount=0;     while (1)     {         //提示用户输入功能     print_menu();     scanf("%d",&menu);     switch (menu)     {     case 1:     enterstu(student,&stucount);         break;     case 2:     print_stu(student, stucount);     break;     case 3:     maxminstu(student,stucount);     break;     case 4:     sumavestu(student,stucount);     break;     case 5:{     int flag=0;     //提示用户用升序还是降序     printf("请输入你要查询升序还是降序(升序输入1,降序输入0):");     scanf("%d",&flag);     sortstu(student,stucount,flag);}     break;     case 6:{         // 提示用户输入要查找的学生姓名         char seach[MAX]="";         printf("请输入你要查找的学生姓名:");         scanf("%s",&seach);     if(seachstu(student,stucount,seach)){         printf("%s该名字存在在班级中\n",seach);     }else     {        printf("%s该名字不存在在班级中\n",seach);     }     }     break;     case 0: goto END;     default:printf("您输入的功能有误,请重新输入\n");     }     }     END:     return 0; }  

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!