C语言 结构体入门

news2024/11/15 17:47:01

目录

一、定义和使用结构体变量

1.1创建结构体类型

1.2定义结构体类型变量

1.先声明结构体类型,在定义该类型的变量

2.在声明类型的同时定义

1.3结构体成员的类型

1.4结构体变量的初始化和引用

1.5结构体的访问 

二、结构体传参


前言:C语言提供了一些由系统已定义好的数据类型,如:int,float,char等,用户可以在程序中用它们定义变量,解决一般的问题,但我们要处理的问题往往比较复杂,只有系统提供的类型还不能满足应用的需求,C语言允许用户根据自己建立一些数据类型,并用它来定义变量。

一、定义和使用结构体变量

1.1创建结构体类型

        我们在描述一个学生时,学生的名字、性别、年龄、地址等,都是属于同一个学生的。如果将name,sex,age和addr分别定义为互相独立的简单变量,难以反映他们之间的内在联系,人们希望八这些数据组成一个组合数据,所以就有结构体来描述复杂类型。建立一个结构体类型,例如:

struct Student
{
	int num;			//学号为整形
	char name[20];		//名字为字符串
	char sex[5];		//性别为字符串
	int age;			//年龄为整形
};						//最后有一个分号

声明一个结构体类型的一般形式

struct      结构体名

        {

        //成员变量,是用来描述结构体对象的相关属性

        成员列表

        };

注意:结构体类型的名字是由一个关键字struct和结构体名组合而成的(例如:struct  Student)。结构体名是由用户指定的,又称“结构体标记”,以区别于其他结构体类型。上面结构体中的Student就是结构体名。

           花括号内是该结构体所包含的子项,称为结构体成员。上例中的num,name,age,sex等都是成员。

1.2定义结构体类型变量

        前面只是建立了一个结构体类型,它相当于一个模型,并没有定义变量,其中没有具体的数据,系统也不会为之分配单元。相当于设计好图纸,但并没有建好房屋。为了能在程序中使用结构体类型的数据,应当定义结构体类型的变量,并在其中存放具体的数据。可以采取以下2种方法来定义结构体类型变量。

1.先声明结构体类型,在定义该类型的变量

struct Student
{
	int num;			
	char name[20];		
	char sex[5];		
	int age;			
};


int main()
{
    struct Student s1;
    struct Student s2;
    return;
}

2.在声明类型的同时定义

struct Student
{
	int num;			
	char name[20];		
	char sex[5];		
	int age;			
}s1,s2;

这种方法定义的一般形式为

struct   结构体名

{

        成员列表;

}变量名列表;

 注意:声明类型和定义变量放在一起进行,能直接看到结构体的结构,比较直观,在写小程序时用此方法比较方便,但在写大程序时,往往要求对类型的声明和对变量的定义分别放在不同的地方,以使程序结构清晰,便于维护。

 说明:

1。结构体类型和结构体变量是不同的概念。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运算。在编译时,对类型是不分配空间的,只对变量分配空间。

2.结构体类型中的成员名可以与程序中的变量名相同,但二者不代表同一对象。例如:程序中可以另定义一个num,它与struct Student中的num不同,互不干扰。

下面我们通过图来加强对结构体类型和结构体变量的理解

1.3结构体成员的类型

结构的成员可以是标量、数组、指针,甚至是其他结构体。例如:

struct Date
{
	int month;
	int day;
	int year;
};


struct Student
{
	int num;			
	char name[20];		
	char sex[5];		
	int age;	
	struct Date birthday;		//成员birthday属于struct Date类型
};	

1.4结构体变量的初始化和引用

        在定义结构体变量时,可以对它进行初始,即赋予初值。然后可以引用这个变量,例如:

struct Student
{
	int num;			
	char name[20];		
	char sex[5];		
	int age;	
};						


int main()
{
	struct Student s1 = { 114202,"张三","男",18 };
	printf("%d %s %s %d\n", s1.num, s1.name, s1.sex, s1.age);
	return 0;
}

(1)在定义结构体变量时可以对它的成员初始化。初始化列表是用花括号括起来的一些常量,这些常量依次赋给结构体变量中的各成员。 

注意:是对结构体变量初始化,而不是对结构体类型初始化。

(2)可以引用结构体变量中成员的值,引用的方法为

                结构体变量名 . 成员名 

 例如:已定义了s1为Student类型的结构体变量,则s1.num表示s1变量中的num成员,在程序中可以这样赋值,例如:

                s1.num=114202;

“.”是成员运算符,它在所有的运算符中优先级最高,因此可以把s1.num作为一个整体来看待,相当于一个变量。

注意:不能企图通过输出结构体变量名来达到输出结构体变量的所有成员。

(3)若成员本身又属于一个结构体类型,则要用若干个成员运算符,一级一级的找到最低一级的成员。只能对低级的成员进行赋值或存取以及运算。

student.num                (结构体变量student中的成员num)
student.brithday.month    (结构体变量student中的成员brithday中的成员month)

(4)对结构体变量的成员可以像普通变量一样进行各种运算。

student2.score=student1.score;                         (赋值运算)

sum=student1.score+student2.score;                (加法运算) 

student1.age++;                                                 (自加运算)

(5)同类的结构体变量可以相互赋值,如:

student1=student2

(6)可以引用结构体变量成员的地址,也可以引用结构体变量的地址。例如:

scanf("%d",&student1.num);
printf("%o",&student1);        //输出结构体变量student1的起始地址




//不能整体读入结构体变量/例如:
scanf("%d %d %s",&student1);

 说明:结构体变量的的地址主要用作函数传参,传递结构体变量的地址。

1.5结构体的访问 

p指向一个结构体变量stu,

  1. stu.成员名
  2. (*p).成员名
  3. p->成员名

二、结构体传参

struct S
{
     int data[1000];
     int num;
};

struct S s = {{1,2,3,4}, 1000};


//结构体传参
void print1(struct S s)
{
     printf("%d\n", s.num);
}


//结构体地址传参
void print2(struct S* ps)
{
     printf("%d\n", ps->num);
}


int main()
{
     print1(s);  //传结构体
     print2(&s); //传地址
     return 0;
}

print2函数更好

原因:函数传参的时候,参数是需要压栈的。

如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的 下降。

结论:结构体传参的时候,要传结构体的地址。 

本次的内容到这里就结束啦。希望大家阅读完可以有所收获,同时也感谢各位读者的支持。文章有问题可以在评论区留言,博主一定认真认真修改,以后写出更好的文章。 

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

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

相关文章

直流稳压电源的几个性能指标

目录 电压调整率:输入电压在允许的范围内变化时,输出电压稳定性。 电流调整率:负载电流在允许的范围内变化时,输出电压稳定性 输出纹波电压:额定负载时,输出电压的振幅 电源效率:额定负载时&…

07-抚摸抽象边界:Golang 接口的多彩展现

📃个人主页:个人主页 🔥系列专栏:Golang基础 💬Go(又称Golang)是由Google开发的开源编程语言。它结合了静态类型的安全性和动态语言的灵活性,拥有高效的并发编程能力和简洁的语法。G…

Python 操作 Excel 全攻略 | 包括读取、写入、表格操作、图像输出和字体设置

文章目录 前言Python 操作 Excel 教程1. Excel 文件的读取与写入2. Excel 表格的操作2.1 插入和删除行和列2.2 遍历表格中的单元格并修改值 3. 图像的输出3.1 输出柱状图 4. 字体的设置4.1 设置单元格的字体大小和颜色4.2 设置单元格的加粗和斜体4.3 设置单元格的边框和填充颜色…

android实现无root获取其它应用data私有数据

实现原理就是反编译app的AndroidManifest文件,注意是反编译应用的资源文件,而不是编译整个app,这个操作不需要动应用的dex,难度上要容易得多。解码资源文件要用到一些工具,android下推荐ARSCLib。接下来是对目标应用重…

04_Linux设备树DTB文件OF函数

目录 创建小型模板设备树 添加cpus节点 添加soc节点 添加ocram节点 添加aips1、aips2和aips3这三个子节点 添加eespil、usbotg1和rngb这三个外设控制器节点 设备树在系统中的体现 根节点“/”各个属性 根节点“/”各子节点 特殊节点 aliases子节点 chosen子节点 L…

转专业之我见

写在前面 如果你点进来看这篇文章,说明你的至少有想转专业的想法甚至心里是趋向于转专业的。 但是或许是因为学校只有一次转专业的机会或者有别的原因让你犹豫不决,那么你首先要明确你为什么想要转专业,是因为本专业是天坑专业,…

UI 自动化测试 —— selenium的简单介绍和使用

selenium 是 web 应用中基于 UI 的自动化测试框架,支持多平台、多浏览器、多语言。 提到 UI 自动化就先了解什么是自动化测试? 目录 1. 自动化测试 2. UI 自动化 2.1 UI 自动化的特点 2.2 UI 自动化测试的优缺点 2.3 UI 自动化测试的使用对象 2.4…

PPG信号和ECG信号检测血管年龄

PAT 通常用作动脉硬度的间接测量值或心血管健康的指标。它与各种生理和病理状况有关,例如高血压、动脉硬化和内皮功能障碍。 通过脉搏到达时间进行测量,简单来说就是 先从脉冲传输时间 PPG 数据集中提取数据,提取此数据集中每个对象的脉冲到…

【Python从入门到进阶】24、urllib获取网站电影排行

接上篇《23、urllib使用post请求百度翻译》 上一篇我们讲解了如何使用urllib实现百度翻译的效果。本篇我们来讲解如何使用urllib抓取某某电影排行榜信息。 一、某某电影介绍 1、某某电影网站 某某电影成立于2005年,最初只是一个小型的电影社区,但随着…

【备战秋招】每日一题:2023.05-B卷-华为OD机试 - 报文重排序

为了更好的阅读体检,可以查看我的算法学习博客报文重排序 题目描述 对报文进行重传和重排序是常用的可靠性机制,重传缓中区内有一定数量的子报文,每个子报文在原始报文中的顺序已知,现在需要恢复出原始报文。 输入描述 输入第…

改进YOLOv8 | 优化器篇 | YOLOv8 引入谷歌 Lion 优化器

论文地址:https://arxiv.org/pdf/2302.06675.pdf 代码地址:https://github.com/google/automl/tree/master/lion 我们提出了一种将算法发现作为程序搜索的方法,并将其应用于发现用于深度神经网络训练的优化算法。我们利用高效的搜索技术来探索一个无限且稀疏的程序空间。为了…

【SCADA】测试用KingIOServer采集杰控OPC DA服务器数据

Hello,大家好,我是雷工! 现场做数据采集时经常会遇到需要通过OPC采集数据的情况,本篇测试KingIOServer采集北京杰控组态软件的OPCDA服务器数据。 以下为测试记录过程。 一、KingIOServer的OPC DA数据采集介绍 KingIOServer可以作…

Vue中如何进行分布式日志管理与日志分析

Vue中如何进行分布式日志管理与日志分析 在现代应用程序中,日志是一项重要的功能,用于帮助开发人员和运维人员了解应用程序的行为并进行故障排除。随着应用程序的规模和复杂性的增加,日志管理和分析变得越来越困难。本文将介绍如何在Vue应用…

JSON对象花样进阶

JSON 对象使用在大括号{ }中书写。 对象可以包含多个 key/value(键/值)对。 key 必须是字符串,value 可以是合法的 JSON 数据类型(字符串, 数字, 对象, 数组, 布尔值或 null)。 key 和 value 中使用冒号(:)分割。 每个…

Postman接口自动化之postman脚本编写

这是之前搞的接口自动化方案,已经在业务测试中实现了使用postman编写接口脚本,通过GitHubJenkinsemail html report实现了接口自动化,现在分块整理一下。 postman脚本编写 1、创建集合 和 目录: 一条业务线下的接口可以放到一个…

ACL2023 | 大模型如何快速构建指令遵循数据集?self-instruct:用175条种子数据追上InstructGPT001效果

一、概述 title:SELF-INSTRUCT: Aligning Language Models with Self-Generated Instructions 论文地址:https://arxiv.org/abs/2212.10560 代码:GitHub - yizhongw/self-instruct: Aligning pretrained language models with instruction…

chatgpt赋能python:Python怎么输出Unicode值

Python怎么输出Unicode值 Python 是一种高级编程语言,因其简单易学和快速开发已成为许多开发者的首选。Python 可以输出多种数据类型,包括字符串和数字。 在许多情况下,输出 Unicode 值是必需的,本文将介绍在 Python 中如何输出 …

shardingsphere第二课-shardingsphere-jdbc的基本使用及各种分片策略

第一章介绍 一、ShardingJDBC客户端分库分表 ShardingSphere-JDBC 定位为轻量级 Java 框架,在 Java 的 JDBC 层提供的额外服务。 它使用客户端直连数据库,以 jar 包形式提供服务,无需额外部署和依赖,可理解为增强版的 JDBC 驱动…

chatgpt赋能python:Python中如何输入一个列表

Python中如何输入一个列表 输入一个列表是Python编程的基本任务之一。列表可以看做是一种序列,其中包含多个元素,用逗号隔开,并用方括号括起来。在Python中,列表是一种非常常见的数据类型,常用于存储和处理一系列相关…

断言操作符介绍

目录 1.延时操作符(##) 1.1 ##m 1.2 ##[m:n] 2.蕴含操作符(|>,|->) 2.1 |>操作符 2.2 |->操作符 3 重复操作符 ([*m][->m][m]) 3.1 连续重复操作符([*m][*m:n]) 3.2 跟随重复操作…