C语言学习笔记——结构体

一、什么是结构体?

在C语言中,结构体(struct)指的是一种数据结构,是C语言中聚合数据类型(aggregate data type)的一类。我们在程序里会创建很多变量,有时候我们需要用某个变量来描述一个人,而一个人身上的特点有很多,不止一个,如果只用一个特点来描述就显得不那么准确。所以我们要创建多个不同的变量来描述同一个人;而把这多个变量放在一起,起一个新名字就是结构体。

二、结构体的声明

在声明结构体时,必须列出它所包含的所有成员。这个列表包括每个成员的类型和名字。

struct student
{
	char name[20];
	char sex;
	int number;
}stu;

这里声明了一个类型为struct student的结构体,并且创建了一个结构体变量stu,它包括三个成员:一个字符型数组,一个字符型变量,一个整形变量。
这里的student和stu可以根据情况省略掉其中一个。如果删掉类型名,后续不能再次定义此类型的结构体,如果删掉变量名则后续可以重新定义变量。

struct student
{
	char name[20];
	char sex;
	int number;
}stu[20],*p;

这里在创建变量时创建了一个数组,数组的20个成员都是struct student类型的结构体,*p为可以指向该结构体类型的指针。

struct student1
{
	char name[20];
	char sex;
	int number;
}stu;
struct student2
{
	char name[20];
	char sex;
	int number;
}*p;

这里声明了两个结构体类型,其成员列表完全相同,但是其本质上是两个结构体,所以*p可以指向struct student2而不能指向struct student1;

三、创建结构体变量及初始化

struct student
{
	char name[20];
	char sex;
	int number;
};
int main()
{
	struct student stu = {"张三",'m',12};
	return 0;
}

这里创建了stu变量并进行初始化。也可以对任意成员重新赋值。

stu.number = 10;

四、结构体与数组

结构体和数组都是聚合数据类型,不同的是数组存放的是相同的数据类型,而结构体存放的是不同的数据类型,那么,这两种类型是否可以存放各自的类型呢?答案是可以的,数组可以存放数组,也可以存放结构体,同时,结构体可以存放数组,也可以存放其他结构体。如

struct student1
{
	char name[20];
	char sex;
	int number;
};
struct student2
{
	char name[20];
	char sex;
	int number;
	struct student1 stu;
};

那么,结构体是否能存放自身呢?
struct student1
{
char name[20];
char sex;
int number;
struct student1 stu;
};
答案是不可以的,因为在开辟空间时就会发现问题,当系统为结构成员struct student1 stu开辟空间时,发现他是另一个结构体,继而会对该结构体开辟空间而该结构体里又有结构体,陷入死循环,所以这是不成立的。
那如果我就是要一个可以存放自身结构体的元素呢?

struct student1
{
	char name[20];
	char sex;
	int number;
	struct student1 *p;
};

我们可以在结构体里定义一个指向自身类型的指针变量,而指针在64位平台下大小都是4字节,所以有效的避免了开辟空间的问题。
数组可以通过指针和下标访问元素,那结构体可以吗?
事实上结构体可以通过指针访问,但是不能通过下标访问。

五、结构体成员的访问

结构体访问方式有两种第一种直接通过变量名访问。

struct student
{
	char name[20];
	char sex;
	int number;
};
int main()
{
	struct student stu = { "张三",'m',12 };
	printf("%s %c %d\n",stu.name,stu.sex,stu.number);
}

这里用到了“.”操作符,先是结构体变量名然后“.”接着是成员名;就可以访问对应元素。

第二种就是通过指针访问。

struct student
{
	char name[20];
	char sex;
	int number;
}*p;
int main()
{
	struct student stu = { "张三",'m',12 };
	p = &stu;
	printf("%s %c %d\n", p->name,p->sex,p->number);
}

这里用到“->”操作符,用指针来访问结构体成员。

六、结构体传参

结构体是标量,适用于其他标量可以使用的任何场合,因此把结构体作为参数传递给一个函数是合法的,但这种做法往往并不适宜。因为结构体里面往往包含多个成员,而我们知道函数传参会发生值拷贝,如果该结构体成员过多,这样的做法肯定会导致程序运行效率降低。所以正确的做法是指针传递。

struct student
{
	char name[20];
	char sex;
	int number;
};

void fun(struct student *p)
{
	printf("%s %c %d\n", p->name, p->sex, p->number);
}
int main()
{
	struct student stu = { "张三",'m',12 };
	fun(&stu);
	return 0;
}

通过这样的方法就有效的避免了值拷贝问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值