结构体——从零到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[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} };
        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;
}

分析两种传参方式

结构体指针传参更好一点。

因为函数传参的时候,参数是需要压栈的。如果传递一个结构体对象的时候,参数结构体过大,参数压栈的系统开销比较大,会导致性能下降。

压栈

内存分为三个区域:栈区,堆区,静态区。

栈区:局部变量、函数的形式参数
静态区:全局变量、静态变量
栈:栈是一种数据结构,它的结构是只有上层一个入口,

我们可以将栈类比为一口井,数据只能从井口进出,先进入“井”的数据在栈底,后面的数据依次往下压,如下图,入栈出栈方式,先进后出,后进先出。

传参的时候需要在栈区开辟内存,结构体整个数据传过去会占用太多的内存,指针传参只需要传地址,相对就要小得多。


 

猜你喜欢

转载自blog.csdn.net/m0_47646784/article/details/117957494
今日推荐