自定义类型1:struct (结构体类型)

前言:我们知道c语言有整型,浮点型等数据类型,而这些都是c语言自带的类型。在本章,将简单的介绍自定义类型——结构体。

结构体

1.结构的基础知识

结构体是一些值的集合,这些值称为成员变量。结构体的每个成员都可以是不同类型的值。比如可以是数组,指针,甚至是其它结构体。
因此,可以通过结构体完成对一个对象特征的简单描述。

2.结构体的声明

标准框架如下:要切记在大括号结尾后有一个;

在这里插入图片描述

以描述一个学生为例:

struct Student         // tag:标签,想要描述的对象是学生,tag写成student
{
    
                          //member-list:成员列表,描述对象的特征
	char name[20];     //姓名
	int age;           //年龄
	float weight;      //体重 等等,还有其它特征可以继续增加
}s1,s2,s3;            //variable-list:变量列表,具体的描述对象,如s1为学生1,s2为学生2,s3为学生3       

结构体变量的创建

创建结构体变量之前,要了解到底哪部分才是结构体类型,下面将通过类比的方式为大家解释:

int a;  //变量名是a,类型是整型
struct Student s1; //类比上面,类型是struct Student ,变量名是s1

是不是一目了然?

结构体变量的创建有多种形式:

#include<stdio.h>
struct Student 
{
    
    
	char name[20];
	int age;
	float weight;
}s1, s2;//全局变量
struct Student s3;
struct Student s4;
int main()
{
    
    
	//局部变量
	struct Student s5;
	struct Student s6;
	return 0;
}

上面的代码共创建了6个结构体变量:
s1,s2是在声明定义类型的同时创建的变量,且是全局变量
s3,s4,s5,s6是在声明定义类型后创建的变量,但s3,s4是全局变量,而s5,s6是局部变量

3.结构体的初始化(定义变量的同时赋初值)

在创建整型,浮点型等类型时我们会对其初始化,同样的,结构体类型我们也可以对其初始化。

按顺序初始化

严格按照结构体成员的顺序初始化操作:仍旧以一个学生为例且用数组赋初值来类比
我们知道:数组是一组相同类型元素的集合,而结构体是一些不同类型元素的集合,二者略有相似之处。

#include<stdio.h>
struct Stu     //创建学生结构体
{
    
    
	char name[20];
	int age;
	float weight;
}s1;           //结构体变量s1
int main()
{
    
    
	int arr[5] = {
    
     1,2,3,4,5 };
	//数组赋初值用一个大括号,且每个元素用,隔开    
	struct Stu s1 = {
    
    "zhangsan",20,70.3f};
	//与数组类似,赋初值也用一个大括号,每个元素用,隔开
	//需要注意的是;赋初值必须严格按照结构体成员的顺序
	//如上面的第一个为名字,第二个为年龄,第三个为体重
	return 0;
}

不按顺序初始化(定要掌握此方式)

可以按照自己想要的顺序对结构体初始化
首先得认识.(结构体成员访问操作符)
具体形式为.结构体成员

请看如下代码:

#include<stdio.h>
struct Stu
{
    
    
	char name[20];
	int age;
	float weight;
}s1;
int main()
{
    
    
	struct Stu s1 = {
    
     .weight=70.3f,.age=20,.name="zhangsan"};
	//逆序,先给体重赋初值,再给年龄,名字赋初值
	return 0;
}

在VS中使用时只要输入个.就有了成员选择,非常方便:

在这里插入图片描述

4.结构体成员的访问(打印结构体成员)

,打印结构体时需要访问结构体成员,而结构体成员的访问有2种形式:

结构体变量.结构体成员
结构体指针->结构体成员

请看示例代码:

#include<stdio.h>
struct Stu
{
    
    
	char name[20];
	int age;
	float weight;
}s1;
int main()
{
    
    
	struct Stu s1 = {
    
     .weight=70.3f,.age=20,.name="zhangsan"};
	struct Stu* s2 = &s1; //将结构体变量s1的地址存入s2中,s2是个结构体指针
	printf("%.2f %d %s\n", s1.weight, s1.age, s1.name); //结构体变量.结构体成员
	printf("%.2f %d %s\n", s2->weight, s2->age, s2->name);//结构体指针->结构体成员
	return 0;
}

打印结果如下:
在这里插入图片描述

可以看到上述两者打印的效果是一样的。

可能有读者会有疑问,上面的指针打印不是画蛇添足吗?我直接用第一种方式打印不就行了吗,还传个地址再打印干什么?
答: 上面的结构体指针打印只是作为示范的一个例子,事实上许多地方都要用到结构体指针打印,比如说结构体传参时传结构体地址的情况。

5.结构体传参

结构体传参可以选择传结构体变量,也可以选择传结构体地址。但推荐选择后者。
这是因为:函数传参的时候,参数是需要压栈的。如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销就比较大,会导致系统性能的降低。
比如结构体成员有个是int arr[1000],传结构体的地址的话只需要把首地址传过去就行了,大大减少了压栈开销。
总结:结构体传参时,要传结构体的地址

猜你喜欢

转载自blog.csdn.net/qq_73390155/article/details/129691851