【C语言】全面解析结构体,结构体知识点整理

简介: 结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。组成结构型数据的每个数据称为结构型数据的“成员”。结构体通常用来表示类型不同但是又相关的若干数据。

结构体的概念


结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。组成结构型数据的每个数据称为结构型数据的“成员”。结构体通常用来表示类型不同但是又相关的若干数据。


结构体类型的声明


结构体类型的声明要使用s t r u c t \color{#0000FF}{ struct}struct关键字,举个例子,比如我要定义一个学生的结构体类型,学生有姓名,年龄,学号等等。那么我就可以这样声明一个学生的结构体类型:

struct stu

{

char name[20];//姓名

int age;//年龄

char id[15];//学号

};

我在声明学生这个结构体的时候,只写了姓名,年龄和学号。如果想定义其它的变量也可以在结构体里面定义。struct stu就是结构体类型,不能省略struct。结构的成员可以是标量、数组、指针,甚至是其他结构体。


结构体变量的创建


struct stu

{

char name[20];//姓名

int age;//年龄

char id[15];//学号

}s1,s2,s3;//全局变量

int main()

{

//局部变量

struct stu s4;

struct stu s5;

return 0;

}

看上面这段代码,结构体变量的定义可以在声明结构体类型的时候直接创建,如果直接创建就像s1,s2,s3。那么s1,s2,s3就是全局变量。也可以在主函数中通过struct stu这个结构体类型创建结构体变量,像s4和s5,在主函数中创建的结构体变量就是局部变量。


typedef关键字


给大家再补充一个知识点,就是 typedef关键字。我相信大家在学习结构体或者数据结构的时候也见过这个关键字,一般都是配合结构体使用,所以 我们还是要掌握typedef关键字。

typedef用新的类型名代替原有的类型名。简单点来说typedef就是一个重命名的关键字。

看下面这段代码:

#include

typedef int data;//将data定义成int类型

int main()

{

data a = 5;

printf("%d", a);

return 0;

}

我用typedef将data变成了int类型,那么我就可以使用data创建的变量就是一个整型的变量,此时输出的结果就是5,没有任何问题。

不光是数据类型可以使用typedef进行重命名,结构体也是可以的。在结构体中使用typedef关键字一般有两种写法。

#include

typedef struct stu

{

char name[20];//姓名

int age;//年龄

char id[15];//学号

}Stu;

int main()

{

struct stu s4;

struct stu s5;

Stu s6;

return 0;

}

像这种写法,就是直接对结构体进行重命名,但是此时就无法创建结构体的全局变量。在主函数中可以通过结构体类型来创建变量,也可以通过重命名后的名字直接创建变量。我们来看另外一种写法。

#include

struct stu

{

char name[20];//姓名

int age;//年龄

char id[15];//学号

}s1,s2,s3;

typedef struct stu Stu;

int main()

{

struct stu s4;

struct stu s5;

Stu s6;

return 0;

}

像这种创建的方法就可以创建全局变量,其实两种方法的原理差不多,都是**typedef struct stu Stu;**只是位置不同罢了。


结构体的嵌套


结构体的嵌套就是在一个结构体里面再放一个结构体。举个例子:

struct score

{

float Chinese;

float Math;

float Enlish;

float ave;

};

struct stu

{

char name[20];//姓名

int age;//年龄

char id[15];//学号

struct score Score;

}s1, s2, s3;

我在学生这个结构体里面嵌套了一个分数的结构体,结构体的嵌套还是挺简单的,不过有一点需要注意,结构体的嵌套是有顺序的。 \color{#0000FF}{结构体的嵌套是有顺序的。}结构体的嵌套是有顺序的。 因为我是再学生这个结构体里面嵌套的分数这个结构体,所以我要先声明分数这个结构体,如果把它放在学生结构体的下面,代码就会报错。


结构体变量的初始化


结构体的初始化是用{}进行初始化,如果是嵌套的结构体里面也要用{},给大家演示一下,很简单,一看就能看懂。

#include

struct score

{

float Chinese;

float Math;

float Enlish;

}Score1={63.4,56.8,51.3};

struct stu

{

char name[20];//姓名

int age;//年龄

char id[15];//学号

struct score Score2;

}s1, s2, s3;


int main()

{

struct stu s4 = { "张三", 15, "20220805", {63.4,56.8,51.3} };

struct stu s5;

return 0;

}

可以在创建成员变量时直接初始化,也可以在主函数中进行初始化。


结构体成员的访问


结构体成员的访问有两种方式,一种是 '.’,一种是’->'。举个例子:

#include

struct score

{

float Chinese;

float Math;

float Enlish;

}Score1={63.4,56.8,51.3};

struct stu

{

char name[20];//姓名

int age;//年龄

char id[15];//学号

struct score Score2;

}s1, s2, s3;

int main()

{

struct stu s4 = { "张三", 15, "20220805", {63.4,56.8,51.3} };

struct stu s5;

printf("%s\n", s4.name);

printf("%d\n", s4.age);

printf("%.1f\n", s4.Score2.Chinese);

return 0;

}

如果要输出结构体的成员的值,那么就可以通过结构体变量.结构体成员进行输出。

下面来看另外一种访问方式,通过->进行访问通常是结构体指针->结构体成员。

#include

struct stu

{

char name[20];//姓名

int age;//年龄

char id[15];//学号

struct score Score2;

}s1, s2, s3;

void print(struct stu* sp)

{

printf("%s", sp->name);

}

int main()

{

struct stu s4 = { "张三", 15, "20220805", {63.4,56.8,51.3} ,5};

print(&s4);;

return 0;

}

这些内容都不是很难,大家多多练习应该就可以掌握。


结构体的传参


先看下下面这段代码:

#include

struct stu

{

char name[20];//姓名

int age;//年龄

char id[15];//学号

}s1, s2, s3;

void print1(struct stu sp1)

{

printf("%s\n", sp1.name);

}

void print2(struct stu* sp2)

{

printf("%s\n", sp2->name);

}

int main()

{

struct stu s4 = { "张三", 15, "20220805" };

print1(s4);

print2(&s4);

return 0;

}

那么对于print1 和 print2这两个函数,哪一个好点?

答案是print2函数

函数传参的时候,参数是需要压栈的。

如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的

下降。

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


总结


结构体这部分比较简单,不过也是学习数据结构的过程中很重要的一部分,大家还是要熟练掌握结构体。(水平有限,如有错误欢迎大佬指正!感谢!!!)

相关文章
|
10月前
|
存储 网络协议 编译器
【C语言】深入解析C语言结构体:定义、声明与高级应用实践
通过根据需求合理选择结构体定义和声明的放置位置,并灵活结合动态内存分配、内存优化和数据结构设计,可以显著提高代码的可维护性和运行效率。在实际开发中,建议遵循以下原则: - **模块化设计**:尽可能封装实现细节,减少模块间的耦合。 - **内存管理**:明确动态分配与释放的责任,防止资源泄漏。 - **优化顺序**:合理排列结构体成员以减少内存占用。
804 14
|
10月前
|
存储 算法 C语言
【C语言】深入浅出:C语言链表的全面解析
链表是一种重要的基础数据结构,适用于频繁的插入和删除操作。通过本篇详细讲解了单链表、双向链表和循环链表的概念和实现,以及各类常用操作的示例代码。掌握链表的使用对于理解更复杂的数据结构和算法具有重要意义。
3152 6
|
10月前
|
存储 网络协议 算法
【C语言】进制转换无难事:二进制、十进制、八进制与十六进制的全解析与实例
进制转换是计算机编程中常见的操作。在C语言中,了解如何在不同进制之间转换数据对于处理和显示数据非常重要。本文将详细介绍如何在二进制、十进制、八进制和十六进制之间进行转换。
1364 5
|
10月前
|
C语言 开发者
【C语言】断言函数 -《深入解析C语言调试利器 !》
断言(assert)是一种调试工具,用于在程序运行时检查某些条件是否成立。如果条件不成立,断言会触发错误,并通常会终止程序的执行。断言有助于在开发和测试阶段捕捉逻辑错误。
243 5
|
1月前
|
存储 C语言
`scanf`是C语言中用于按格式读取标准输入的函数
`scanf`是C语言中用于按格式读取标准输入的函数,通过格式字符串解析输入并存入指定变量。需注意输入格式严格匹配,并建议检查返回值以确保读取成功,提升程序健壮性。
748 0
|
3月前
|
安全 C语言
C语言中的字符、字符串及内存操作函数详细讲解
通过这些函数的正确使用,可以有效管理字符串和内存操作,它们是C语言编程中不可或缺的工具。
260 15
|
9月前
|
存储 算法 C语言
【C语言程序设计——函数】素数判定(头歌实践教学平台习题)【合集】
本内容介绍了编写一个判断素数的子函数的任务,涵盖循环控制与跳转语句、算术运算符(%)、以及素数的概念。任务要求在主函数中输入整数并输出是否为素数的信息。相关知识包括 `for` 和 `while` 循环、`break` 和 `continue` 语句、取余运算符 `%` 的使用及素数定义、分布规律和应用场景。编程要求根据提示补充代码,测试说明提供了输入输出示例,最后给出通关代码和测试结果。 任务核心:编写判断素数的子函数并在主函数中调用,涉及循环结构和条件判断。
419 23
|
8月前
|
人工智能 Java 程序员
一文彻底搞清楚C语言的函数
本文介绍C语言函数:函数是程序模块化的工具,由函数头和函数体组成,涵盖定义、调用、参数传递及声明等内容。值传递确保实参不受影响,函数声明增强代码可读性。君志所向,一往无前!
233 1
一文彻底搞清楚C语言的函数
|
9月前
|
算法 C语言
【C语言程序设计——函数】利用函数求解最大公约数和最小公倍数(头歌实践教学平台习题)【合集】
本文档介绍了如何编写两个子函数,分别求任意两个整数的最大公约数和最小公倍数。内容涵盖循环控制与跳转语句的使用、最大公约数的求法(包括辗转相除法和更相减损术),以及基于最大公约数求最小公倍数的方法。通过示例代码和测试说明,帮助读者理解和实现相关算法。最终提供了完整的通关代码及测试结果,确保编程任务的成功完成。
327 15
【C语言程序设计——函数】利用函数求解最大公约数和最小公倍数(头歌实践教学平台习题)【合集】
|
9月前
|
C语言
【C语言程序设计——函数】亲密数判定(头歌实践教学平台习题)【合集】
本文介绍了通过编程实现打印3000以内的全部亲密数的任务。主要内容包括: 1. **任务描述**:实现函数打印3000以内的全部亲密数。 2. **相关知识**: - 循环控制和跳转语句(for、while循环,break、continue语句)的使用。 - 亲密数的概念及历史背景。 - 判断亲密数的方法:计算数A的因子和存于B,再计算B的因子和存于sum,最后比较sum与A是否相等。 3. **编程要求**:根据提示在指定区域内补充代码。 4. **测试说明**:平台对代码进行测试,预期输出如220和284是一组亲密数。 5. **通关代码**:提供了完整的C语言代码实现
172 24

推荐镜像

更多
  • DNS