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

news2024/12/23 17:13:39

结构体及应用

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

    在这里插入图片描述

  2. 结构体的初始化

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

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

    在这里插入图片描述

  4. 应用练习

    /*
    用结构体做一个选票系统,输入选民和唱票过程,输出票数和当选人
    */
    #include <stdio.h>
    #include <string.h>
    
    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. 指针就是地址,指针变量就是存放地址的变量,结构体也是变量。变量的访问有两种方式:1.变量名;2.地址。之前的结构体都是用变量名访问。

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

    int a;
    int *p;
    p = &a;
    
    struct Test t1;
    struct Test *p;
    p = &t1;
    
  2. 访问

    #include <stdio.h>
    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;
    }
    
  3. 结构体指针+函数的练习

    /*
    函数创建结构体,函数初始化结构体
    函数实现唱票过程
    */
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    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;
    }
    
  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);
    }
    

联合体union

  1. 结构体struct

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

  2. 联合体/共用体union

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

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

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

    看大小

在这里插入图片描述

看地址

在这里插入图片描述

联合体应用小练习

#include <stdio.h>
/*
有若干人员的数据,其中有学生和教师,学生的数据中包括:姓名、号码、
性别、职业、班级,教师数据包括:姓名、号码、性别、职业、职务,
要求用同一个结构体来处理。
*/
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;
}

枚举类型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;
    
    • 只限列表中的几种情况
    • 值默认从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;
    
  2. typedef与#define的区别

    Typedef是起别名,define是替换。

    例如:

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

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

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

    此时等同于

    int *a,b;
    

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1602434.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

顺序表(增删减改)+通讯录项目(数据结构)+顺序表专用题型

什么是顺序表 顺序表和数组的区别 顺序表本质就是数组 结构体初阶进阶 系统化的学习-CSDN博客 简单解释一下&#xff0c;就像大家去吃饭&#xff0c;然后左边是苍蝇馆子&#xff0c;右边是修饰过的苍蝇馆子&#xff0c;但是那个好看的苍蝇馆子一看&#xff0c;这不行啊&a…

C++动态内存管理 解剖new/delete详细讲解(operator new,operator delete)

讨厌抄我作业和不让我抄作业的人 讨厌插队和不让我插队的人 讨厌用我东西和不让我用东西的人 讨厌借我钱和不借给我钱的人 讨厌开车加塞和不让我加塞的人 讨厌内卷和打扰我内卷的人 一、C中动态内存管理 1.new和delete操作内置类型 2.new和delete操作自定义类型 二、operat…

Ethereum WebSocket接口实践

之前在学习Ethereum的infura API时候看到有WebSocket&#xff0c;但是翻了很久都没找到很完整的接口文档和实践文档。当时比较迷&#xff0c;没太在意&#xff0c;以为是区块链接口的性能还用不上WebSocket&#xff0c;HTTP完全支持没问题。 后面在更深入学习了jsonrpc协议之后…

面试官:一个Java对象占用多大内存?

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

校园智能水电预付费管理系统

校园智能水电预付费管理系统是一种专为学校水电资源管理而设计的智能化系统&#xff0c;旨在提供全面的水电资源管理解决方案&#xff0c;满足校园管理者对水电资源管理的需求。该系统整合了先进的智能技术和云计算&#xff0c;为校园管理者提供了实时监控、自动计费、节能管理…

Windows 部署ChatGLM3大语言模型

一、环境要求 硬件 内存&#xff1a;> 16GB 显存: > 13GB&#xff08;4080 16GB&#xff09; 硬盘&#xff1a;60G 软件 python 版本推荐3.10 - 3.11 transformers 库版本推荐为 4.36.2 torch 推荐使用 2.0 及以上的版本&#xff0c;以获得最佳的推理性能 二、部…

docker安装EelasticSearch、目录权限修改、并安装IK 中文分词器

文章目录 docker安装EelasticSearch、目录权限修改、并安装IK 中文分词器1、docker安装ES2、docker ps发现容器没有正常启动&#xff0c;docker logs 容器id 查看日志发现是挂载目录的权限不足3、修改目录的权限4、使用docker restart 容器id重新启动刚才没有启动成功的容器5、…

人工智能揭示矩阵乘法的新可能性

人工智能揭示矩阵乘法的新可能性 数学家酷爱漂亮的谜题。当你尝试找到最有效的方法时&#xff0c;即使像乘法矩阵&#xff08;二维数字表&#xff09;这样抽象的东西也会感觉像玩一场游戏。这有点像尝试用尽可能少的步骤解开魔方——具有挑战性&#xff0c;但也很诱人。除了魔方…

嵌入式工程师如何摸鱼?

有老铁问我&#xff0c;做嵌入式开发要加班吗&#xff1f; 也不知道搞什么鬼&#xff0c;现在的年轻人对加班这么抵触。 我刚做开发那会&#xff0c;啥也不懂&#xff0c;每天基本都要加班到晚上7-9点不等&#xff0c;我并不抵触加班&#xff0c;因为早早回家&#xff0c;也没什…

【文献分享】PCCP:机器学习 + 分子动力学 + 第一性原理 + 热学性质 + 微观结构

分享一篇关于机器学习 分子动力学 第一性原理 热学性质&#xff08;密度、粘度、扩散系数&#xff09; 微观结构的文章。 感谢论文的原作者&#xff01; 关键词&#xff1a; 1. Machine learning, 2. Deep potential, 3. Molecular dynamics 4. Molten salt, 5. Thermo…

10-菜刀连接木马

找到了漏洞后&#xff0c;并且上传了木马之后才能使用的两款工具 中国菜刀和冰蝎 想办法获取别人的cookie&#xff0c;cookie中有session-id 一、中国菜刀 1、必须提前已经完成木马植入然后才能使用 2、木马必须是POST请求&#xff0c;参数自定义&#xff0c;在菜刀里给出…

苹果系统如何使用CorelDRAW?coreldraw苹果版使用指南

有不少粉丝使用的是苹果的电脑或者笔记本&#xff0c;想要利用最新的M系列芯片带来的长续航便利&#xff0c;实现外出时进行创意设计的工作。 那如何才能在苹果系统使用CorelDRAW&#xff1f;2个方法分享给大家&#xff1a; 一、购买Mac版CorelDRAW 从2020版开始&#xff0c…

预分region解决热点问题(面试题)

一、题目&#xff1a;如何解决hbase中遇到的热点问题&#xff1f; 1、问题引入 在默认的拆分策略中 ,region的大小达到一定的阈值以后才会进行拆分,并且拆分的region在同一个regionserver中 ,只有达到负载均衡的时机时才会进行region重分配!并且开始如果有大量的数据进行插入操…

【HormonyOS4+NEXT】TypeScript基础语法详解

&#x1f64b;‍ 一日之际在于晨 ⭐本期内容&#xff1a;TypeScript基础语法详解 &#x1f3c6;系列专栏&#xff1a;鸿蒙HarmonyOS4NEXT&#xff1a;探索未来智能生态新纪元 文章目录 前言变量与类型函数类与接口类&#xff08;Class&#xff09;接口&#xff08;Interface&am…

基于51单片机点滴输液控制系统LCD显示( proteus仿真+程序+设计报告+讲解视频)

基于51单片机点滴输液控制系统LCD显示 1. 主要功能&#xff1a;2. 讲解视频&#xff1a;3. 仿真设计4. 程序代码5. 设计报告6. 设计资料内容清单&&下载链接 基于51单片机点滴输液控制系统LCD显示( proteus仿真程序设计报告讲解视频&#xff09; 仿真图proteus7.8及以上…

Ubuntu上安装Chrome浏览器

安装步骤 1.下载安装chrome安装包 wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb2.安装Chrome浏览器 sudo dpkg -i google-chrome-stable_current_amd64.debsudo apt-get -f install3.启动Chrome浏览器 查看收藏夹里的Chrome图标 单击C…

【已开源】​基于stm32f103的爬墙小车

​基于stm32f103的遥控器无线控制爬墙小车&#xff0c;实现功能为可平衡在竖直墙面上&#xff0c;并进行移动和转向&#xff0c;具有超声波防撞功能。 直接上&#xff1a; 演示视频如&#xff1a;哔哩哔哩】 https://b23.tv/BzVTymO 项目说明&#xff1a; 在这个项目中&…

前端开发攻略---从源码角度分析Vue3的Propy比Vue2的defineproperty到底好在哪里。一篇文章让你彻底弄懂响应式原理。

1、思考 Vue的响应式到底要干什么&#xff1f; 无非就是要知道当你读取对象的时候&#xff0c;要知道它读了。要做一些别的事情无非就是要知道当你修改对象的时候&#xff0c;要知道它改了。要做一些别的事情所以要想一个办法&#xff0c;把读取和修改的动作变成一个函数&#…

ESXi 无法启动NTP守护进程

在VMware ESXi环境中如果遇到无法启动NTP&#xff08;Network Time Protocol&#xff09;守护进程的问题&#xff0c;可以通过以下步骤进行排查和解决&#xff1a; 步骤1&#xff1a;检查与修复配置文件 登录到ESXi Shell&#xff08;SSH&#xff09;。编辑 /etc/ntp.conf 配…

北京InfoComm展推出500款新品,覆盖30个市场,助力行业未来

【2024年4月17日——北京讯】亚太区首屈一指的专业视听和集成体验解决方案展北京InfoComm China 2024 今天在北京的国家会议中心 (CNCC) 盛大开幕&#xff0c;展开为期三天的商贸展会和高峰会议。作为行业产品发布的首要平台&#xff0c;北京InfoComm China吸引众多展商携新品推…