• 结构体及应用;结构体指针及应用;union、enum、typedef三个关键字


    结构体及应用

    参考文章链接:https://blog.csdn.net/zw1996/article/details/53844585
    
    • 1
    1. 结构体的声明

      在这里插入图片描述

    2. 结构体的初始化

      注意如果在定义结构体变量的时候没有初始化,那么后面就不能全部一起初始化了。

      /这样是可以的,在定义变量的时候就初始化了;
      struct book s1={//对结构体初始化 
              "guojiajiaoyun",//author为字符数组 
                "yuwen",//title为字符串 
                22.5
          };
      /这种就不行了,在定义变量之后,若再要对变量的成员赋值,那么只能单个赋值了;
      struct book s1;
          s1={ 
               "guojiajiaoyun",//author为字符数组 
                "yuwen",//title为字符串 
                22.5  
          };//这样就是不行的,只能在定义的时候初始化才能全部赋值,之后就不能再全体赋值了,只能单个赋值;
          只能;
          s1.title = "yuwen";........//单个赋值;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
    3. 结构体数组初始化

      在这里插入图片描述

    4. 应用练习

      /*
      用结构体做一个选票系统,输入选民和唱票过程,输出票数和当选人
      */
      #include 
      #include 
      
      struct XuanMin
      {
      	char name[32];
      	int tickets;
      };
      int main()
      {
      	int i;
      	int j;
      	int len;
      	int mark;
      	int quit = 0;
      	char tmp_name[32];
      	struct XuanMin xm[3];
      	struct XuanMin max;
      	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++){//总共有5票
      	
      		mark = 0;
      		printf("请输入你要投给谁:\n");
      		memset(tmp_name,'\0',sizeof(tmp_name));
      		scanf("%s",tmp_name);
      		for(j = 0;j < len;j++){//判断是否和输入的三个选民名字相同
      			
      			if(strcmp(tmp_name,xm[j].name) == 0){
      				xm[j].tickets++;
      				mark = 1;
      			}
      		}
      		if(mark == 0){
      			quit++;
      			printf("查无此人,弃票\n");
      		}
      	}
      	max = xm[0];
      	for(i = 1;i<len;i++){
      		if(max.tickets < xm[i].tickets){
      			max = xm[i];
      		}
      	}
      	
      
      	for(i = 0;i < len;i++){
      		printf("选民:%s的票数为:%d\n",xm[i].name,xm[i].tickets);
      	}
      	printf("弃票数:%d\n",quit);
      	printf("%s以%d票当选,%d人弃票\n",max.name,max.tickets,quit);
      	return 0;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62

    结构体指针及应用

    1. 指针就是地址,指针变量就是存放地址的变量,结构体也是变量。变量的访问有两种方式:1.变量名;2.地址。之前的结构体都是用变量名访问。

      通过结构体变量地址来访问该结构体需要一个变量来存放这个地址:和之前的指针是一样的,只是指针类型是结构体。

      int a;
      int *p;
      p = &a;
      
      struct Test t1;
      struct Test *p;
      p = &t1;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    2. 访问

      #include 
      struct Test
      {
      	int idata;
      	char cdata;
      };
      int main()
      {
      	struct Test t1 = {10,'X'};
      	struct Test *p;
      	p = &t1;
      
      	printf("idata:%d\n",t1.idata);//变量名访问 用点符号
      	printf("idata:%d\n",p->idata);//指针访问 用箭头符号
      
      	return 0;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
    3. 结构体指针+函数的练习

      /*
      函数创建结构体,函数初始化结构体
      函数实现唱票过程
      */
      #include 
      #include 
      #include 
      
      struct XuanMin
      {
      	char name[32];
      	int tickets;
      };
      //结构体初始化
      struct XuanMin* init_xm(struct XuanMin *p,int *plen)//返回值是结构体指针
      {
      	int i;
      	//为指针开辟空间
      	if(p == NULL){
      		printf("请输入选民个数:\n");
      		scanf("%d",plen);
      		p = (struct XuanMin*)malloc(*plen*sizeof(struct XuanMin));
      	}
      	
      	for(i=0;i<*plen;i++){
      		p->tickets = 0;
      		printf("请输入第%d个选民的名字:",i+1);
      		scanf("%s",p->name);
      		p++;
      	}
      	
      	return p-*plen;
      }
      //打印结构体
      void printf_struct(struct XuanMin *p,int len)
      {
      	int i;
      	for(i=0;i<len;i++){
      		printf("选民:%s的票数为:%d\n",p->name,p->tickets);
      		p++;
      	}
      	
      }
      //唱票过程
      int do_vote(struct XuanMin* p,int len,int num)
      {
      	int i;
      	int j;
      	int mark;
      	int quit = 0;
      	char tmp_name[32];
      	struct XuanMin* pbak = p;
      	for(i=0;i<num;i++){//总共有num票
      		p = pbak;
      		mark = 0;
      		printf("第%d个人投给:",i+1);
      		memset(tmp_name,'\0',sizeof(tmp_name));//清空
      		scanf("%s",tmp_name);
      		for(j = 0;j < len;j++){//判断是否和输入的三个选民名字相同
      			
      			if(strcmp(tmp_name,p->name) == 0){
      				p->tickets++;
      				mark = 1;
      			}
      			p++;
      		}
      		if(mark == 0){
      			quit++;
      			printf("查无此人,弃票\n");
      		}
      	}
      	
      	return quit;
      }
      //找出票数最高的
      struct XuanMin* getmax(struct XuanMin* p,int len)
      {
      	int i;
      	struct XuanMin* max;
      	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* max ;
      	int len;
      	int quit;
      	int num;
      	xm =  init_xm(xm,&len);
      	printf("请输入投票次数:\n");
      	scanf("%d",&num);
      	quit = do_vote(xm,len,num);
      	printf("弃票数为:%d\n",quit);
      	printf_struct(xm,len);
      	max = getmax(xm,len);
      	printf("%s以%d票当选,%d人弃票\n",max->name,max->tickets,quit);
      	return 0;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
      • 50
      • 51
      • 52
      • 53
      • 54
      • 55
      • 56
      • 57
      • 58
      • 59
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79
      • 80
      • 81
      • 82
      • 83
      • 84
      • 85
      • 86
      • 87
      • 88
      • 89
      • 90
      • 91
      • 92
      • 93
      • 94
      • 95
      • 96
      • 97
      • 98
      • 99
      • 100
      • 101
      • 102
      • 103
      • 104
      • 105
    4. 二级指针的练习

      void init_xm(struct XuanMin** pxm,int*  plen)
      {
      	//初始化结构体
      	int i;
      	
      	if(*pxm == NULL){
      		printf("请输入选民的个数:\n");
      		scanf("%d",plen);
      		*pxm = (struct XuanMin*)malloc(*plen * sizeof(struct XuanMin));
      	}
      	for(i=0;i<*plen;i++){
      		(*pxm)->tickets = 0;
      		printf("请输入第%d个选民的名字:\n",i+1);
      		scanf("%s",(*pxm)->name);
      		(*pxm)++;
      	}
      	*pxm = *pxm - *plen;
      }
      int main()
      {
          struct XuanMin *xm;
      	int len;
      	int *plen = &len;
      	struct XuanMin** pxm = &xm;//定义指向指针的变量为二级指针
      
      	init_xm(&xm,&len);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27

    联合体union

    1. 结构体struct

      各成员各自拥有自己的内存,各自使用互不干涉,同时存在的,遵循内存对齐原则。一个struct变量的总长度等于所有成员的长度之和。

    2. 联合体/共用体union

      各成员共用一块内存空间,并且同时只有一个成员可以得到这块内存的使用权(对该内存的读写),各变量共用一个内存首地址。因而,联合体比结构体更节约内存。一个union变量的总长度至少能容纳最大的成员变量,而且要满足是所有成员变量类型大小的整数倍。不允许对联合体变量名U2直接赋值或其他操作。

    3. 共同体每次只能存放共同体变量中的的一种!!

      共同体变量中起作用的成员是最后一次存放的成员,在存入新的成员后原有的成员失去了作用!

      看大小

    在这里插入图片描述

    看地址

    在这里插入图片描述

    联合体应用小练习

    #include 
    /*
    有若干人员的数据,其中有学生和教师,学生的数据中包括:姓名、号码、
    性别、职业、班级,教师数据包括:姓名、号码、性别、职业、职务,
    要求用同一个结构体来处理。
    */
    struct Person
    {
    	char name[16];
    	int num;
    	char sex[16];
    	char zhiye;
    	union {
    		int class;
    		char kemu[16];
    	}msg;
    };
    
    int main()
    {
    	int i;
    	struct Person school[2];
    	//初始化结构体
    	for(i=0;i<2;i++){
    		printf("请输入这个人的职业:'s'代表学生,'t'代表老师。\n");
    		scanf("%c",&(school[i].zhiye));
    		if(school[i].zhiye == 's'){
    			printf("请输入学生的名字:");
    			scanf("%s",&(school[i].name));
    			printf("请输入学生的号码:");
    			scanf("%d",&(school[i].num));
    			printf("请输入学生的性别:");
    			scanf("%s",&(school[i].sex));
    			printf("请输入学生的班级:");
    			scanf("%d",&(school[i].msg.class));
    		}if(school[i].zhiye == 't'){
    			printf("请输入老师的名字:");
    			scanf("%s",&(school[i].name));
    			printf("请输入老师的号码:");
    			scanf("%d",&(school[i].num));
    			printf("请输入老师的性别:");
    			scanf("%s",&(school[i].sex));
    			printf("请输入老师的科目:");
    			scanf("%s",&(school[i].msg.kemu));
    		}
    		getchar();
    	}
    	//打印结构体数据
    	for(i=0;i<2;i++){
    		if(school[i].zhiye == 's'){
    		printf("学生个人资料:\n");
    		printf("姓名:%s,号码:%d,性别:%s,班级:%d\n",
    			school[i].name,school[i].num,school[i].sex,school[i].msg.class);
    		}
    		if(school[i].zhiye == 't'){
    		printf("老师个人资料:\n");
    		printf("姓名:%s,号码:%d,性别:%s,科目:%s\n",
    			school[i].name,school[i].num,school[i].sex,school[i].msg.kemu);
    		}
    	}
    	
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    枚举类型enum

    1. 如果一个变量只有几种可能的值,比如星期几:Mon、Tues、Wed、Thurs、Fri、Sat、Sun。

    2. 怎么定义枚举类型:列表中的名字,可以自己定义,无需像变量一样去申请。

      C编译器把它当成常量处理,也称枚举变量。

      enum Week {Mon,Tues,Wed,Thurs,Fri,Sat,Sun};
      enum Week {Mon = 1,Tues = 2,Wed,Thurs,Fri,Sat,Sun};
      enum {Mon,Tues,Wed,Thurs,Fri,Sat,Sun}w1,w2;
      
      • 1
      • 2
      • 3
      • 只限列表中的几种情况
      • 值默认从0开始,枚举元素不能被赋值,虽然看着像变量名
      • 可以指定列表中枚举数的值

    typedef关键字

    1. typedef是在C和C++编程语言中的一个关键字。作用是为现有的数据类型(int、float、char……)创建一个新的名字,目的是为了使代码方便阅读和理解。

      typedef 原类型 新类型名;
      //整型
      typedef int DATATYPE;
      DATATYPE a;
      
      //结构体
      typedef struct stu STU;
      STU stu1;
      //结构体
      typedef struct{
      	int data;
      	int data2;
      }T2;
      T2 t2;
      
      //数组
      typedef char ARRAY20[20];
      //表示ARRAY20是类型char[20]的别名,它是一个长度为20的字符数组类型,接着可以用ARRAY20定义数组:
      ARRAY20 a1,a2,a3,a4;
      
      //指针
      typedef int *STRING;
      STRING a;
      
      //数组指针
      typedef int (*PTR_TO_ARR)[4];
      //表示 PTR_TO_ARR 是类型int (*) [4]的别名,它是一个一维数组指针类型。接着可以使用 PTR_TO_ARR 定义一维数组指针:
      PTR_TO_ARR p1, p2;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
    2. typedef与#define的区别

      Typedef是起别名,define是替换。

      例如:

      typedef int *PTR; //要加 ";"
      PTR a,b;
      
      • 1
      • 2

      此时a,b都是指针变量。

      #define PTR int* //不用 ";"
      PTR a,b;
      
      • 1
      • 2

      此时等同于

      int *a,b;
      
      • 1

      只有a为指针变量,而b为整型变量。

  • 相关阅读:
    【Hack The Box】windows练习-- Bastard
    P4的exercises实现原理
    Ubuntu20运行SegNeXt代码提取道路水体(一)——从零开始运行代码过程摸索
    关于在 Angular 应用里重复调用 RouterModule.forRoot(ROUTES) 的讨论
    SD3403/SS928 视频采集调试记录
    UUCTF部分web题解
    Matlab:Matlab软件之Simulink的简介、特点、使用方法、界面介绍之详细攻略
    c++的字节序与符号位的问题
    React Refs 使用场景及核心要点
    Hadoop+Zookeeper+HA错题总结(一)
  • 原文地址:https://blog.csdn.net/weixin_45650620/article/details/137876481