您现在的位置是:首页 >技术交流 >C语言深度解析--结构体网站首页技术交流

C语言深度解析--结构体

别是清欢 2024-07-14 18:01:02
简介C语言深度解析--结构体

目录

结构体类型的定义

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

结构体成员的访问

结构体传参


结构体是一种构造类型的数据结构,是一种或多种基本类型或构造类型的数据的集合。

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

结构体类型的定义

语法格式:

struct tag //struct:关键字,tag:类型名
{
	member-list;//成员列表

}variable-list;//变量列表

1.先定义结构体类型,再去定义结构体变量

struct 结构体类型名
{
	成员列表;
};

例如:

struct Stu
{
	char name[20];//名字
	int age;//年龄
	char sex[8];//性别
	float score;//分数
};//分号不能丢

有了结构体类型后,就可以用类型定义变量了。例如,struct Stu lucy,bob,lilei;定义了三个strcut Stu类型的变量,每个变量都有四个成员,分别是name,age,sex,score。

2.在定义结构体类型的时候顺便定义结构体变量,以后还可以定义结构体变量

struct 结构体类型名
{
	成员列表;
}结构体变量1,结构体变量2;

struct 结构体类型名 变量3,变量4;

例如:

struct Stu
{
	char name[20];//名字
	int age;//年龄
	char sex[8];//性别
	float score;//分数
}lucy,bob,lilei;//分号不能丢

struct stu xiaohong,xiaoming;

3.在定义结构体类型的时候,没有结构体类型名,顺便定义结构体变量

因为没有类型名,所以以后不能再定义相关类型的数据了

struct
{
	成员列表;
}结构体变量1,结构体变量2;

例如:

struct
{
	char name[20];//名字
	int age;//年龄
	char sex[8];//性别
	float score;//分数
}lucy,bob;//分号不能丢

以后没法再定义这个结构体类型的数据了,因为没有变量名。

4.最常用的方法:通常将一个结构体类型重新起个类型名,用新的类型名代替原先的类型

typedef struct Stu
{
	成员列表;
}结构体变量1,结构体变量2;

例如:

typedef struct Stu
{
	char name[20];//名字
	int age;//年龄
	char sex[8];//性别
	float score;//分数
}STU;

以后STU就相当于struct stu,STU lucy和struct stu lucy是等价的。

结构体成员的类型:

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

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

结构体变量是个变量,这个变量是若干个相同或不同数据构成的集合

注意:

  1. 在定义结构体变量之前首先得有结构体类型,然后再定义变量;
  2. 在定义结构体变量时,可以顺便给结构体变量赋初值,被称为结构体的初始化;
  3. 结构体变量初始化时,各个成员顺序初始化
struct Point
{
	int x;
	int y;
}p1 = {10,15};

struct Point p = {100,200};
struct Point
{
	int x;
	int y;
}p1 = { 10,15 };

struct Node
{
	int data;
	struct Point p;
	struct Node* next;
}n1 = { 10,{4,5},NULL };

struct Node n2 = { 20,{5,6},NULL };

结构体成员的访问

.:结构体变量.结构体成员

struct Point
{
	int x;
	int y;
}p1 = {10,15};

struct S
{
	char c;
	struct Point sp;
	double d;
	char arr[20];
};

void print1(struct S s)
{
	printf("%c
", s.c);
	printf("%d %d
", s.sp.x, s.sp.y);//结构体嵌套定义
	printf("%lf
", s.d);
	printf("%s
", s.arr);
}

int main()
{
	struct Point p = {100,200};

	struct S ss = { 'w',{100,20},5.5,"hello"};
	ss.c = 'b';
	ss.sp.x = 1000;
	ss.sp.y = 2000;
	ss.d = 3.14;
	strcpy(ss.arr,"world");//strcpy字符串拷贝

	print1(ss);

	return 0;
}

->:结构体指针->结构体成员

struct Point
{
	int x;
	int y;
}p1 = {10,15};

struct S
{
	char c;
	struct Point sp;
	double d;
	char arr[20];
};

void print2(struct S* s)
{
	printf("%c
", s->c);
	//结构体嵌套定义
	printf("%d %d
", s->sp.x, s->sp.y);
	printf("%lf
", s->d);
	printf("%s
", s->arr);
}

int main()
{
	struct Point p = {100,200};

	struct S ss = { 'w',{100,20},5.5,"hello"};
	ss.c = 'b';
	ss.sp.x = 1000;
	ss.sp.y = 2000;
	ss.d = 3.14;
	strcpy(ss.arr,"world");//strcpy字符串拷贝,不能使用等号=

	print2(&ss);

	return 0;
}

相同类型的结构体变量可以相互赋值

struct Stu
{
	int num;
	char name[20];
	char sex;
};

int main()
{
	struct Stu bob = {101,"bob",'m'};

	struct Stu lilei;

	lilei = bob;

	printf("%d %s %c
", lilei.num,lilei.name,lilei.sex);

	return 0;
}

结构体传参

struct S
{
	int data[10];
	int num;
};

//结构体传参
void print1(struct S ss)
{
	printf("%d
", ss.num);
}

//结构体地址传参
void print2(struct S* pss)
{
	printf("%d
", pss->num);
}

int main()
{
	struct S s = { {1,2,3,4}, 1000 };

	print1(s);  //传结构体
	print2(&s); //传结构体地址

	return 0;
}

上面的print1和print2函数哪个好些?

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

结论:结构体传参的时候,要传结构体的地址。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。