C的实用笔记38——结构体的引入和定义

1.为什么要用结构体?

0、原因:实际开发中,我们需要将不同类型的数据组合成一个整体,这就是结构体。结构体是自创的类型。

1、查找一名学生信息的两种方案:在EXCEL表格和数据库中经常有这种情况,比方说一个学生的信息可能包括:学号、姓名、性别、年龄、成绩、地址等。现在我们有两种方案来查找任意一名学生的信息,如图:

                                      

  1.  方案一:以行为一个整体(结构体),不用看其他行就能读取一个学生的所有信息。
  2. 方案二:以列为一个整体(数组),需要先按列查找(比方说先找学生学号),然后记住行号,需要看所有列才能读取一个学生的所有信息。

2.结构体变量的四要素

与普通变量的四要素完全相同。

1、结构体变量的类型:也就是结构体,它是我们自创的类型,简称构造类型。它的声明通常不放在函数中,书写的方式就像全局变量,因为它要尽可能让程序中的所有位置都能使用这个类型声明。结构体又有三部分:

  1. struct关键字:表示构造的是结构体。
  2. 结构体类型名:编程习惯是用大写开头,小写开头虽然不出错,就是看起来太low了。
  3. 结构体成员列表:成员列表也称为域表,通常我们称结构体成员列表(域表)中的每个成员为成员变量(域),成员变量之间用分号隔开。你可以定义许多成员变量,但并不是每一个选项在具体使用中会被派上用场,不要给成员变量赋值,虽然不出错,但是看起来太low了。成员列表中的成员变量可以是我们之前学过的任何类型的变量,比如整型、字符型、字符数组、各类指针、浮点型。甚至可以是结构体类型的成员变量。当然,成员列表中的变量可以是同一类型的,这时结构体看起来就像数组一样。
    struct Student				//struct是关键字,Student是自己取的结构体类型名
    {							//花括号中的是结构体成员列表
        int num;
        char name[32];
        char sex;
        int age;
        double score;
        char addr[50];
    };							//从此以后,我们构造了一个结构体,它是 struct Student 类型。

1、结构体的知识点:

  1. 结构体声明时,末尾加分号;
  2. 结构体这个构造类型,决定了结构体变量占用空间的大小,系统会在程序运行或编译阶段给你静态分配好内存。这个类型占用多少内存当然需要用sizeof来测一下,留在第2小节(结构体内存分配)中讲。
  3. 与int a; 中 类型名是int一个道理,这里struct Student 在概念上就相当于 int。

2、结构体变量的名字:是结构体变量定义时候的名字,与 int a; 中变量名是a一个道理,留在本节第3部分讲

3、结构体变量的地址:显然这就是指向结构体变量的指针,留在第4小节(结构体指针)中讲

4、结构体变量的值:这里指的是结构体变量中成员变量的值,留在本节第4、5、6部分讲

3.结构体变量的定义

1、标准的定义方式:结构体声明和结构体变量定义分开写。

  1. 由于结构体是自定义的构造类型,所以需要先声明结构体,然后拿它来定义结构体变量。
    #include <stdio.h>
    struct Student
    {
        int num;
        char name[32];
        char sex;
        int age;
        double score;
        char addr[50];
    };
    int main(int argc, char const *argv[])
    {
        struct Student stu1;		//stu1就是struct Student类型的结构体变量
    }

2、见怪不怪的定义方式:

  1. 声明结构体,同时定义结构体变量:后面照样可以定义其他结构体变量,但这个方法尽量少用
    #include <stdio.h>
    struct Student
    {
        int num;
        char name[32];
        char sex;
        int age;
        double score;
        char addr[50];
    } stu2, stu3;					//尽量少用
    int main(int argc, char const *argv[])
    {
        struct Student stu1;	
    }

  2. 声明结构体时不写类型名,必须同时定义结构体变量:少用,因为后面无法再拿它来定义其他结构体变量
    #include <stdio.h>
    struct					//不写结构体类型名
    {
        int num;
        char name[32];
        char sex;
        int age;
        double score;
        char addr[50];
    } stu2, stu3;			//同时在这里定义结构体变量,不要使用这种方法

4.结构体变量中有许多成员变量,如何引用?

数组引用数组元素的方式有:数组下标法、数组名偏移后取星花。但是这些明显都不适用于结构体。

1、用点运算符来访问结构体变量中的成员变量(域):

  1. 单级引用(成员列表中没有构造类型变量):结构体变量名.成员变量名
    #include <stdio.h>
    #include <string.h>
    struct Student
    {
        int num;
        char name[32];
        char sex;
        int age;
        double score;
        char addr[50];
    };
    int main(int argc, char const *argv[])
    {
        struct Student stu1; 
        stu1.num = 64031; 					//点运算符访问结构体变量中的成员变量
        strcpy(stu1.name, "Li Hua");
        stu1.sex = 'M'; 
        stu1.age = 24;
        stu1.score = 94;
        strcpy(stu1.addr, "杭州");
        printf("学号:%d,名字:%s,性别:%c,年龄:%d,分数:%lf,地址:%s\n", \
                stu1.num, stu1.name, stu1.sex, stu1.age, stu1.score, stu1.addr);
        return 0;
    }

  2. 二级引用(成员列表中有结构体变量):结构体变量名.成员变量名.成员变量名
    #include <stdio.h>
    #include <string.h>
    struct Day
    {
        int year;
        int month;
        int day;
    };
    struct Student
    {
        int num;
        char name[32];
        char sex;
        int age;
        double score;
        char addr[50];
        struct Day birth;					//结构体的成员列表中还有结构体变量
    };
    int main(int argc, char const *argv[])
    {
        struct Student stu1; 
        stu1.num = 64031; 
        strcpy(stu1.name, "Li Hua");
        stu1.sex = 'M'; 
        stu1.age = 24;
        stu1.score = 94;
        strcpy(stu1.addr, "杭州");
        stu1.birth.year = 1999;				//点运算符二级引用
        stu1.birth.month = 12;
        stu1.birth.day = 1;
        printf("学号:%d,名字:%s,性别:%c,年龄:%d,分数:%lf,地址:%s,生日:%d年%d月%d日\n", \
                stu1.num, stu1.name, stu1.sex, stu1.age, stu1.score, stu1.addr, \
                stu1.birth.year, stu1.birth.month, stu1.birth.day);
        return 0;
    }

5.结构体变量的初始化

        结构体变量的初始化和数组的初始化方法几乎一模一样,也分为全部初始化和部分初始化,都是用花括号来实现。

1、全部初始化:定义结构体变量时用花括号赋值,花括号内的数据与结构体成员列表一一对应,数据用逗号分隔。

#include <stdio.h>
//#include <string.h>			由于是初始化,就不需要用strcpy修改字符串
struct Student
{
    int num;
    char name[32];
    char sex;
    int age;
    double score;
    char addr[50];
};
int main(int argc, char const *argv[])
{
    struct Student stu2 = {64066,"Li Fang",'M',24,90,"大连"};            //结构体变量的全部初始化
    printf("学号:%d,名字:%s,性别:%c,年龄:%d,分数:%lf,地址:%s", \
            stu2.num, stu2.name, stu2.sex, stu2.age, stu2.score, stu2.addr);
    return 0;
}

2、部分初始化:只能按照顺序给结构体变量的前几个成员变量初始化,不允许用空格跳过中间某个变量

#include <stdio.h>
//#include <string.h>			由于是初始化,就不需要用strcpy修改字符串
struct Student
{
    int num;
    char name[32];
    char sex;
    int age;
    double score;
    char addr[50];
};
int main(int argc, char const *argv[])
{
    struct Student stu2 = {64066,"Li Fang",'M',24,};               		//结构体变量的部分初始化
    printf("学号:%d,名字:%s,性别:%c,年龄:%d,分数:%lf,地址:%s", \
            stu2.num, stu2.name, stu2.sex, stu2.age, stu2.score, stu2.addr);
    return 0;
}

6.4和5中哪一种方法确定结构体变量的值比较好?

1、需要分情况:看起来好像定义结构体变量时就初始化比较简单,但是要分情况,因为有的时候一开始没法确定结构体变量中成员变量的值,就是需要通过点运算符来进行访问。

7.结构体变量相互赋值的条件

1、知识点:总的来说就是结构体相同,也就是结构体变量的类型相同

  1. 结构体类型名一致
  2. 结构体成员列表一致

8.习题

习题1:输入两个学生的信息,找出成绩好的学生,并显示他的信息。

  1. 思路:
    构造一个与学生信息有关的结构体类型1: struct Student{......};
    1. 用构造体类型1,定义两个结构体变量stu1和stu2,初始化或者通过点运算符确认结构体变量的值
    2. 定义一个与stu1和stu2相同类型的结构体变量max,它表示成绩好的同学,暂时认为stu1成绩好: 
    	struct Student max = stu1;
    3. 判断,stu1.score是否小于stu2.score,
    	3.1 如果是,
        		那么,认为stu2是成绩好的同学: max = stu2;
    4. 打印max同学的信息

  2. 代码:
    #include <stdio.h>
    #include <string.h>
    struct Student
    {
        int num;
        char name[32];
        char sex;
        int age;
        double score;
        char addr[50];
    };
    int main(int argc, char const *argv[])
    {
        struct Student stu1; 
        struct Student stu2 = {64066,"Li Fang",'M',24,90,"大连"};
        struct Student max;
        stu1.num = 64031; 
        strcpy(stu1.name, "Li Hua");
        stu1.sex = 'M'; 
        stu1.age = 24;
        printf("请输入%s的成绩:\n", stu1.name);
        scanf("%lf", &stu1.score);
        strcpy(stu1.addr, "杭州");
        max = stu1;
        if(stu1.score < stu2.score){
            max = stu2;
        }
        printf("成绩比较好的是:\n");
        printf("学号:%d,名字:%s,年龄:%d,分数:%lf,地址:%s\n", \
                max.num, max.name, max.age, max.score, max.addr);
        return 0;
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值