当前位置:网站首页>从零开始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字节)啊,这个对性能来说友好很多
边栏推荐
- 金仓数据库KingbaseES客户端编程接口指南-JDBC(6. JDBC 大对象数据处理)
- 【剑指Offer】二分法例题
- FCN - the originator of semantic segmentation (based on tf-Kersa reproduction code)
- 金仓数据库 KDTS 迁移工具使用指南 (5. SHELL版使用说明)
- 七夕情人节:中英文祝福短信送给你
- 分布式计算实验1 负载均衡
- 两日总结七
- 字节跳动岗位薪酬体系曝光,看完我真的酸了...
- 【我想要老婆】
- Distributed Computing Experiment 4 Random Signal Analysis System
猜你喜欢

FCN - the originator of semantic segmentation (based on tf-Kersa reproduction code)

JNI学习1.环境配置与简单函数实现

QT + msvc2017编译器

一天学会JDBC03:Statement的用法

七牛云上传图片和本地上传

【论文笔记】—低照度图像增强—Supervised—RetinexNet—2018-BMVC

Distributed Computing Experiment 1 Load Balancing

分布式计算实验1 负载均衡

金仓数据库 KDTS 迁移工具使用指南 (5. SHELL版使用说明)

unity2D横版游戏教程7-敌人AI死亡效果
随机推荐
MySQL 8.0.29 详细安装(windows zip版)
图的基本概念
力扣 剑指 Offer 04. 二维数组中的查找
金仓数据库的单节点如何转集群?
最近的一些杂感-20220731
LLVM编译技术应用分析
虚拟机没有USB网卡选项怎么解决
「PHP基础知识」转换数据类型
IntelliJ新建一个类或者包的快捷键是什么?
学校申请链接
金仓数据库 KDTS 迁移工具使用指南 (6. 注意事项)
leetcode 22.8.1 二进制加法
中职网络安全竞赛C模块MS17-010批量扫描
25.时间序列预测实战
FCN - the originator of semantic segmentation (based on tf-Kersa reproduction code)
【虚幻引擎UE】UE5基于Gltf加载插件实现gltf格式骨骼动画在线/本地导入和切换
Typora_Markdown_图片标题(题注)
全国职业院校技能大赛网络安全竞赛之应急响应
金仓数据库 KDTS 迁移工具使用指南 (5. SHELL版使用说明)
The national vocational skills contest competition of network security emergency response