结构体——从零到1,认识并使用结构体
Posted better,faster
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了结构体——从零到1,认识并使用结构体相关的知识,希望对你有一定的参考价值。
前言:众所周知,学习C语言,指针和结构体是两大重点,本篇带大家初识结构体。
目录
结构体的声明
结构体是什么,为什么要使用结构体?
答:结构体跟数组类似,是一些值的集合,不同的是,这些值的类型可以不同,这些值称为成员变量,结构的每个成员可以是不同类型的变量。
因为在日常生活中,有许多复杂的对象,这些对象不能简单的通过整形或者浮点型来定义,所以我们就需要用到结构体来定义这些复杂对象。
声明
如下,声明一个结构体,struct是结构体的关键词(必不可少),stu是结构体标签(自定义且可更改),struct stu合起来就是结构体的类型;
struct tag //struct是结构体关键字 tag是结构体标签 struct tag合起来就是结构体类型
{
member - list;//结构体成员列表
}variable - list;//结构体变量列表
学生成绩表例子:
struct stu //struct结构体关键字 stu结构体标签 struct stu结构体类型
{
//成员变量,可以是数值,指针,甚至是其他结构体
char name;//名字
int class;//年级
int grade;//成绩
int rank;//排名
}s1,s2,s3; //结构体变量 ,全局变量
匿名结构体
明显比较一般的结构体,匿名结构体缺少结构体标签,这种匿名结构体只能使用一次。
匿名结构体,只能用一次
struct //类型名
{
member-list;
}variable-list;
结构体变量的定义及初始化
定义变量
在定义变量前,先区分一下结构体和结构体变量
结构体是一种数据类型,是一种创建变量的模板,编译器不会为它分配内存空间,就像 int、float、char 这些关键字本身不占用内存一样;
结构体变量是需要分配内存来存储数据的。
(简单来举个“栗子”,结构体类型就像是建造房子的图纸,是不需要材料的,结构体变量是我们需要根据图纸去真实建造的房子,是需要的材料的)
定义变量有两种方式:
一种 是上面讲到的在结构体声明时在后面直接加上结构体变量,这种变量是全局变量,因为全局变量很容易被更改,所以不推荐使用;
struct stu //struct结构体关键字 stu结构体标签 struct stu结构体类型
{
//成员变量,可以是数值,指针,甚至是其他结构体char name;//名字
int class;//年级
int grade;//成绩
int rank;//排名
}s1,s2,s3; //结构体变量 ,全局变量
另一种是先声明结构体类型,之后再定义;(推荐这种)
struct stu s1; //先创建结构体类型,再定义结构体变量
初始化
在定义结构体变量时初始化。
直接上代码供大家参考
#include<stdio.h>
struct S
{
int a;
char b;
char c[20];
double d;
};
struct stu //struct结构体关键字 stu结构体标签 struct stu结构体类型
{
//成员变量,可以是数值,指针,甚至是其他结构体
char name[10];//名字
int class;//年级
int grade;//成绩
int rank;//排名
struct S s;
}s1, s2, s3; //结构体变量 ,全局变量
int main()
{
//初始化的时候,成员如果是结构体,需要用{ }括起来。
struct stu s4 = { "张三",5,100,1,{100,'a',"hello world",1.11} };
printf("%s\\n", s4.name);//s4.name是结构体访问
printf("%d\\n", s4.grade);
printf("%s\\n", s4.s.c);
return 0;
}
结构体成员的访问
结构体访问也有两种方式
①结构体变量访问,通过(.)访问,结构体变量名.结构体成员
②结构体指针访问,通过(->)访问,结构体指针->结构体成员
#include<stdio.h>
struct S
{
int a;
char b;
char c[20];
double d;
};
struct stu //struct结构体关键字 stu结构体标签 struct stu结构体类型
{
//成员变量,可以是数值,指针,甚至是其他结构体
char name;//名字
int class;//年级
int grade;//成绩
int rank;//排名
struct S s;
}s1,s2,s3; //结构体变量 ,全局变量
int main()
{
//初始化的时候,成员如果是结构体,需要用{ }括起来。
struct stu s4 = { "张三",5,100,1,{100,'a',"hello world",1.11} };
struct stu *p = &s4;
printf("%s\\n", s4.name);//通过结构体变量形式访问
printf("%d\\n", (*p).grade);//解引用指针,本质上还是结构体变量
printf("%s\\n", p->s.c);//结构体指针访问
return 0;
}
结构体传参
两种传参方式:
①结构体传参
②指针传参
#include<stdio.h>
struct S
{
int a;
char b;
char c[20];
double d;
};
struct stu //struct结构体关键字 stu结构体标签 struct stu结构体类型
{
//成员变量,可以是数值,指针,甚至是其他结构体
char name[10];//名字
int class;//年级
int grade;//成绩
int rank;//排名
struct S s;
}s1, s2, s3; //结构体变量 ,全局变量
void print1(struct stu s)
{
printf("%s\\n", s.name);
printf("%d\\n", s.grade);
}
void print2(struct stu* p)
{
printf("%s\\n", p->name);
printf("%d\\n", p->grade);
}
int main()
{
//初始化的时候,成员如果是结构体,需要用{ }括起来。
struct stu s4 = { "张三",5,100,1,{100,"a","hello world",1.11} };
print1(s4);
print2(&s4);
return 0;
}
分析两种传参方式
结构体指针传参更好一点。
因为函数传参的时候,参数是需要压栈的。如果传递一个结构体对象的时候,参数结构体过大,参数压栈的系统开销比较大,会导致性能下降。
压栈
内存分为三个区域:栈区,堆区,静态区。
栈区:局部变量、函数的形式参数
静态区:全局变量、静态变量
栈:栈是一种数据结构,它的结构是只有上层一个入口,
我们可以将栈类比为一口井,数据只能从井口进出,先进入“井”的数据在栈底,后面的数据依次往下压,如下图,入栈出栈方式,先进后出,后进先出。
传参的时候需要在栈区开辟内存,结构体整个数据传过去会占用太多的内存,指针传参只需要传地址,相对就要小得多。
以上是关于结构体——从零到1,认识并使用结构体的主要内容,如果未能解决你的问题,请参考以下文章