今天我们就一起来了解一下C语言中结构体有关的知识吧!
结构是什么?
结构是一些值的集合,这些值被称为成员变量,结构的每个成员可以是不同类型的变量。
我们之前也学习过数组,这里我们来区分一下结构体和数组的概念
数组是一组相同类型元素的集合。
结构体是一组不同类型元素的集合。
我们可以了解到,结构体和数组都是元素的集合,区别是,结构体是不同类型的元素的集合。这里我们发现,结构体面向的对象是复杂的。
结构体的声明
struct stu
{
char name[20];
int stu_num[20];
}s1;
在这个代码中,我们声明了结构体stu,stu是标签名,可以理解为结构体的名称,这个名称并不是固定不变的,可以随我们心意和具体内容来设置,比如这串代码中,我们想设置一个学生的学号和姓名,我们就可以将结构体命名为stu(student)。
当然结构体括号中的就是结构体的成员列表了,我们想表示姓名和学号,我们就定义两个数组来存放我们将要表示的内容,姓名需要定义char类型的,我们设置为name,学号这里我们定义为stu_num,因为学号是数字,所以我们定义类型为int。
结构体成员的类型
这里我们需要了解到结构体成员的类型:可以是标量,数组,指针,甚至可以是其他的结构体(后面举例说明)。
结构体变量的定义和初始化
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//结构体变量的定义
struct stu
{
char name[20];
int stu_num;
char sex[10];
float score;
};
int main()
{
//结构体变量的初始化
struct stu s1 = { "zhangsan",0001,"nan",59.5f };
struct stu s2 = { "wangwu",0003,"nv",60.2f };
printf("%s %d %s %f", s1.name, s1.stu_num, s1.sex, s1.score);
return 0;
}
在这个代码中,我们定义了结构体stu,结构体面向的对象是学生,结构体的成员列表中包含了结构体对象stu的姓名,学号,性别,分数。这是我们对结构体stu的定义,告诉别人我们定义的结构体stu中都有什么成员。
我们之前说结构体面向的对象是复杂的,这里就是他复杂的地方,面向一个学生对象可以有四个或者更多的结构体成员,而数组的话就只有一组相同类型的元素。
在后面的主函数中,我们定义结构体对象的结构体变量,并且将它初始化,这里初始化就是对我们的结构体变量的各个成员进行填充,例如在代码中我们给结构体变量s1赋初值为:"zhangsan",0001,"nan",59.6f 。
之后我们打印一下结构体变量s1的值,看看有没有初始化成功,结果显示无误:
结构体成员的访问
其实我们刚刚已经访问过结构体成员了,我们使用了(.)操作符,这是结构体成员访问的一种方式。
代码解释
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
struct X
{
int a;
char c;
};
struct Y
{
double d;
struct X x;
float f;
};
void print1(struct Y yn)
{
printf("%lf %d %c %f\n", yn.d, yn.x.a, yn.x.c, yn.f);
}
void print2(struct Y* ym)
{
printf("%lf %d %c %f\n", (*ym).d, (*ym).x.a, (*ym).x.c, (*ym).f);
printf("%lf %d %c %f\n", ym->d, ym->x.a, ym->x.c, ym->f);
}
int main()
{
struct Y y = { 5.2,{13,'b'},1.314f};
//传值调用
print1(y);
//传址调用
print2(&y);
return 0;
}
因为是给大家解释所以这里的结构体变量名称就尽量简单方便大家理解。
解析
首先我们定义结构体X,里面存放一个整型变量a和字符型变量c,再定义一个结构体Y,里面存放了一个双精度浮点型的d,结构体X和一个单精度浮点型的f。
定义好我们的结构体之后我们对结构体变量y进行初始化,赋初值为: 5.2,{13,'b'},1.314f,这里有大家需要注意的点哦,我们发现在结构体Y的内部还有一个结构体X,那么这个时候我们就需要再来一个{}用来存放在结构体Y中结构体X的值了。
传值调用
我们通过函数调用的方式来实现结构体的传值调用,我们定义函数print1,传值调用我们主要使用点操作符来完成。但是我们在使用点操作符之前需要知道结构体变量是什么,此代码中,结构体变量y传参给print1函数为yn。
printf("%lf %d %c %f\n", yn.d, yn.x.a, yn.x.c, yn.f);
结构体变量.成员名
传址调用
我们还是使用函数调用的方式实现传址调用,定义函数print2,这里就需要注意了,我们既然是传址调用,那么我们就应该将地址作为参数进行传递,所以我们主函数中print2需要将y的地址传给print2函数中的* ym,地址需要一个指针来接收,我们这里一定不能忘记ym前的*号啊。
传址调用有两种方式,但是不是很推荐第一种,因为操作起来很麻烦。
第一种方式:
printf("%lf %d %c %f\n", (*ym).d, (*ym).x.a, (*ym).x.c, (*ym).f);
我们这边取地址之后解引用将结构体指针变为结构体变量的方式其实和传值调用是一样的,但是步骤要繁琐很多,属于是多此一举。
第二种方式:
printf("%lf %d %c %f\n", ym->d, ym->x.a, ym->x.c, ym->f);
这种方式是直接使用地址的方式来进行传址调用,嗯对,物尽其用,但是这里也要注意,当我们结构体中还有结构体的时候,我们结构体成员X的结构体变量x需要的还是点操作符,因为这里我们ym->x的时候x已经是结构体变量了,所以我们直接使用点操作符就可以访问结构体变量x中的成员。
结构体指针->成员名
今天就到这里喽,希望大家都可以了解结构体的知识,大家下次再见!如有不足之处请各位指正!!!评论区留言一定会回大家的嘞!