当前位置:网站首页>从零开始C语言精讲篇6:结构体
从零开始C语言精讲篇6:结构体
2022-08-04 07:53:00 【高邮吴少】
提示:以下是本篇文章正文内容,下面案例可供参考
一、结构体类型的声明
1.1结构的基础知识
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量
我们现在已经学了char、int、short、float等等类型,但是这些类型都是孤立的。
如果你想描述一个复杂对象,比如你描述一本书,书有价格、书名、作者、出版号…
为了能够描述复杂对象,就有了结构体。
而因为复杂对象有着不同的属性,所以就有了不同的成员变量,不同的成员变量可能有不同类型
1.2结构的声明
struct tag
{
member-list;//成员列表
}variable-list;//变量列表,可以有,可以没有
例如描述一本书
struct Book
{
char name[20];
char author[15];
float price;
};//这里是有一个分号的,别忘记了
1.3结构成员的类型
结构的成员可以是标量、数组、指针,甚至是其他结构体。
二、结构体变量的定义及初始化
2.1结构体的变量的定义
#include<stdio.h>
struct Book
{
char name[20];
char author[15];
float price;
}b1,b2;//可以直接在结构体后面创建(一个或多个)变量
//这里的b1,b2是全局变量,在静态区
int main()
{
//struct Book 看做一个类型
struct Book b3;//也可以在main函数里创建变量
//这里的b3是局部变量,在栈区
return 0;
}
如果你嫌每次都写 “struct 结构体名” 来创建变量麻烦,可以使用typedef来对类型重命名
typedef struct Student
{
char name[20];
int age;
char id[20];
}Stu;//把类型struct Student重命名为Stu
//Stu后面不可以再跟变量了(重命名之后就不允许有变量列表了)
int main()
{
struct Student s1;
Stu s2;//s1和s2是一个类型
return 0;
}
2.2结构体的变量的初始化
struct Student
{
char name[20];
int age;
char id[20];
};
int main()
{
struct Student s1 = {
"张三",20,"2016486001"};
struct Student s2 = {
"李四",19,"2016486002"};
return 0;
}
可能会遇到嵌套定义的情况,那我们初始化也需要嵌套一下
struct M
{
int a;
char b;
};
struct N
{
struct M m;
float c;
};
int main()
{
struct N t = {
{
1,'x'},3.14 };
return 0;
}
声明是不会占空间的,定义则会占空间。
声明就相当于造房子的图纸,而定义则是把按图纸把房子建出来。
三、结构体成员的访问
结构体变量访问成员 结构变量的成员是通过点操作符(.)访问的。
点操作符接受两个操作数。例如:
struct M
{
int a;
char b;
};
struct N
{
struct M m;
float c;
};
int main()
{
struct N t = {
{
1,'x'},3.14 };
printf("%d\n", t.m.a);//可以再用一次点号“.”来对里层结构体成员访问
printf("%c\n", t.m.b);
printf("%f\n", t.c);
return 0;
}
但有时,我们拿到的不是结构体本身,而是结构体的地址。
这时,如果我们想访问结构体成员怎么办?
struct M
{
int a;
char b;
};
struct N
{
struct M m;
float c;
};
int main()
{
struct N t = {
{
1,'x'},3.14 };
//printf("%d\n", t.m.a);//也可以再用一次点号“.”来对里层结构体成员访问
//printf("%c\n", t.m.b);
//printf("%f\n", t.c);
struct N* pt = &t;//获取结构体t的地址
//法一
printf("%d %c %f\n",(*pt).m.a, (*pt).m.b, (*pt).c);
//*pt,对pt进行解引用,就得到了t,(*pt).m就相当于t.m
//法二
printf("%d %c %f\n", (pt->m).a, (pt->m).b,pt->c);
//pt是指向结构体t的指针,m是结构体t的成员变量
//我们规定一种写法pt->m就相当于t.m
return 0;
}
四、结构体传参
请看下面代码:
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;
}
上面的 print1 和 print2 函数哪个好些?
答案是:首选print2函数。 原因:
函数传参的时候,参数是需要压栈的。 如果传递一个结构体对象的时候,结构体过大,参数压栈
的的系统开销比较大,所以会导致性能的下降。
但是如果你传的参数仅仅是个地址,也就是4个字节(64位下8字节)啊,这个对性能来说友好很多
边栏推荐
- GBase 8c数据库集群中,怎么替换节点呢?比如设置A节点为gtm,换到B节点上。
- 力扣 剑指 Offer 04. 二维数组中的查找
- 安装GBase 8c数据库的时候,报错显示“Resource:gbase8c already in use”,这怎么处理呢?
- 中职网络安全竞赛B模块新题
- 金仓数据库 KDTS 迁移工具使用指南 (7. 部署常见问题)
- The sorting algorithm including selection, bubble, and insertion
- LLVM编译技术应用分析
- leetcode 22.8.1 二进制加法
- 智能健身动作识别:PP-TinyPose打造AI虚拟健身教练!
- (19)[系统调用]SSTD hook 阻止关闭
猜你喜欢
随机推荐
powershell和cmd对比
js异步变同步、同步变异步
电脑系统数据丢失了是什么原因?找回方法有哪些?
金仓数据库KingbaseES客户端编程接口指南-JDBC(8. JDBC 元数据处理)
【论文笔记】—低照度图像增强—Supervised—RetinexNet—2018-BMVC
智能健身动作识别:PP-TinyPose打造AI虚拟健身教练!
关于常用状态码4XX提示错误
实现加载驱动、得到数据库对象、关闭资源的代码复用,将代码提取到相应的工具包里边。优化程序
高等代数_证明_对称矩阵属于不同特征值的特征向量正交
【JS 逆向百例】某网站加速乐 Cookie 混淆逆向详解
Use of MotionLayout
【字符串】最小表示法
安装GBase 8c数据库集群时,报错误码:80000306,显示Dcs cluster not healthy。怎么处理错误呢?
金仓数据库KingbaseES客户端编程接口指南-JDBC(9. JDBC 读写分离)
(三)DDD上下文映射图——老师,我俩可是纯洁的男女关系!
redis---分布式锁存在的问题及解决方案(Redisson)
【我想要老婆】
解决循环依赖import cycle not allowed的最佳解决办法
MySQL group_concat()详解
data:image/jpg; base64 format data is converted to image