当前位置:网站首页>从零开始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字节)啊,这个对性能来说友好很多
边栏推荐
- 金仓数据库 KDTS 迁移工具使用指南 (6. 注意事项)
- 此时已莺飞草长,愿世间美好与你环环相扣
- 给Unity Behavior Designer(Unity行为树) 的Can See Object 画圆锥辅助图
- LLVM编译技术应用分析
- int *p = &a、p = &a、*p = a的正确理解
- 创建数据库报错--MySQL server is running with the --super-read-only option
- Use of MotionLayout
- 【UE虚幻引擎】UE5三步骤实现AI漫游与对话行为
- unity2D横版游戏教程7-敌人AI死亡效果
- 全国职业院校技能大赛网络安全竞赛之应急响应
猜你喜欢
高等代数_证明_两个矩阵乘积为0,则两个矩阵的秩之和小于等于n
unittest使用简述
JNI学习1.环境配置与简单函数实现
LeetCode 135. 分发糖果
Distributed Computing Experiment 3 PRC-based Book Information Management System
经典动态规划问题的递归实现方法——LeetCode39 组合总和
inject() can only be used inside setup() or functional components.
设计信息录入界面,完成人员基本信息的录入工作,
两日总结四
给Unity Behavior Designer(Unity行为树) 的Can See Object 画圆锥辅助图
随机推荐
开发小技巧 navicate如何点击单元格显示全部的文本内容或通过图像查看内容
TCP协议详解
金仓数据库KingbaseES客户端编程接口指南-JDBC(9. JDBC 读写分离)
IDEA引入类报错:“The file size (2.59 MB) exceeds the configured limit (2.56MB)
data:image/jpg; base64 format data is converted to image
高等代数_证明_对称矩阵一定能够相似对角化
24.循环神经网络RNN
【我想要老婆】
(三)DDD上下文映射图——老师,我俩可是纯洁的男女关系!
ContrstrainLayout的动画之ConstraintSet
金仓数据库的单节点如何转集群?
安装GBase 8c数据库集群时,报错误码:80000306,显示Dcs cluster not healthy。怎么处理错误呢?
学校申请链接
【JS 逆向百例】某网站加速乐 Cookie 混淆逆向详解
两日总结八
powershell和cmd对比
2022的七夕,奉上7个精美的表白代码,同时教大家改源码快速自用
LeetCode 97. 交错字符串
Mysql insert on duplicate key 死锁问题定位与解决
此时已莺飞草长,愿世间美好与你环环相扣