Bootstrap

第八章结构体

1、结构体引入-定义结构体和使用结构体

      1. 为什么要用结构体
      2. 整型数,浮点型数,字符串是分散的数据表示
        有时候我们需要用很多类型的数据来表示一个整体,比如学生信息
      3. 类比与数组:数组是元素类型一样的数据集合
        如果是元素类型不同的数据集合,就要用到结构体了

        1. 定义一个结构体
    1. 它算是一个模板,一般不给赋具体的值,每一项在实际应用中并不是都要使用

       

让我逐行解释这段代码:

  1. #include <stdio.h>:这是一个预处理命令,意思是在编译之前包含标准输入输出头文件stdio.h,该头文件中包含了许多与输入和输出相关的函数声明和宏定义。

  2. #include <string.h>:这也是一个预处理命令,意思是在编译之前包含字符串操作相关的头文件string.h,该头文件中包含了许多与字符串操作相关的函数声明和宏定义。

  3. struct Student:这是定义一个名为Student的结构体类型。

  4. 在接下来的行中,定义了结构体Student的成员变量,包括num(学号,int类型)、name(名字,字符数组类型)、sex(性别,字符类型)、age(年龄,int类型)、score(分数,double类型)和addr(地址,字符数组类型)。

  5. int main():这是定义一个主函数,程序从这里开始执行。

  6. int a;:定义了一个变量a,类型为int

  7. struct Student stu1;struct Student stu2;:定义了两个Student类型的结构体变量stu1stu2

  8. a = 10;:将变量a赋值为10

  9. stu1.num = 1;:使用点运算符将1赋值给stu1结构体变量的num成员变量。

  10. stu1.age = 18;:将18赋值给stu1结构体变量的age成员变量。

  11. stu1.score = 99.9;:将99.9赋值给stu1结构体变量的score成员变量。

  12. strcpy(stu1.name, "lili");:使用strcpy函数将字符串"zhonglibo"复制到stu1结构体变量的name成员变量中。

  13. strcpy(stu1.addr, "深圳");:使用strcpy函数将字符串"深圳"复制到stu1结构体变量的addr成员变量中。

  14. printf("学号:%d,年龄:%d,分数:%lf,名字:%s,地址:%s\n", stu1.num, stu1.age, stu1.score, stu1.name, stu1.addr);:使用printf函数按照指定的格式输出stu1结构体变量的各个成员变量的值。

  15. return 0;:主函数执行完毕,返回值0表示程序正常结束。

#include <stdio.h>
#include <string.h>
struct Student
{
    int num;
    char name[32];
    char sex;
    int age;
    double score;
    char addr[32];
};
int main()
{
    int a;
    struct Student stu1;
    struct Student stu2;

    a = 10;
    stu1.num = 1;//点运算符来访问结构体中的成员变量(域)
    stu1.age = 18;
    stu1.score = 99.9;
    strcpy(stu1.name,"lili");
    strcpy(stu1.addr,"深圳");

    printf("学号:%d,年龄:%d,分数:%lf,名字:%s,地址:%s\n",
           stu1.num,stu1.age,stu1.score,stu1.name,stu1.addr);
    return 0;
}

1、1小应用比较大小成绩 

#include <stdio.h>
#include <string.h>

//定义一个结构体学生数据类型
struct Student//名称大写
{
    int num;//学号
    char name[32];//名字
    char sex;//性别
    int age;//年龄
    double score;//分数
    char addr[32];//地址
};
int main()
{
    int a;//通常的int 型 变量
    struct Student stu1;//结构体型命名结构体变量
    struct Student stu2 = {2,"莉莉",'g',19,99,"广州"};//定义一个结构体命名并且赋值
    struct Student max;//定义一个类型max

    a = 10;
    
    stu1.num = 1;//点运算符来访问结构体中的成员变量(域)
    stu1.age = 18;//点运算符赋值年龄18
    stu1.score = 99.9;//点运算符赋值分数99.9
    strcpy(stu1.name,"小李");//strcpy拷贝函数赋值stu1,name名字
    strcpy(stu1.addr,"深圳");//strcpy拷贝函数赋值stu1,addr地址名字
    max = stu1;//max=stu1,下面max = stu2;//先让max = stu1

    //输出
    printf("学号:%d,年龄:%d,分数:%.1f,名字:%s,地址:%s\n",
           stu1.num,stu1.age,stu1.score,stu1.name,stu1.addr);
    printf("学号:%d,年龄:%d,分数:%.1f,名字:%s,地址:%s\n",
           stu2.num,stu2.age,stu2.score,stu2.name,stu2.addr);
    if(stu1.score < stu2.score){
        max = stu2;//必须是 = stu2;否则无法判断大小
    }else {
        printf("成绩好的是:\n");
        printf("学号:%d,年龄:%d,分数:%.1f,名字:%s,地址:%s\n",
           max.num,max.age,max.score,max.name,max.addr);
    }
    
    return 0;
}

 

1、2提示输入方式

#include <stdio.h>
#include <string.h>

// 定义一个结构体学生数据类型
struct Student
{
    int num;             // 学号
    char name[32];       // 名字
    char sex;            // 性别
    int age;             // 年龄
    double score;        // 分数
    char addr[32];       // 地址
};

int main()
{
    int a;                                           // 通常的int型变量
    struct Student stu1;                             // 结构体类型命名结构体变量
    struct Student stu2 = {2, "莉莉", 'g', 19, 99, "广州"};  // 定义一个结构体命名并且赋值
    struct Student max;                              // 定义一个max结构体变量

    a = 10;

    printf("请输入学号:");
    scanf("%d", &stu1.num);
    printf("请输入年龄:");
    scanf("%d", &stu1.age);
    printf("请输入分数:");
    scanf("%lf", &stu1.score);
    printf("请输入名字:");
    scanf("%s", stu1.name);
    printf("请输入地址:");
    scanf("%s", stu1.addr);

    max = stu1;                                     // 先让max = stu1

    // 输出
    printf("学号:%d,年龄:%d,分数:%.1f,名字:%s,地址:%s\n",
           stu1.num, stu1.age, stu1.score, stu1.name, stu1.addr);
    printf("学号:%d,年龄:%d,分数:%.1f,名字:%s,地址:%s\n",
           stu2.num, stu2.age, stu2.score, stu2.name, stu2.addr);

    if (stu1.score < stu2.score)
    {
        max = stu2;
    }
    else
    {
        printf("成绩好的是:\n");
        printf("学号:%d,年龄:%d,分数:%.1f,名字:%s,地址:%s\n",
               max.num, max.age, max.score, max.name, max.addr);
    }

    return 0;
}

2、结构体和数组的结合

  • 这段代码定义了一个名为Student的结构体,包含了学号(num)、姓名(name)、性别(sex)、年龄(age)、分数(score)和地址(addr)等成员变量。
  • 定义了一个名为arr的整型数组,长度为3,并初始化为{1, 2, 3};定义了整型变量ilen
  • 定义了一个名为arr2的结构体数组,长度为3,并初始化了每个数组元素的各个成员变量的值。
  • 计算arr2数组的长度,即数组元素的个数。sizeof(arr2)表示整个数组所占的字节数,sizeof(arr2[0])表示数组中第一个元素所占的字节数,通过相除得到数组长度。
  • 使用for循环遍历arr2数组的每个结构体元素,然后使用printf函数打印每个结构体的成员变量值。
#include <stdio.h>
#include <string.h>

struct Student
{
    int num;
    char name[32];
    char sex;
    int age;
    double score;
    char addr[32];
};


int main()
{
	int arr[3] = {1,2,3};
	int i;
	int len;
	
	struct Student arr2[3] = {
		
		{2,"张三",'g',17,99.5,"北京"},
		{3,"李四",'M',18,89.2,"上海"},
		{4,"王五",'f',19,100,"内蒙"}
	};
	len = sizeof(arr2)/sizeof(arr2[0]);
	
	for(i = 0;i< len;i++){
		printf("学号:%d,年龄:%d, 分数:%lf, 名字:%s, 地址:%s\n",
			arr2[i].num,arr2[i].age,arr2[i].score,arr2[i].name,arr2[i].addr);
	}
	
	return 0;
}

 3、结构体数组应用之选票系统


//
#include <stdio.h>
#include <string.h>

struct XuanMin
{
    char name[32];
    int tickets;
};

int main()
{
    struct XuanMin xm[3];
    struct XuanMin max;

    int i;
    int len;
    int j;
    int total = 5;
    char tmpName[32];
    int mark;
    int feipiao = 0;//初始化为零

    //初始化选民信息
    len = sizeof (xm)/sizeof (xm[0]);
    for(i = 0; i < len; i++){
        xm[i].tickets = 0;
        printf("请输入第%d个选民的名字:\n",i+1);
        scanf("%s",xm[i].name);
    }
    //唱票环节
    for(i = 0; i < 5; i++){

        mark = 0;
        printf("请输入你投给谁:\n");
        memset(tmpName,'\0',sizeof (tmpName));//每次清空一下
        scanf("%s",tmpName);//输入选中的选民名字,像拆开一个选票,看到名字一样
        for(j = 0; j < len;j++){//拿到名字,对应候选人票数加1
            if(strcmp(tmpName,xm[j].name) == 0){
                xm[j].tickets++;
                mark = 1;
            }
        }
        if(mark == 0) {
            printf("没有此候选人,放弃\n");
            feipiao++;
        }
    }
    //公布结果
    for(i = 0; i < len; i++){
        printf("名字:%s,票数:%d\n",xm[i].name,xm[i].tickets);
    }
    max = xm[0];
    for (i = 1; i < len; i++)
        if (max.tickets < xm[i].tickets){
            max = xm[i];
        }

    printf("%s以%d票当选!!!废票数:%u\n", max.name, max.tickets, feipiao);
    return 0;
}

 4、结构体指针变量引入-通过结构体指针来访问结构体内容

#include <stdio.h>

struct Test
{
    int idata;
    char cdata;
};
int main()
{
    int a;
    int *p = &a;//普通整数

    char c;
    char *pc = &c;//普通字符

    struct Test t1 = {10,'c'};//1.类型 2.名字 3.值 4.地址
    struct Test *ps = &t1;

    printf("t1的idata = %d\n",t1.idata);//变量名访问,用点运算符
    printf("t1的idata = %d\n",ps->idata);//变量名访问,用“->”运算符

    ps->cdata = 'R';
    printf("t1的cdata = %c\n",t1.cdata);//变量名访问,用点运算符
    printf("t1的cdata = %c\n",ps->cdata);//变量名访问,用“->”运算符
    return 0;
}

 

5、 结构体指针应用01

#include <stdio.h>
#include <string.h>

struct Student
{
    int num;
    char name[32];
    char sex;
    int age;
    double score;
    char addr[32];
};


int main()
{
	int arr[3] = {1,2,3};
	int i;
	int len;
	
	struct Student arr2[3] = {
		
		{2,"张三",'g',17,99.5,"北京"},
		{3,"李四",'M',18,89.2,"上海"},
		{4,"王五",'f',19,100,"内蒙"}
	};
    struct Student *p;
    p = arr2;

	len = sizeof(arr2)/sizeof(arr2[0]);
	
	for(i = 0;i < len; i++){
		printf("学号:%d,年龄:%d, 分数:%lf, 名字:%s, 地址:%s\n",
			p->num,p->age,p->score,p->name,p->addr);
            p++;//记得++否则无法访问全部信息
	}
	
	return 0;
}

6、 结构体指针应用02之改写选票系统

  • 这部分是引入头文件和定义结构体。头文件 <stdio.h>包含了输入输出函数的声明,而头文件 <string.h>包含了字符串处理函数的声明。struct XuanMin定义了一个结构体,其中包含了名字和票数两个成员。
  • 这部分是 main() 函数的开头,声明了一系列变量,包括结构体数组 xm 用于存储选民的信息,结构体变量 max 用于存储得票最多的选民,结构体指针 p 用于遍历数组,其他变量用于循环计数、临时存储名字和计算废票数。
  • 这部分是初始化选民信息的代码。通过循环遍历 xm 数组,将每个选民的票数设置为0,并提示用户输入每个选民的名字。
  • 这部分是投票环节的代码。通过循环进行5次投票,提示用户输入投票给谁,并通过循环遍历 xm 数组,将对应名字的选民票数加1。如果输入的名字没有对应的候选人,则打印提示信息,并增加废票数。
  • 这部分是公布选民信息的代码。通过循环遍历 xm 数组,打印每个选民的名字和票数。
  • 这部分是找到得票最多的选民并公布结果的代码。通过循环遍历 xm 数组,将得票最多的选民保存在结构体变量 max 中。然后输出得票最多的选民的名字、票数和废票数。最后返回 0 表示程序正常结束。
#include <stdio.h>
#include <string.h>

struct XuanMin
{
    char name[32];
    int tickets;
};
/*
	1.把以前的普通变量名,或者下标访问的.运算符,改成结构体指针的->
	2.指针++,每次遍历会到数组尾巴,下次遍历之前记得回来(重新指数组头)
*/
int main()
{
    struct XuanMin xm[3];
    struct XuanMin max;
	struct XuanMin *p = xm;

    int i;
    int len;
    int j;
    int total = 5;
    char tmpName[32];
    int mark;
    int feipiao = 0;//初始化为零

    //初始化选民信息
    len = sizeof (xm)/sizeof (xm[0]);
    for(i = 0; i < len; i++){
        p->tickets = 0;
        printf("请输入第%d个选民的名字:\n",i+1);
        scanf("%s",p->name);
		p++;
    }//指针++,每次遍历会到数组尾巴,下次遍历之前记得回来(重新指数组头)
	p = xm;
    //唱票环节
    for(i = 0; i < 5; i++){

        mark = 0;
        printf("请输入你投给谁:\n");
        memset(tmpName,'\0',sizeof (tmpName));//每次清空一下
        scanf("%s",tmpName);//输入选中的选民名字,像拆开一个选票,看到名字一样
		p = xm;//指针++,每次遍历会到数组尾巴,下次遍历之前记得回来(重新指数组头)
        for(j = 0; j < len;j++){//拿到名字,对应候选人票数加1
            if(strcmp(tmpName,p->name) == 0){
               p->tickets++;
                mark = 1;
            }
			p++;
        }
        if(mark == 0) {
            printf("没有此候选人,放弃\n");
            feipiao++;
        }
    }
	p = xm;//指针++,每次遍历会到数组尾巴,下次遍历之前记得回来(重新指数组头)
    //公布结果
    for(i = 0; i < len; i++){
        printf("名字:%s,票数:%d\n",p->name,p->tickets);
    }
    max = xm[0];
    for (i = 1; i < len; i++)
        if (max.tickets < p->tickets){
            max = xm[i];
        }
		p++;
    printf("%s以%d票当选!!!废票数:%u\n", p->name,p->tickets, feipiao);
    return 0;
}

7、结构体指针数组函数综合应用改写选票系统

  • 这段代码是一个简单的投票程序,用于进行选民的投票、计票和最终当选者的选举。
  • 代码中包含了以下头文件:
  •  
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>

  • 代码定义了一个结构体`XuanMin`,用于表示选民的信息。结构体包含两个成员变量,分别为选民的名字`name`(长度为32的字符数组)和选民的票数`tickets`(整数)。
  • struct XuanMin
    {
        char name[32];
        int tickets;
    };
  • 代码实现了以下几个函数:
  • - `initXms`:初始化选民信息。该函数接受一个指向`XuanMin`结构体的指针`p`和一个指向整数的指针`pn`,表示选民数量。在函数中,首先判断`p`是否为空指针,如果为空,则要求用户输入选民数量,并分配足够的内存空间存储选民信息。然后通过循环获取每个选民的名字,并将其存储在结构体中。最后,返回指向初始化后的选民信息的指针。
  • - `printXms`:打印选民信息。该函数接受一个指向`XuanMin`结构体的指针`p`和选民数量`len`作为参数。函数通过循环打印每个选民的名字和票数信息。
  • - `doVot`:进行投票。该函数接受一个指向`XuanMin`结构体的指针`p`和选民数量`len`作为参数。函数通过循环进行5次投票,要求用户输入投票给谁,然后遍历选民信息,找到对应的候选人并将票数增加1。如果找不到对应的候选人,则认为是废票,并将废票数加1。最后,返回废票数。
  • - `getMax`:找到得票最多的候选人。该函数接受一个指向`XuanMin`结构体的指针`p`和选民数量`len`作为参数。函数定义了一个指向`XuanMin`结构体的指针`max`,并将其初始化为指向选民信息中的第一个元素。然后通过循环遍历选民信息,比较每个选民的票数与`max`的票数,如果大于`max`的票数,则更新`max`为当前选民。最后,返回得票最多的候选人的指针。
  • 最后,在`main`函数中,定义了一个指向`XuanMin`结构体的指针`xm`和一个指向`XuanMin`结构体的指针`final`,以及一个整型变量`total`。然后,通过调用`initXms`函数初始化选民信息,并通过调用`printXms`函数打印选民信息。接下来,调用`doVot`函数进行投票,并输出废票数。然后,再次调用`printXms`函数打印选民信息。最后,调用`getMax`函数找到得票最多的候选人,并输出其名字、票数和废票数。最后,返回0表示程序正常结束。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct XuanMin
{
    char name[32];
    int tickets;
};

struct XuanMin* initXms(struct XuanMin *p,int *pn)
{

    int i;
    if(p == NULL){
        printf("请输入有几个人参选:\n");
        scanf("%d",pn);
        p = (struct XuanMin*)malloc(*pn*sizeof(struct XuanMin));
    }

    for(i=0;i<*pn;i++){
        p->tickets = 0;
        printf("请输入第%d个选民的名字:\n",i+1);
        scanf("%s",p->name);
        p++;
    }
    return p-*pn;
}

void printXms(struct XuanMin *p,int len)
{
    int i;
    for(i=0;i<len;i++){
        printf("名字:%s,票数:%d\n",p->name,p->tickets);
        p++;
    }
}

int doVot(struct XuanMin *p, int len)
{
    int i;
    int j;
    int feiPiao = 0;
    int mark;
    char tmpName[32];
    struct XuanMin *pbak = p;

    for(i=0;i<5;i++){

        mark = 0;
        printf("请输入你投给谁:\n");
        memset(tmpName,'\0',sizeof(tmpName)); //每次清空一下
        scanf("%s",tmpName);//输入选中的选民名字,像拆开一个选票,看到名字一样
        p = pbak;
        for(j = 0;j<len; j++){ //拿到名字,对应候选人票数加1
            if(strcmp(tmpName, p->name) == 0){
                p->tickets++;
                mark  = 1;
            }
            p++;
        }
        if(mark == 0){
            printf("没有此候选人,放弃\n");
            feiPiao++;
        }

    }

    return feiPiao;
}

struct XuanMin* getMax(struct XuanMin *p, int len)
{
    struct XuanMin* max;
    int i;

    max = p;

    for(i=0;i<len;i++){
        if(max->tickets < p->tickets){
            max = p;
        }
        p++;
    }

    return max;
}

int main()
{
    struct XuanMin *xm = NULL;
    struct XuanMin *final;
    int total = 0;
    xm = initXms(xm,&total);
    printXms(xm,total);

    int feip = doVot(xm,total);
    printf("废票数是:%d\n",feip);
    printXms(xm,total);

    final = getMax(xm,total);
    printf("%s以%d票当选!!废票是%d\n",final->name,final->tickets,feip);
    return 0;
}

 8、结构体二级指针

  •  这段代码是一个简单的投票系统。它使用了结构体`XuanMin`来表示候选人,包括候选人的名字和得票数。
  • 函数`initXms`用于初始化候选人数组。它接受一个指向`XuanMin`结构体指针的指针`p`和一个整型指针`pn`作为参数。首先判断传入的指针`p`是否为空,若为空,则通过输入要选择的候选人数量,使用`malloc`动态分配足够的内存空间来存储候选人数组。然后,通过循环输入每个选民的名字,并将票数初始化为0。最后,返回指向候选人数组的指针。
  • 函数`printXms`用于打印候选人数组中每个候选人的名字和得票数。它接受一个指向`XuanMin`结构体指针的指针`p`和长度`len`作为参数。通过循环遍历候选人数组,逐个打印每个候选人的名字和得票数。
  • 函数`doVot`用于进行投票。它接受一个指向`XuanMin`结构体指针的指针`p`和长度`len`作为参数。函数会循环进行5次投票,要求输入投票给哪个候选人。然后,通过遍历候选人数组来匹配输入的名字,并将匹配到的候选人的票数加1。如果没有匹配到候选人,则输出"没有此候选人,放弃"并增加废票数。
  • 函数`getMax`用于找到得票数最高的候选人。它接受一个指向`XuanMin`结构体指针的指针`p`和长度`len`作为参数。函数会通过比较候选人数组中的得票数,找到得票数最高的候选人,并返回指向该候选人结构体的指针。
  • 在`main`函数中,首先声明了指向`XuanMin`结构体的指针`xm`和`final`,并将其初始化为NULL。然后,声明了一个整型变量`total`,用于存储候选人的总数。
  • 调用`initXms`函数初始化候选人数组,并通过传递指向`xm`和`total`的指针来获取指向候选人数组的指针。
  • 接着调用`printXms`函数打印候选人的信息。
  • 调用`doVot`函数进行投票,并将废票数保存在整型变量`feip`中。
  • 再次调用`printXms`函数打印更新后的候选人信息。
  • 最后,调用`getMax`函数找到得票最高的候选人,并将结果保存在指针`final`中。然后,输出得票最高的候选人的名字、得票数以及废票数。
  • 整个代码实现了一个简单的投票系统,可以帮助统计候选人的得票情况并输出最高得票的候选人信息。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct XuanMin
{
	char name[32];
	int tickets;
};

void initXms(struct XuanMin **pxm,int *pt)
{
	int i;
	
	//*pt = 0;
	//*pxm = NULL;
	if(*pxm == NULL){
		printf("请输入有几个人参选:\n");
		scanf("%d",pt);
		printf("一共%d个人参选\n",*pt);
		*pxm = (struct XuanMin*)malloc(*pt * sizeof(struct XuanMin));
	}
	for(i=0;i<*pt;i++){
		(*pxm)->tickets == 0;
		printf("请输入第%d个选民的名字:\n",i+1);
		scanf("%s",(*pxm)->name);
		(*pxm)++;
	}
	*pxm = *pxm - *pt;
}

void printXms(struct XuanMin *p,int len)
{
	int i;
	for(i=0;i<len;i++){
		printf("名字:%s,票数:%d\n",p->name,p->tickets);
		p++;
	}
}

int doVot(struct XuanMin *p, int len)
{
	int i;
	int j;
	int feiPiao = 0;
	int mark;
	char tmpName[32];
	struct XuanMin *pbak = p;
	
	for(i=0;i<5;i++){
		
		mark = 0;
		printf("请输入你投给谁:\n");
		memset(tmpName,'\0',sizeof(tmpName)); //每次清空一下
		scanf("%s",tmpName);//输入选中的选民名字,像拆开一个选票,看到名字一样
		p = pbak;
		for(j = 0;j<len; j++){ //拿到名字,对应候选人票数加1
			if(strcmp(tmpName, p->name) == 0){
				p->tickets++;
				mark  = 1;	
			}
			p++;
		}
		if(mark == 0){
			printf("没有此候选人,放弃\n");
			feiPiao++;
		}
		
	}
	
	return feiPiao;
}

struct XuanMin* getMax(struct XuanMin *p, int len)
{
	struct XuanMin* max;
	int i;
	
	max = p;
	
	for(i=0;i<len;i++){
		if(max->tickets < p->tickets){
			max = p;
		}
		p++;
	}
	
	return max;
}

int main()
{
	struct XuanMin *xm = NULL;
	struct XuanMin *final;
	int total = 0;
	
	initXms(&xm,&total);
	printXms(xm,total);
	
	int feip = doVot(xm,total);
	printf("废票数是:%d\n",feip);
	printXms(xm,total);
	
	final = getMax(xm,total);
	printf("%s以%d票当选!!废票是%d\n",final->name,final->tickets,feip);
	return 0;
}

9、联合体共用体概念引入

  • 这段代码演示了结构体(struct)和联合体(union)在C语言中的用法。
  • 首先定义了一个名为TesT的结构体,结构体中包含一个整型变量idata、一个字符型变量cdata和一个双精度浮点型变量ddata。
  • 接着定义了一个名为TestU的联合体,联合体中包含一个整型变量idata、一个字符型变量cdata和一个双精度浮点型变量ddata。联合体的特点是共用一块内存空间,不同成员变量共享该内存空间,因此只能同时存储一个成员的值。
  • 在main函数中,创建了一个结构体变量t1和一个联合体变量u1。
  • 接下来使用sizeof操作符来计算结构体t1和联合体u1的大小,并使用printf函数打印出这两个值。
  • 然后使用printf函数打印出结构体t1各成员变量的地址,分别是idata、cdata和ddata的地址。再打印出联合体u1各成员变量的地址,同样是idata、cdata和ddata的地址。
  • 这样就完成了整段代码的解析,它主要展示了结构体和联合体的定义和使用方式。
#include <stdio.h>

struct TesT
{
    int idata;
    char cdata;
    int ddata;
};

union TestU
{
    int idata;
    char cdata;
    int ddata;
};

int main()
{
    struct TesT t1;
    union TestU u1;

    printf("结构体t1的大小是:%d\n",sizeof(t1));
    printf("联合体u1的大小是:%d\n",sizeof(u1));

    t1.idata = 10;
    t1.cdata = 'a';
    t1.ddata = 20;

    printf("idata: %p,%d\n",&t1.idata,t1.idata);
    printf("cdata: %p,%d\n",&t1.cdata,t1.cdata);
    printf("ddata: %p,%d\n",&t1.ddata,t1.ddata);

    u1.idata = 10;
    u1.ddata = 20;
    u1.cdata = 'a';

    printf("idata: %d\n",u1.idata);
    printf("idata: %p\n",&u1.idata);
    printf("cdata: %p\n",&u1.cdata);
    printf("ddata: %p\n",&u1.ddata);

}

结构体t1的大小是:16   
联合体u1的大小是:8    
idata: 00000083ffdff6f0
cdata: 00000083ffdff6f4
ddata: 00000083ffdff6f8
idata: 00000083ffdff6e8
cdata: 00000083ffdff6e8
ddata: 00000083ffdff6e8

10、共用体注意数据覆盖问题

//注意联合体的值覆盖问题

```c
#include <stdio.h>
```
包含标准输入输出的头文件。

```c
struct TesT
{
    int idata;
    char cdata;
    int ddata;
};
```
定义一个名为 TesT 的结构体,包含三个成员变量:一个整数 idata,一个字符 cdata,一个整数 ddata。

```c
union TestU
{
    int idata;
    char cdata;
    int ddata;
};
```
定义一个名为 TestU 的联合体,包含三个成员变量:一个整数 idata,一个字符 cdata,一个整数 ddata。

```c
int main()
{
    struct TesT t1;
    union TestU u1;
```
定义一个 main 函数,创建了一个名为 t1 的 TesT 结构体变量和一个名为 u1 的 TestU 联合体变量。

```c
    printf("结构体 t1 的大小是:%d\n", sizeof(t1));
    printf("联合体 u1 的大小是:%d\n", sizeof(u1));

    t1.idata = 10;
    t1.cdata = 'a';
    t1.ddata = 20;
```
使用 sizeof 运算符输出结构体 t1 和联合体 u1 的大小,然后给结构体 t1 的成员变量赋值。

```c
    printf("idata: %p,%d\n", &t1.idata, t1.idata);
    printf("cdata: %p,%d\n", &t1.cdata, t1.cdata);
    printf("ddata: %p,%d\n", &t1.ddata, t1.ddata);
```
打印结构体 t1 的各项成员的地址和值。

```c
    u1.idata = 10;
    u1.ddata = 20;
    u1.cdata = 'a';

    printf("idata = %d\n", u1.idata);
    printf("idata: %p\n", &u1.idata);
    printf("cdata: %p\n", &u1.cdata);
    printf("ddata: %p\n", &u1.ddata);

    return 0;
}
```
给联合体 u1 的成员变量赋值,然后打印联合体 u1 各项成员的值和地址。

最后,返回值 0,表示程序正常执行结束。

#include <stdio.h>

struct TesT
{
    int idata;
    char cdata;
    int ddata;
};

union TestU
{
    int idata;
    char cdata;
    int ddata;
};

int main()
{
    struct TesT t1;
    union TestU u1;

    printf("结构体t1的大小是:%d\n",sizeof(t1));
    printf("联合体u1的大小是:%d\n",sizeof(u1));

    t1.idata = 10;
    t1.cdata = 'a';
    t1.ddata = 20;

    printf("idata: %p,%d\n",&t1.idata,t1.idata);
    printf("cdata: %p,%d\n",&t1.cdata,t1.cdata);
    printf("ddata: %p,%d\n",&t1.ddata,t1.ddata);

    u1.idata = 10;
    u1.ddata = 20;
    u1.cdata = 'a';

    printf("idata = %d\n",u1.idata);
    printf("idata: %p\n",&u1.idata);
    printf("cdata: %p\n",&u1.cdata);
    printf("ddata: %p\n",&u1.ddata);

    return 0;
}

结构体t1的大小是:12      
联合体u1的大小是:4       
idata: 0000008f3c3ffd44,10
cdata: 0000008f3c3ffd48,97
ddata: 0000008f3c3ffd4c,20
idata = 97                
idata: 0000008f3c3ffd40   
cdata: 0000008f3c3ffd40   
ddata: 0000008f3c3ffd40

11、共用体开发案例

这段代码是一个简单的C语言程序,它定义了一个名为Person的结构体,并在结构体中使用了联合体。以下是对每一行代码的解析:

1. `#include <stdio.h>`:包含了输入输出函数的头文件。

3. `struct Person`:定义了一个名为Person的结构体类型。

4. `char name[32];`:在Person结构体中定义了一个名为name的字符数组,长度为32。

5. `int age;`:在Person结构体中定义了一个名为age的整型变量。

6. `char zhiYe;`:在Person结构体中定义了一个名为zhiYe的字符变量。

7. `char addr[32];`:在Person结构体中定义了一个名为addr的字符数组,长度为32。

8. `union { ... } mes;`:在Person结构体中定义了一个名为mes的联合体。联合体可以在给定的一段内存空间中存储不同类型的数据。

9-14. `int class;` 和 `char keMu[12];`:联合体mes中的成员变量,定义了一个名为class的整型变量和一个名为keMu的字符数组,长度为12。这两个成员变量共享内存空间,只能同时存储其中一个值。

16. `int main()`:程序的主函数。

18. `struct Person p[2];`:定义了一个名为p的Person类型数组,长度为2,用于存储两个人的信息。

19. `int i;`:定义了一个名为i的整型变量,用于循环计数。

22-39. `for` 循环:循环两次,依次获取两个人的信息。

24. `printf("请输入职业:t代表老师,s代表学生\n");`:打印提示信息,要求输入职业信息。

25. `scanf("%c",&(p[i].zhiYe));`:将输入的字符赋值给p[i]的zhiYe成员变量。

27-33. 根据输入的职业信息进行判断和赋值,如果是学生则要求输入班级信息和名字,如果是老师则要求输入科目和名字。

38. `getchar();`:读取一个字符,用于处理换行符。

41-48. 循环输出每个人的信息。

43. `printf("学生的名字是:%s,班级是%d\n",p[i].name,p[i].mes.class);`:打印学生的名字和班级信息。

46. `printf("老师的名字是:%s,职业是%s\n",p[i].name,p[i].mes.keMu);`:打印老师的名字和科目信息。

50. `return 0;`:返回程序执行成功的标志。

#include <stdio.h>

struct Person
{
    char name[32];
    int age;
    char zhiYe;
    char addr[32];
    union {
        int class;
        char keMu[12];
    }mes;
};

int main()
{
    struct Person p[2];
    int i;
    for(i=0;i<2;i++){
        printf("请输入职业:t代表老师,s代表学生\n");
        scanf("%c",&(p[i].zhiYe));
        if(p[i].zhiYe == 's'){
            printf("请输入学生班级:\n");
            scanf("%d",&(p[i].mes.class));
            printf("请输入学生名字:\n");
            scanf("%s",p[i].name);
        }
        else{
            printf("请输入老师的科目:\n");
            scanf("%s",p[i].mes.keMu);
            printf("请输入老师名字:\n");
            scanf("%s",p[i].name);
        }
        getchar();
    }
    for(i=0;i<2;i++){

        if(p[i].zhiYe == 's'){
            printf("学生的名字是:%s,班级是%d\n",p[i].name,p[i].mes.class);
        }
        else{
            printf("老师的名字是:%s,职业是%s\n",p[i].name,p[i].mes.keMu);
        }
    }
    return 0;
}

请输入职业:t代表老师,s代表学生
t
请输入老师的科目:
射箭
请输入老师名字:
依依
请输入职业:t代表老师,s代表学生
s
请输入学生班级:
1
请输入学生名字:
双双
老师的名字是:依依,职业是射箭
学生的名字是:双双,班级是1

 12、枚举类型介绍 

解析每一行代码:

1. `#include <stdio.h>`:预处理指令,包含了标准输入/输出函数的头文件。

3. `enum  {sun,mon,tus,wed,thi,fri,sat}w1,w2;`:定义了一个匿名的枚举类型,并声明了两个枚举变量w1和w2。枚举常量sun, mon, ..., sat分别对应0到6。

5. `int main()`:主函数的定义。

7. `w1 = mon;`:将枚举常量mon赋值给w1。

8. `w2 = tus;`:将枚举常量tus赋值给w2。

9. `if(w2 < tus)`:使用比较运算符判断w2是否小于tus。

10. `printf("哈哈哈\n");`:如果w2小于tus,则输出"哈哈哈"。

12. `printf("w1 = %d\n",w1);`:输出w1的值。

13. `printf("w2 = %d\n",w2);`:输出w2的值。

15. `return 0;`:函数返回值为0,表示程序执行成功结束。

#include <stdio.h>

//enum WeekDay {sun,mon,tus,wed,thi,fri,sat};

enum  {sun,mon,tus,wed,thi,fri,sat}w1,w2;

int main()
{
    //enum WeekDay w;
    //w = thi;
    w1 = mon;
    w2 = tus;
    if(w2 < tus){
        printf("哈哈哈\n");
    }
    //printf("w = %d\n",w);
    printf("w1 = %d\n",w1);
    printf("w2 = %d\n",w2);
    return 0;
}

 

 13、typedef关键字


//
#include <stdio.h>

typedef unsigned int u8;
typedef int  u16;
typedef int arr[10];

struct Test
{
    int data;
    int data2;
};

typedef struct Test T;

typedef struct
{
    int data1;
    int data2;
}Demo;

void printInfo(T t)
{
    printf("%d\n",t.data);
}
int main()
{
    arr a;
    a[0] = 10;

    printf("%d\n",a[0]);

    struct Test t1;
    t1.data = 100;
    printf("%d\n",t1.data);

   T t2;
   t2.data = 1000;
    printInfo(t2);

    Demo d;
    d.data1 = 999;
    printf("%d\n",d.data1);
}

 

  14、typedef关键字和结构体练习



#include <stdio.h>

typedef struct
{
    int num;
    char name[32];
    char sex;
}Person,*pPerson;

void printInfo(Person p)
{
    printf("%d号姐姐:%s %c\n",p.num,p.name,p.sex);
}

void printInfo3(Person *p)
{
    printf("%d号姐姐:%s %c\n",p->num,p->name,p->sex);
}
void printInfo2(pPerson pp)
{
    printf("%d号姐姐:%s %c\n",pp->num,pp->name,pp->sex);
}

int main()
{
    Person p1 = {1,"莉莉",'g'};
    Person p2 = {2,"美美",'g'};
    printInfo(p1);
    printInfo(p2);

    pPerson pp1 = &p1;
    pPerson pp2 = &p2;
    printInfo2(pp1);
    printInfo2(pp2);


    Person *pp3 = &p1;
    Person *pp4 = &p2;
    printInfo3(pp3);
    printInfo3(pp4);
    return 0;
}

F:\C-code\typedef-struct案例练习.exe
1号姐姐:莉莉 g
2号姐姐:美美 g
1号姐姐:莉莉 g
2号姐姐:美美 g
1号姐姐:莉莉 g
2号姐姐:美美 g

进程已结束,退出代码0

;