C语言基础内容(七)——第07章_结构体与共同体

文章目录

  • 第07章_结构体与共用体
    • 本章专题脉络
    • 1、结构体(struct)类型的基本使用
      • 1.1 为什么需要结构体?
      • 1.2 结构体的理解
      • 1.3 声明结构体
      • 1.4 声明结构体变量并调用成员
      • 1.5 举例
      • 1.6 小 结
    • 2、进一步认识结构体
      • 2.1 结构体嵌套
      • 2.2 结构体占用空间
      • 2.3 结构体变量的赋值操作
    • 3、结构体数组
      • 3.1 对比结构体与数组
      • 3.2 结构体数组的声明
      • 3.3 初始化数组元素
      • 3.4 结构体数组元素的成员的调用
    • 4、结构体指针
      • 4.1 结构体指针格式
      • 4.2 结构体传参
      • 4.3 -> 操作符
      • 4.4 指向结构体数组的指针
    • 5、结构体在数据结构中的应用
      • 5.1 声明结点的结构体
      • 5.2 声明结点变量
      • 5.3 两种方式对比
      • 5.4 malloc()模板
      • 5.5 举 例
    • 6、共用体类型(union)
      • 6.1 共用体概述
      • 6.2 声明共用体
      • 6.3 声明共用体变量
      • 6.4 调用共同体变量的成员
      • 6.5 ->操作符
      • 6.6 补充说明
      • 6.7 练习
    • 7、typedef 的使用(熟悉)
      • 7.1 为什么使用typedef
      • 7.2 使用格式
      • 7.3 举 例
      • 7.4 小 结
      • 7.5 应用场景

第07章_结构体与共用体

本章专题脉络

在这里插入图片描述

1、结构体(struct)类型的基本使用

1.1 为什么需要结构体?

C 语言内置的数据类型,除了几种原始的基本数据类型,只有数组属于复合类型,可以同时包含多个值,但是只能包含相同类型的数据,实际使用场景受限。

举例:隔壁老王养了两只猫咪。一只名字叫小黄,今年2岁,橘色;另一只叫小黑,今年3岁,黑色。请编写一个程序,当用户输入小猫的名字时,就显示该猫的名字,年龄,颜色。如果用户输入的小猫名错误,则显示老王没有这只猫。

传统的解决方法

尝试1:单独定义多个变量存储,实现需求。但是,多个变量,不便于数据的管理。

尝试2:使用数组,它是一组具有相同类型的数据的集合。但在编程中,往往还需要一组类型不同的数据,例如猫的名字使用字符串、年龄是int,颜色是字符串,因为数据类型不同,不能用一个数组来存放。

尝试3:C语言提供了结构体。使用结构体,内部可以定义多个不同类型的变量作为其成员。

考研中见的最多的就是指针和结构体结合起来构造结点(如链表的结点、二叉树的结点等)。

1.2 结构体的理解

C 语言提供了 struct关键字,允许自定义复合数据类型,将不同类型的值组合在一起,这种类型称为结构体(structure)类型。

C 语言没有其他语言的对象(object)和类(class)的概念,struct 结构很大程度上提供了对象和类的功能。

比如:

在这里插入图片描述

1.3 声明结构体

构建一个结构体类型的一般格式:

struct 结构体名{ 数据类型1 成员名1;   //分号结尾数据类型2 成员名2; ……数据类型n 成员名n;
}; //注意最后有一个分号

举例:学生

struct Student{       // 定义结构体:学生int id;           //学号char name[20];    //姓名char gender;      //性别char address[50]; //家庭住址
};  

举例:猫

struct Cat{char name[20];   //名字int age;         //年龄char color[20];  //颜色
};

举例:人类

struct Person{char name[20];    //姓名char gender;      //性别int age;          //年龄double weight;    //体重
}; 

举例:通讯录

struct Contacts{            char name[50];          //姓名int year;               //年int month;              //月int day;                //日char email[100];        //电子邮箱char phone_number[15]; //手机号
};

举例:员工

struct Employee {  int id;               //员工编号 char name[20];		  //员工姓名char gender;		  //员工性别int age;			  //员工年龄char address[30];	  //员工住址
};

1.4 声明结构体变量并调用成员

定义了新的数据类型以后,就可以声明该类型的变量,这与声明其他类型变量的写法是一样的。

声明结构体变量格式1:

struct 结构体类型名称 结构体变量名;

注意,声明自定义类型的变量时,类型名前面,不要忘记加上 struct 关键字。

举例:

struct Student stu1;

调用结构体变量的成员:

结构体变量名.成员名 [= 常量或变量值]

举例:

#include <stdio.h>
#include <string.h>
int main() {struct Student stu1; //声明结构体变量//调用结构体成员stu1.id = 1001;//stu1.name = "Tom"; //报错,不能直接通过赋值运算符来给字符数组赋值strcpy(stu1.name, "Tony");stu1.gender = 'M';strcpy(stu1.address, "北京市海淀区五道口");printf("id = %d,name = %s,gender = %c,address = %s\n", stu1.id, stu1.name, stu1.gender, stu1.address);return 0;
}

说明:

1)先声明了一个 struct Student类型的变量 stu1,这时编译器就会为 stu1 分配内存,接着就可以为 stu1 的不同属性赋值。可以看到,struct 结构的属性通过点( . )来表示,比如 id 属性要写成 stu1.id。

2)字符数组是一种特殊的数组,直接改掉字符数组名的地址会报错,因此不能直接通过赋值运算符来对它进行赋值。你可以使用字符串库函数 strcpy() 来进行字符串的复制操作。

声明结构体变量格式2:

除了逐一对属性赋值,也可以使用大括号,一次性对 struct 结构的所有属性赋值。此时,初始化的属性个数最好与结构体中成员个数相同,且成员的先后顺序一一对应。格式:

struct 结构体名 结构体变量={初始化数据};

举例:

//声明结构体
struct Car {char* name;double price;int speed;
};//声明结构体变量
struct Car audi = {"audi A6L", 460000.99, 175};

注意:如果大括号里面的值的数量少于属性的数量,那么缺失的属性自动初始化为 0 。

struct Student {int id;char name[20];char gender;int score;  //学生成绩};int main() {struct Student stu = {1001, "songhk", 'M'};printf("Name: %s\n", stu.name);printf("Score: %d\n", stu.score);return 0;
}

声明结构体变量格式3:

方式2中大括号里面的值的顺序,必须与 struct 类型声明时属性的顺序一致。此时,可以为每个值指定属性名。

格式:

struct 结构体名 结构体变量={.成员1=xxx,.成员2=yyy,...};

举例:

struct Car audi = {.speed=175, .name="audi A6L"};

同样,初始化的属性少于声明时的属性,剩下的那些属性都会初始化为 0 。

声明变量以后,可以修改某个属性的值。

struct Car audi = {.speed=175, .name="audi A6L"};
audi.speed = 185;  //将 speed 属性的值改成 185

声明结构体变量格式4: 声明类型的同时定义变量

struct 的数据类型声明语句与变量的声明语句,可以合并为一个语句。格式:

struct 结构体名 {成员列表
} 变量名列表;

举例:同时声明了数据类型 Circle 和该类型的变量 c1

struct Circle {int id;double radius;
} c1;

举例:

struct Employee {char name[20];int age;char gender;char phone[11];
} emp1, emp2;

声明结构体变量格式5: 不指定类型名而直接定义结构体类型变量

如果类型标识符(比如Student、Circle、Employee等)只用在声明时这一个地方,后面不再用到,那就可以将类型名省略。 该结构体称为匿名结构体

格式:

struct {成员列表;
} 变量名列表;

举例:

struct {char name[20];int age;char gender;char phone[11];
} emp1, emp2;

struct 声明了一个匿名数据类型,然后又声明了这个类型的两个变量emp1、emp2 。与其他变量声明语句一样,可以在声明变量的同时,对变量赋值。

举例:

struct {char name[20];int age;char gender;char phone[11];
} emp1 = {"Lucy", 23, 'F', "13012341234"},emp2 = {"Tony", 25, 'M', "13367896789"};

上例在声明变量 emp1 和 emp2 的同时,为它们赋值。

**声明结构体变量格式6:**使用 typedef 命令

使用 typedef 可以为 struct 结构指定一个别名,这样使用起来更简洁。

举例:

//声明结构体
typedef struct cell_phone {int phone_no;              //电话号码double minutes_of_charge;  //每分钟费用
} Phone;//声明结构体变量
Phone p = {13012341234, 5};

上例中, Phone 就是 struct cell_phone 的别名。声明结构体变量时,可以省略struct关键字。

这种情况下,C 语言允许省略 struct 命令后面的类型名。进一步改为:

//声明匿名结构体
typedef struct {int phone_no;double minutes_of_charge;
} Phone;//声明结构体变量
Phone p = {13012341234, 5};

进一步,在考研中,还会出现如下的声明方式:

typedef struct {int phone_no;double minutes_of_charge;
} Phone,*pPhone;

这里多了个*pPhone,其实在定义一个结点指针p时,Phone *p; 等价于 pPhone p; ,前者的写法类似于int *a、char *b等更方便记忆,不必再加个pPhone p来增加记忆负担。所以在考研中我们不采用这种方法,统一删掉 *pPhone的写法。

说明:

1、在创建一个结构体变量后,需要给成员赋值。在没有给成员赋值的情况下调用,打印的值是垃圾数据,可能导致程序异常终止。

2、不同结构体变量的成员是独立的,互不影响,一个结构体变量的成员更改,不影响另外一个。

1.5 举例

练习:盒子案例

(1)编程创建一个Box结构体,在其中定义三个成员表示一个立方体的长、宽和高,长宽高可以通过控制台输入。

(2)定义一个函数获取立方体的体积(volume)。

(3)创建一个结构体,打印给定尺寸的立方体的体积。

#include <stdio.h>// 1. 定义Box结构体
struct Box {double length;double width;double height;
};// 2. 获取立方体体积的函数
double getVolume(struct Box box) {return box.length * box.width * box.height;
}int main() {// 3. 创建结构体实例struct Box box;printf("输入长度:");scanf("%lf", &box.length);printf("输入宽度:");scanf("%lf", &box.width);printf("输入高度:");scanf("%lf", &box.height);// 调用函数获取体积并打印printf("体积为: %.2lf\n", getVolume(box));return 0;
}

1.6 小 结

区分三个概念:结构体、结构体变量、结构体变量的成员。

  • 结构体是自定义的数据类型,表示的是一种数据类型。

  • 结构体变量代表一个具体变量。类比:

    int num1 ; // int 是数据类型, 而num1是一个具体的int变量struct Car car1; // Car 是结构体数据类型,而car1是一个Car变量
    
  • Car 就像一个“汽车图纸”,生成出来的具体的一辆辆汽车,就类似于一个个的结构体变量。这些结构体变量都含有相同的成员,将结构体变量的成员比作“零件”,同一张图纸生产出来的零件的作用都是一样的。

2、进一步认识结构体

2.1 结构体嵌套

结构体的成员也是变量,那么成员可以是基本数据类型,也可以是数组指针结构体等类型 。如果结构体的成员是另一个结构体,这就构成了结构体嵌套。

举例1:

#include <stdio.h>
#include <string.h>struct Name {char firstName[50];char lastName[50];
};struct Student {int age;struct Name name;char gender;
} stu1;int main(){strcpy(stu1.name.firstName, "美美");strcpy(stu1.name.lastName, "韩");//stu1.age = 18;//stu1.gender = 'F';//或者struct Name myname = {"美美","韩"};stu1.name = myname;//stu1.age = 18;//stu1.gender = 'F';return 0;
}

举例2:

struct Date {    //声明一个结构体类型 struct Date int year;    //年int month;   //月int day;     //日
};struct Employee { //声明一个结构体类型 struct Employeeint id;char name[20];int age;struct Date birthday; //成员birthday属于struct Date类型
};

声明结构体变量并调用成员:

#include <stdio.h>
#include 

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

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

相关文章

requestAnimationFrame实现动画

实现浏览器在每一帧中&#xff0c;将页面div元素的宽度变长1px&#xff0c;直到宽度达到100px后停止。 我们采用requestAnimationFrame来实现这个功能&#xff0c;关键代码如下&#xff1a; <div id"div" className{"progress-bar "} style{{ backgrou…

Python——python练习题

1.小明身高1.75&#xff0c;体重80.5kg。请根据BMI公式&#xff08;体重除以身高的平方&#xff09;帮小明计算他的BMI指数&#xff0c;并根据BMI指数&#xff1a; 低于18.5&#xff1a;过轻 18.5-25&#xff1a;正常 25-28&#xff1a;过重 28-32&#xff1a;肥胖 高于32&…

Vue实现输入框某一行高亮

实现边输入边校验是否符合限制规则&#xff0c;如果不符合使得这一行的字符颜色为红 <style scoped> .main {width: 500px;margin-left: 100px;height: 500px;position: relative;}.common-style {width: 100%;height: 100%;font-size: 14px;font-family: monospace;wor…

19. 蒙特卡洛强化学习之策略控制

文章目录 1. MC学习中的策略控制是什么2. 基于贪心算法的策略改进的基本描述3.MC学习中完全使用贪心算法可行否4. 如何改进完全贪心算法5. 何谓 ε − \varepsilon- ε−贪心算法5.1 基本思想5.2 基于 ϵ − 贪心算法 \epsilon-贪心算法 ϵ−贪心算法的策略控制的形式化描述5.3…

跳跃游戏,经典算法实战。

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

AES加解密模式

要想学习AES&#xff0c;首先要清楚三个基本的概念&#xff1a;密钥、填充、模式。 1、密钥 密钥是AES算法实现加密和解密的根本。对称加密算法之所以对称&#xff0c;是因为这类算法对明文的加密和解密需要使用同一个密钥。 AES支持三种长度的密钥&#xff1a; 128位&#xff…

(十)IIC总线-PCF8591-ADC/DAC

文章目录 IIC总线篇起始&#xff0c;终止信号应答信号发送&#xff0c;读取数据IIC通讯规则 PCF8591-ADC-DAC篇特性一般说明地址Control byte&#xff08;控制字&#xff09;简单了解一下DAC电阻分隔链应用为王DAC的应用ADC的应用ADC采集特点ADC读模式 ADC现象演示DAC现象演示 …

Spring Bean 是线程安全的吗?

如果你现在需要准备面试&#xff0c;可以关注我的公众号&#xff1a;”Tom聊架构“&#xff0c;回复暗号&#xff1a;”578“&#xff0c;领取一份我整理的50W字面试宝典&#xff0c;可以帮助你提高80%的面试通过率&#xff0c;价值很高&#xff01;&#xff01; Spring 框架中…

Linux文件和目录管理命令----unlink命令

unlink命令是Linux系统中一个用于删除文件的命令。与常见的rm命令不同,unlink命令不会将文件放入回收站,而是直接删除文件,并且不会提示用户确认操作,因此需要谨慎使用。 unlink命令的基本用法 unlink命令的基本语法如下: unlink 文件名其中,文件名 是要删除的文件的名…

使用Python爬取小红书笔记与评论(js注入方式获取x-s)

文章目录 1. 写在前面2. 分析加密入口3. 使用JS注入4. 爬虫工程化 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】&#xff1a;对JS逆向感…

Java使用Mybatis获取数据库Geometry

Java使用Mybatis获取数据库Geometry 方案A 使用ST_AsText(l.coordinates) 查询速度会慢因转换字符串数据大小会大 将几何对象转换为文本 mapper层 select ST_AsText(coordinates) as coordinates from table1domain 层 public class Entry implements Serializable {priva…

Cesium 实战 - 模型亮度调整,自定义着色器(CustomShader)完美解决模型太暗的问题

Cesium 实战 - 自定义视频标签展示视频 模型变暗问题以往通过光线解决问题模型变暗原理解决问题完整代码在线示例在 Cesium 项目中,添加模型是比较基础的功能,Cesium 支持 glTF(GBL) 格式。 在实际应用中,经常会遇到模型特别暗的情况,对比而言,其他三维环境添加是正常的…

[足式机器人]Part2 Dr. CAN学习笔记-Advanced控制理论 Ch04-5稳定性stability-李雅普诺夫Lyapunov

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-Advanced控制理论 Ch04-5稳定性stability-李雅普诺夫Lyapunov Stability in the sense of Lyapunov Assympototic Stability

怎么做微信秒活动_掀起购物狂潮,引爆品牌影响力

微信秒杀活动&#xff1a;掀起购物狂潮&#xff0c;引爆品牌影响力 在数字化时代&#xff0c;微信已经成为人们日常生活中不可或缺的一部分。作为中国最大的社交媒体平台&#xff0c;微信不仅为人们提供了便捷的通讯方式&#xff0c;还为商家提供了一个广阔的营销舞台。其中&a…

借助小redbook.item_get_video API:电商如何增强客户体验

随着电商市场的竞争日益激烈&#xff0c;客户体验成为了电商企业能否在市场中立足的关键因素之一。如何提高客户体验&#xff0c;增加用户黏性&#xff0c;成为电商企业亟待解决的问题。小redbook.item_get_video API作为一种强大的电商个性化营销工具&#xff0c;可以帮助电商…

基于SpringBoot的医护人员排班系统(代码+数据库+文档)

&#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目 希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;一、研究背景 1.1 研究背景 随…

使用OTB数据集需要注意的一个问题

一般网上下载的otb100数据集只要98给序列&#xff0c;这样就会导致在跑数据集的时候出现错误。 需要进行修改&#xff0c;下面链接里面的是我在网上收集到的一个修改后的数据集&#xff0c;有100个视频序列。 otb100提取码&#xff1a;z4tp 除了上面这一步&#xff0c;有的还需…

JC/T 2080-2011 木铝复合门窗检测

木铝复合门窗是指由铝合金型材和实木型材镶装构成的木铝复合型材制作的门窗。 JC/T 2080-2011 木铝复合门窗检测项目 测试项目 测试标准 表面质量 JC/T 2080 装配质量 JC/T 2080 木材含水率 GB/T 1931 甲醛释放量 GB 18580 启闭力 GB/T 9158 反复启闭性能 JG/T 1…

Visual Studio 2017 “无法查找或打开PDB文件“ 解决方法

运行的时候提示无法查找或打开PDB文件 解决办法&#xff08;注意&#xff1a;必须使用管理员身份运行VS&#xff09; 第一步 打开调试窗口的选项 第二步 调试——>常规——>勾选启用源服务器支持 它会弹出警告窗口&#xff0c;点“是”即可 第三步 调试——>符号——…

记录误删除docker中极狐gitlab容器恢复过程

如题一次误操作导致删除了docker中极狐gitlab容器恢复过程 情况说明 创建容器时&#xff0c;我是用的是极狐官网推荐安装的步骤&#xff0c;具体按照官网步骤走就行 sudo docker run --detach \--hostname gitlab.example.com \--publish 443:443 --publish 80:80 --publish …