【C语言】结构体——相关知识详解

目录

一、结构体的基础知识

二、结构体的声明 与 各结构分析

(1)结构体各成分 分析

(2)结构体变量的声明

三、结构体的另一种正确写法 (尽量少用)

四、结构成员的类型

五、"嵌套结构体” 重要栗子: 重要规律

六、结构体传参: 以 创建打印功能的函数 为栗子

(1)普通传参: 结构体对象.成员变量(传参耗时耗空间)

(2)指针法的两种写法

结构体传参优先使用 指针传地址法:

(3)关于浮点数注意事项


一、结构体的基础知识

 结构体 :

               一组  不同类型元素  的集合,这些值称为   成员变量  ,每个成员可以是不同 类型 的变量(char , int , float , double.....); 

对  复杂对象   的描述   就会使用到:   结构体  

  • 人: 名字+电话+性别+身高
  • 书:书名+作者+定价+书号

另解:结构体差不多就是类 创建结构体变量相当于实例化

但 结构体内 不能定义函数 所以跟类还是有区别的

结构体和数组比较

数组:一组相同类型元素的集合


二、结构体的声明 与 各结构分析

(1)结构体各成分 分析
  1. struct : 结构体关键字
  2. Stu : 结构体标签___自定义的,具有意义
  3. p1 : 结构体变量
  4. s.name:中间这个点为  结构体 操作符
  5. {"zhansan","17", 99.9f} :这些 量时一一存放在 结构体对应的数组中的
  6. char namel20]; int age; double score; : 结构体成员变量
  7. struct st s 中的 struct st 意义:直观理解就是    类似于在 int a 中 int 是 变量a 的类型名   而 struct Stu s 中  struct stu 是 变量s  的类型名

温馨提示:千万别忘了 创建结构体 要加上   " ; " 

struct Stu
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct st s = {"zhansan","17", 99.9f};
	printf("名字:%s ,年龄:%s ,分数:%f", s.name, s.age, s.score);
	return 0;
}
(2)结构体变量的声明

结构体变量的声明:先创建好 结构体 struct Stu 后 使用


结构体的声明位置:   影响使用结构体范围,上面代码中的声明是放在 函数外部,使用范围 会比放在 函数内部 内部声明 更大,类似全局变量和局部变量的关系


三、结构体的另一种正确写法 (尽量少用)

  • p1和p2  是使用struct Stu 结构类型 创建的  2个  全局  结构体变量

  • 建议少用:在 使用时 需要创建 结构体变量 时,再创建 , 不必要提前 在此创建,就像 上一张代码图中 结构体变量 p1 在main函数的使用
struct Stu
{
	char name[20];
	int age;
	double score;
}p1, p2;

四、关于 结构体初始化

这里可以直接初始化

struct Stu

{

char name[20];

int age;

double score;

}p1= { "zhansan",  "18",  99.9 }, p2 { "lisi",  "19",  97 };

不按默认顺序来初始化:  通过 点 . 操作符 对变量进行引用,可以改变顺序

初始化默认按顺序一一对齐;也可以通过   .name = ..   这样不按默认顺序来

p1= { .age="18", .name="zhansan",  .score=99.9 }, p2 { "lisi",  "19",  97 }


五、结构成员的类型

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

(如下图在struct st中  将  struct Peo p   作为结构体成员)

(一层层剖析,一个属性之下可能有更细致的 属性划分)相当于一个 学生student 的内层还可以细化分析 这个学生作为 人person 的属性

struct Peo
{
	char name[20]; 
	char tele[12]; 
	char sex[5];
	int high;
};
	
struct st
{
	struct Peo p; 
	int num; 
	float f;
};

六、"嵌套结构体” 重要栗子: 重要规律

规律:
1、结构体1  中有 以结构体2 作为成员变量: 初始化结构体1  时 在结构体2 位置用大括号 { }

将结构体2初始化

例如:struct st s = {{"zhansan","15812305977","nan"}, "2300502113". 99.9f};
2、"连环"结构体成员访问: 

 引用结构体1 中的成员结构体2 的成员 模式--> (结构体变量s . 结构体变量p1 . p1的成员)

例如:s.p1.name,   s.p1.tele,   s.p1.sex

struct Peo//张三本人people的属性
{
	char name[20];
	char tele[12];
	char sex[5];//女 男 保密
};
struct st//张三的学生属性
{
	struct Peo p1;//在张三的学生student属性中,细化张三本人people的属性
	char xuenum[11];//学号
	float score;//分数
};	
int main()
{
	struct st s = {{"zhansan","15812305977","nan"}, "2300502113". 99.9f};
	printf("名字:%s ,电话:%s ,性别:%s ,学号:%s ,分数:%f",
             s.p1.name, s.p1.tele, s.p1.sex, s.xuenum, s.score);
	return 0;
}


七、结构体传参: 以 创建打印功能的函数 为栗子

温馨提示:代码较长 请自行拖动 代码块 下方的 拖条 查看全部代码

  • (1)普通传参: 结构体对象.成员变量(传参耗时耗空间)

    void print(struct st s)
    {
    	printf("名字:%s ,电话:%s ,性别:%s ,学号:%s ,分数:%f", s.p1.name, s.p1.tele, s.p1.sex, s.xuenum, s.score);
    }
    
  • (2)指针法的两种写法

模式:

1、 结构体指针->成员变量;

2、结构体指针解引用 . 成员变量

注意  : *ps =  s (两者完全等价)

  • void print(struct st* ps)
    {
    	printf("名字:%s ,电话:%s ,性别:%s ,学号:%s ,分数:%f", ps->p1.name, ps->p1.tele, ps->p1.sex,ps->xuenum, ps->score);
    }
    void print(struct st* ps)
    {
    	printf("名字:%s ,电话:%s ,性别:%s ,学号:%s ,分数:%f", (*ps).p1.name, 
                 (*ps).p1.tele, (*ps).p1.sex, (*ps).xuenum, (*ps).score);
    }
    

  • 结构体传参优先使用 指针传地址法:

相比于直接传参 更加省时省空间,效率更高


原因:如果传递一个结构体对象的时候,结构体过大,

参数压栈的的系统开销比较大,会导致性能的下降

  • (3)关于浮点数注意事项

打印出来的 数值 会不精确: 如 下图   分数 :99.900002

因为在内存中 不可以 精确的保存 浮点数

(关于浮点数在内存中如何存储在这里暂时不做分析)

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值