【C语言初阶】结构体

【C语言初阶】结构体


本章目标

学会声明一个结构体并能使用结构体定义变量,了解什么是结构体传参。

本章重点

1.结构体类型的声明

2.结构体的初始化

3.访问结构体成员

4.结构体传参


正文


一、结构体的声明

1 结构体的基础知识

结构体是一些值的集合,这些值称为成员变量。结构体的每个成员可以是不同类型的变量。

在C语言中,结构体类型是一种用户自定义的复合数据类型


2 结构体的声明

2.1 介绍

示例

struct tag
{
	member-list;
}variable-list;

说明

1 tag 表示结构名struct tag结构体类型名

2 member-list; 表示结构体成员列表variable-list; 表示结构体变量列表


2.2 声明示例

描述一个学生结构体类型

示例

typedef struct Stu
{
	char name[20];	//名字
	int age;		//年龄
	char sex[5];	//性别
	char id[20];	//学号
}Stu;

说明

1 typedef struct Stu {...}Stu; :将 struct Stu 重命名为 Stu ,这样就可以简化代码;

  在C语言中,struct 关键字是不能省略的,但可以通过 typedef 重命名简化写法


3 结构体成员类型

结构体的成员可以是:变量、数组、指针、其他结构体(结构体变量)


二、结构体变量的定义和初始化

1 结构体变量的定义和初始化

代码示例

#include<stdio.h>

int main()
{
	//结构体变量的定义和初始化

	struct Point //类型声明
	{
		int x;
		int y;
	}p1;		 //声明类型的同时定义变量p1
	struct Point p2;//定义结构体变量p2
	struct Point p3 = { 0, 0 };//初始化:在定义变量的同时赋予初始值


	struct Stu
	{
		char name[15];//名字
		int age;	  //年龄
	};
	struct Stu s = { "张三", 20 };//按成员顺序的初始化
	struct Stu s1 = { .age = 18, .name = "张三" };//指定成员顺序的初始化


	struct Node
	{
		int data;
		struct Point;
		struct Node* next;
	}n1 = { 10,{4,5}, NULL };//在结构体声明的同时创建变量并进行了初始化
	struct Node n2 = { 20,{5,6},NULL };//结构体嵌套初始化

	return 0;
}

解释说明

1 struct Stu s1 = { .age = 18, .name = "张三" };

  这种在结构体变量初始化时,可以不按照结构成员的顺序依次对成员进行赋值,此时就可以使用 . 操作符直接访问成员进行赋值


三、结构体成员的访问

1 结构体变量直接访问成员

结构体变量的成员是通过 . 操作符访问的。

代码示例

#include<stdio.h>

int main()
{
	//结构体变量访问成员
	
	//类型声明
	struct Stu
	{
		char name[20];
		int age;
	};
	//变量声明
	struct Stu s;
	strcpy(s.name, "张三");//使用.访问name成员
	s.age = 20;//使用.访问age

	return 0;
}

解释说明

1 声明变量的同时,会向内存申请空间

2 声明结构体变量:
声明结构体变量


2 结构体指针间接访问结构体变量的成员

可以通过指向结构体变量的结构体指针间接访问结构体变量的成员。

代码示例

#include<stdio.h>

struct Stu
{
	char name[20];
	int age;
};
void print(struct Stu* ps)
{
	printf("name = %s,age = %d\n", (*ps).name, (*ps).age);
	printf("name = %s,age = %d\n", ps->name, ps->age);//使用结构体指针访问指向对象的成员
}
int main()
{
	//结构体指针访问指向变量的成员

	struct Stu s = { .age = 20, .name = "张三" };
	print(&s);//结构体变量地址传参

	return 0;
}

解释说明

1 对结构体指针进行解引用 *ps 相当于是找到了其指向的结构体变量 s

(*ps).name  <-->  s.name
(*ps).age   <-->  s.age

2 ps->name, ps->age通过结构体指针间接访问结构变量的成员

3 void print(struct Stu* ps) 将形参设置为结构体指针,不会拷贝结构体变量的内容,减少了系统开销。


四、结构体传参

实参是结构体变量或者结构体变量的地址

代码示例

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

struct S
{
	int data[100];
	int num;
};
struct S s = { {1,2,3,4},1000 };//全局结构体变量

//结构体变量传参
void print1(struct S s)
{
	printf(" .num = %d\n", s.num);
}
//结构体变量地址传参
void print2(struct S* ps)
{
	printf("->num = %d\n", ps->num);
}
//传值调用
void Set_S1(struct S ss)
{
	//scanf("%d", ss.num);//error
	//ss.data = { 10,15,20 };//error,表达式必须是可以修改的左值
	ss.num = 200;
}
//传址调用
void Set_S2(struct S* pss)
{
	pss->num = 200;
}
int main()
{
	//结构体传参
	print1(s);	//传值调用
	print2(&s);	//传址调用

	struct S ss = { 0 };
	Set_S1(ss);	//传值调用
	Set_S2(&ss);//传址调用

	print1(ss);	//传值调用
	print2(&ss);//传址调用

	return 0;
}

解释说明

1 实参传递结构体变量到被调用函数处,形参只是拷贝了一份具有相同值的新的结构体变量。

2 实参传递的是结构体变量,形参会重新创建一份新的结构体变量的空间来接收传递的数值
  如果传递的结构体变量过大,那么形参拷贝所需的空间和时间的开销会变大

3 实参传递的是结构体指针,那么形参只需拷贝一份指针变量系统开销会减少,同时也提高了效率

4 选 print2 函数更好,因为在函数传参的时候,形参是要压栈的

  如果传递的一个结构体对象过大,参数压栈的系统开销就会较大,会导致性能的下降


结构体传参

结构体传参的时候,一般要传结构体对象的地址,也就是地址传参


总结:

  本节介绍了什么是结构体;给出了结构体变量的声明和初始化以及如何访问结构体成员;最后指出结构体在传参时,最好传递的是结构体的地址。


感谢您的阅读!如有任何错误,欢迎您的批评指正!

  • 29
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值