【C语言】结构体(1)

大家好,我是苏貝,本篇博客带大家了解C语言的结构体(初阶),以后会出进阶的,如果大家觉得我写的不错的话,可以给我一个赞👍吗,感谢❤️

目录

  • ① WHO IS 结构体
  • ② 结构体的作用
  • ③ 结构体细节
    • 1. 结构体的声明
    • 2. 结构成员的类型
    • 3. 结构体变量的定义和初始化
    • 4. 结构体成员的访问
    • 5. 结构体作为函数参数

① WHO IS 结构体

结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量(这与数组不同,数组是一组相同类型元素的集合)


② 结构体的作用

1.首先,我们之前所学的int,char,double等类型都是内置类型,单个的它们无法描述一个复杂对象,比如描述一个人,那就可能要描述他的名字、性别、年龄等,这些显然是不能通过某个内置类型来很好的描述的,所以结构体应运而生

2.在实际项目中,结构体是大量存在的。研发人员常使用结构体来封装一些属性来组成新的类型。由于C语言内部程序比较简单,研发人员通常使用结构体创造新的“属性”,其目的是简化运算。

3.结构体在函数中的作用不是简便,最主要的作用就是封装。封装的好处就是可以再次利用。让使用者不必关心这个是什么,只要根据定义使用就可以了。


③ 结构体细节

1. 结构体的声明

首先,要使用结构体就必须先声明一个结构体类型。其中,struct是关键字,不能省略(若一定要省略也行,用typedef,下面会讲到);struct后接结构体名;struct+结构体名表示一个结构体类型,这与内置类型(如:int,double,long等)一样可以用来定义变量; member-list是成员变量的列表,包含不同的基本类型;variable-list是变量列表,可写可不写,写了该变量就是全局变量。

struct 结构体名
{member-list;//成员变量的列表
}variable-list;//变量列表

例如描述一个学生:

struct Stu
{char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号
};//分号不能丢

注意:
1.结构体类型{ }后面的 ;(分号)不能省略
2.struct后面也可没有结构体名,如下

struct
{int a;char b;
}s1;

这种形式是被C语言允许的,但是我们一般不去使用,因为这种结构体类型的声明只能定义一次变量,以后不能再定义,这就不方便该结构体以后的使用,因此不推荐写这种形式的结构体类型

上面有讲到,struct是关键字,不能省略,但如果用typedef就可以省略,这是怎么回事呢,让我们往下看

typedef即类型重定义,意思是给数据类型起一个新的名字。
所以下面的stu并非定义的变量,而是struct Stu的重命名,所以以后既可用struct Stu定义变量,也可用stu定义变量

typedef struct Stu
{char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号
}stu;

2. 结构成员的类型

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

struct B
{char ch[5];int age;
};
struct A
{char c;int arr[10];double* pd;struct B b;struct B* pb;
};

3. 结构体变量的定义和初始化

(1) 定义:可以在以下地方定义结构体变量(应该尽量少的使用全局变量)

1.结构体类型{ }的后面,;(分号)的前面(全局变量)
2.结构体类型的后面,main函数上面(全局变量)
3.main函数里面(局部变量)

struct B
{char ch[5];int age;
};
struct A
{char c;int arr[10];double* pd;
}a, b;//a,b是全局变量struct A d;//d是全局变量int main()
{struct A f;//f是局部变量return 0;
}

(2)初始化

1.按照顺序初始化
2.指定成员来初始化
3.单个初始化

struct A
{char m;int arr[10];double* pd;
}s1 = { .m = 'c',.arr = {1,2,3} }; //指定成员来初始化;int main()
{double d = 3.14;//1.按照顺序初始化struct A s3 = { 'q',{ 1,2,3,4,5 } ,&d };//2.指定成员来初始化struct A s4 = { .m = 'r',.pd = &d };//3.单个初始化struct A s5;s5.m = 'w';return 0;
}

4. 结构体成员的访问

1.结构体变量访问成员
结构变量的成员是通过点操作符(.)访问的。点操作符接受两个操作数
例如:

struct stu
{char name[20];int age;
};
int main()
{struct stu s1 = { "zhangsan",18 };//s1初始化printf("%s %d\n", s1.name, s1.age);//s1的成员访问return 0;
}

2.结构体指针访问指向变量的成员
有时候我们得到的不是一个结构体变量,而是指向一个结构体的指针。那该如何访问成员?
答案:使用 ->

struct Stu
{char name[20];int age;
};
void print(struct Stu* ps)
{//以下两种方式都可以printf("name = %s age = %d\n", (*ps).name, (*ps).age);//*ps=s//使用结构体指针访问指向对象的成员printf("name = %s age = %d\n", ps->name, ps->age);
}
int main()
{struct Stu s = { "zhangsan", 18 };//写一个函数打印s中的数据print(&s);//结构体地址传参return 0;
}

5. 结构体作为函数参数

直接上代码:

struct Stu
{char name[20];int age;
};void set(struct Stu* bs)
{bs->age = 18;//bs->name = "zhangsan";//err//因为name是数组名,在此情况下,数组名是首元素地址,为常量//因此如果想将name改变,可以:strcpy(bs->name, "zhangsan");
}void print1(struct Stu ps)
{printf("%s %d\n", ps.name, ps.age);
}void print2(struct Stu* ps)
{printf("%s %d\n", ps->name, ps->age);
}int main()
{struct Stu s = { 0 };//写一个函数打印s中的数据set(&s);//写一个函数打印s中的数据print1(s);print2(&s);return 0;
}

由上述代码可知:函数传参既可传值,也可传址。在结构体作为函数参数时,参数可以是结构体变量,也可以是结构体变量的地址。那两者谁更好呢?
答案是传结构体变量的地址。因为函数传参的时候,参数是需要压栈的。如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的下降 。简单来讲就是因为形参是实参的一份临时拷贝,若实参(即结构体)过大,那么形参也会较大,这样就会导致效率降低。但传结构体变量的地址的话,形参的大小只是4个或8个字节,效率较传结构体更高

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


好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️

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

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

相关文章

【学习日记】【FreeRTOS】手动任务切换详解

前言 本文是关于 FreeRTOS 中实现两个任务轮流切换并执行的代码详解。目前不支持优先级,仅实现两个任务轮流切换。 一、任务的自传 任务从生到死的过程究竟是怎么样的呢?(其实也没死),这个问题一直困扰着我&#xf…

LeetCode[164]最大间距

难度:Hard 题目: 给定一个无序的数组 nums,返回 数组在排序之后,相邻元素之间最大的差值 。如果数组元素个数小于 2,则返回 0 。 您必须编写一个在「线性时间」内运行并使用「线性额外空间」的算法。 示例 1: 输入: …

nacos 403错误

403错误 2023-08-12 18:04:55,418 [main] ERROR [com.alibaba.cloud.nacos.client.NacosPropertySourceBuilder:106] [trace,span,parent] - get data from Nacos error,dataId:gateway-server.yaml, com.alibaba.nacos.api.exception.NacosException: <html><body&…

CSDN 直播:腾讯云大数据 ES 结合 AI 大模型与向量检索的新一代云端检索分析引擎 8月-8号 19:00-20:30

本次沙龙围绕腾讯云大数据ES产品展开&#xff0c;重点介绍了腾讯云ES自研的存算分离技术&#xff0c;以及能与AI大模型和文本搜索深度结合的高性能向量检索能力。同时&#xff0c;本次沙龙还将为我们全方位介绍腾讯云ES重磅推出的Elasticsearch Serverless服务&#xff0c;期待…

【BASH】回顾与知识点梳理(十六)

【BASH】回顾与知识点梳理 十六 十六. 十二至十五章知识点总结及练习16.1 总结16.2 练习16.3 简答题 该系列目录 --> 【BASH】回顾与知识点梳理&#xff08;目录&#xff09; 十六. 十二至十五章知识点总结及练习 16.1 总结 绝对路径&#xff1a;『一定由根目录 / 写起』…

permission denied while trying to connect to the Docker daemon socket 错误

安装 docker 执行错误如下&#xff1a; $ docker pspermission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get “http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json”: dial unix /var/run/docker.sock: connect:…

基于亚奈奎斯特采样和SOMP算法的平板脉冲响应空间插值matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ...................................................................... %fine regular gr…

本地构建包含java和maven的镜像

目录 1.前提条件 2.下载 2.1.创建Dockerfile 3.构建镜像 参考文章 1.前提条件 本地环境需要的系统和软件 win10 Docker Desktop Powershell 图1 Win10安装Docker后&#xff0c;直接在Powershell使用Docker命令 有些Developer不习惯win10系统&#xff0c;却想要使用Lin…

C++初阶——运算符重载

前言&#xff1a;前面介绍过了函数重载&#xff0c;C为了增强代码的可读性引入了运算符重载的概念&#xff0c;运算符重载是具有特殊函数名的函数&#xff0c;也具有其返回值类型。 下文博主将通过自定义类型日期类的比较引出运算符重载&#xff0c;以此凸显运算符重载提高代码…

Arraylist集合

保存数据会经常使用到数组&#xff0c;但数组存在以下几个缺陷: 长度固定&#xff1b;保存的必须为同一类型的元素&#xff0c;&#xff08;基本数据类型&#xff0c;或引用数据类型&#xff09;&#xff1b;使用数组进行增加元素的步骤比较麻烦&#xff1b; 这个时候就需要用一…

安卓:网络框架okhttp

目录 一、okhttp介绍 1. OkHttpClient类&#xff1a; 常用方法&#xff1a; 2. Request类&#xff1a; 常用方法&#xff1a; 3. Response类&#xff1a; 常用方法&#xff1a; 4. Call类&#xff1a; 常用方法&#xff1a; 5. Interceptor接口&#xff1a; 常用方法&…

在生产环境中部署Elasticsearch:最佳实践和故障排除技巧———索引与数据上传(二)

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

MySQL语句总和之MySQL数据库与表结构操作

目录 1、启动MySQL服务 2、进入MySQL数据库 3、退出数据库 4、查看MySQL数据库所有库 5、创建、删除、使用、查看所处库操作 6、创建表 7、查看表结构 8、表结构操作 1&#xff09;修改表名 2&#xff09;自增长操作 3)添加一个address字段放在Phone字段后面 4)添加…

python爬虫3:requests库-案例1

python爬虫3&#xff1a;requests库-案例1 前言 ​ python实现网络爬虫非常简单&#xff0c;只需要掌握一定的基础知识和一定的库使用技巧即可。本系列目标旨在梳理相关知识点&#xff0c;方便以后复习。 申明 ​ 本系列所涉及的代码仅用于个人研究与讨论&#xff0c;并不会对网…

SQLAlchemy 入门:Python 中的 SQL 工具包和 ORM

SQLAlchemy 是 Python 中一款非常流行的数据库工具包&#xff0c;它对底层的数据库操作提供了高层次的抽象。在本篇文章中&#xff0c;我们将介绍 SQLAlchemy 的两个主要组成部分&#xff1a;SQL 工具包 (SQL Toolkit) 和对象关系映射器 (Object-Relational Mapper, ORM) 的基本…

linux初学者小命令

linux初学者小命令 一.在正式学习linux命令之前需要先认识一下linux环境中命令是如何被执行的shell是一个属于linux内核的软件&#xff0c;在系统启动后加载进RAM(内存)内&#xff0c;每个用户通过终端登录系统后&#xff0c;就会运行。负责不间断的接收用户的输入&#xff0c…

分布式系统监控zabbix安装部署及使用

目录 一.zabbix监控 1.什么是zabbix 2.zabbix功能 3.zabbix的构成 4.zabbix的3种架构 4.1 C/S架构 4.2 分布式架构&#xff1a;zabbix-proxy-client架构 4.3 master-node-client架构 6.zabbix监控模式 二.zabbix部署及图形化页面显示设置(192.168.158.25) 1.zabbix安装…

uniapp 用 hbuilderx下载 uview

uView2.0重磅发布&#xff0c;利剑出鞘&#xff0c;一统江湖 - DCloud 插件市场 1.uniapp官网下载资源 2按下载 3.官网安装文档 要按 这个红色圈错了 然后看他的配置步骤 第四easycom 就可以 不用配了

第二课-一键安装SD-Stable Diffusion 教程

前言 看完这篇文章并跟着操作,就可以在本地开始 SD 绘图了。 理论上来说,这篇课程结束,想要画什么图都可以画了。 启动器介绍 SD 是开源的,可以在 github 上找到。但直接下载源码安装,非常费劲,而且因为国内外差异,就是我这样的秃头程序员也难以应对。 所以,我们改…