当前位置: 首页 > article >正文

[c语言日寄]结构体的使用及其拓展

在这里插入图片描述

【作者主页】siy2333
【专栏介绍】⌈c语言日寄⌋:这是一个专注于C语言刷题的专栏,精选题目,搭配详细题解、拓展算法。从基础语法到复杂算法,题目涉及的知识点全面覆盖,助力你系统提升。无论你是初学者,还是进阶开发者,这里都能满足你的需求!
【食用方法】1.根据题目自行尝试 2.查看基础思路完善题解 3.学习拓展算法
【Gitee链接】资源保存在我的Gitee仓库:https://gitee.com/siy2333/study


文章目录

  • 前言
  • 题目引入
  • 一、结构体的定义与初始化
    • 结构体的定义
    • 结构体变量的初始化
      • 1. 直接初始化
      • 2. 使用点运算符(.)逐个赋值
      • 3. 使用指针访问结构体成员
  • 二、结构体数组的使用
    • 遍历结构体数组
    • 使用指针访问结构体数组
  • 三、函数与结构体
    • 函数参数传递
    • 返回结构体变量
  • 四、程序分析与输出结果
  • 五、结构体的高级特性
    • 结构体嵌套
    • 结构体与联合体
    • 结构体与位字段
  • 总结


前言

在C语言的世界里,结构体(struct)是一种非常强大且灵活的工具,它允许我们自定义数据类型,将多个不同类型的数据组合在一起。这种特性使得结构体在处理复杂数据时变得非常方便。今天,我们就通过一个简单的程序来深入探讨结构体的使用,以及它在C语言中的重要性。

题目引入

下面程序的输出结果是:( )

struct stu
{
    int num;
    char name[10];
    int age;
};

void fun(struct stu *p)
{
	printf("%s\n",(*p).name);
	return;
}

int main()
{
	struct stu students[3] = {{9801,"zhang",20},
							 {9802,"wang",19},
                    {9803,"zhao",18} };
   fun(students + 1);
	return 0;
}

A.zhang
B.zhao
C.wang
D.18

在接下来的文章中,我们会一起把结构体的知识与题目结合起来,学习这一知识点。

一、结构体的定义与初始化

结构体的定义

结构体的定义通常使用struct关键字,后面跟着结构体名称和花括号{}括起来的成员列表

struct stu
{
    int num;
    char name[10];
    int age;
};

这里,我们定义了一个名为struct stu的结构体,它包含三个成员:

  • int num:表示学生的编号。
  • char name[10]:表示学生的姓名,是一个长度为10的字符数组。
  • int age:表示学生的年龄。

结构体的定义只是定义了一个数据类型,就像定义了一个模板。要使用这个结构体,我们需要创建结构体变量。创建变量的方式与基本数据类型相同:

struct stu a;//创建结构体变量

结构体变量的初始化

1. 直接初始化

在定义结构体变量时,可以直接为每个成员赋值:

struct stu student = {1001, "Alice", 20};

这里,student是一个struct stu类型的变量,它的num成员被初始化为1001,name成员被初始化为"Alice",age成员被初始化为20。

2. 使用点运算符(.)逐个赋值

我们也可以在定义结构体变量后,使用点运算符逐个为成员赋值:

struct stu student;
student.num = 1002;
strcpy(student.name, "Bob");//使用了strcpy函数来为name成员赋值,name是一个字符数组,不能直接用赋值运算符=来赋值。
student.age = 21;

3. 使用指针访问结构体成员

除了直接使用结构体变量,我们还可以通过指针来访问结构体成员。

struct stu *p = &student;
printf("Name: %s, Age: %d\n", p->name, p->age);

这里,p是一个指向struct stu的指针,我们使用->运算符来访问结构体成员。

二、结构体数组的使用

结构体不仅可以单独使用,还可以作为数组的元素。结构体数组允许我们存储多个结构体变量,这在处理大量相关数据时非常方便。

//例如,我们可以在一个数组中存储多个学生的信息:
struct stu students[3] = {
    {9801, "zhang", 20},
    {9802, "wang", 19},
    {9803, "zhao", 18}
};

在这里,students是一个包含3个struct stu元素的数组。每个元素都是一个结构体变量。

遍历结构体数组

我们可以使用循环来遍历结构体数组,并访问每个元素的成员:

for (int i = 0; i < 3; i++) {
    printf("Student %d: Num = %d, Name = %s, Age = %d\n", i + 1, students[i].num, students[i].name, students[i].age);
}

这段代码会输出每个学生的编号、姓名和年龄。

使用指针访问结构体数组

与上文中使用指针为结构体变量初始化原理相同,我们也可以使用指针来访问结构体数组的元素:

struct stu *p = students;
for (int i = 0; i < 3; i++) {
    printf("Student %d: Num = %d, Name = %s, Age = %d\n", i + 1, p->num, p->name, p->age);
    p++;
}

这里,p是一个指向struct stu的指针,初始时指向students数组的第一个元素。通过p++操作,我们可以逐个访问数组中的每个元素。

三、函数与结构体

在C语言中,函数是程序的基本组成单元,它允许我们将代码模块化,提高代码的可读性和可维护性。结构体与函数的结合使用可以实现更复杂的功能。

函数参数传递

函数可以接收结构体变量作为参数。当我们传递结构体变量时,可以选择传递值或传递指针。

  • 传递值时,函数会接收结构体的一个副本,对副本的修改不会影响原始变量。
  • 传递指针时,函数会接收结构体的地址,可以直接修改原始变量。

我们定义了一个函数fun,它接收一个指向struct stu的指针作为参数:

void fun(struct stu *p)
{
    printf("%s\n", (*p).name);
    return;
}

这个函数的作用是打印传入的结构体变量的name成员。我们可以通过传递结构体数组的某个元素的地址来调用这个函数:

struct stu
{
    int num;
    char name[10];
    int age;
};

void fun(struct stu *p)
{
	printf("%s\n",(*p).name);
	return;
}

int main()
{
	struct stu students[3] = {{9801,"zhang",20},
							 {9802,"wang",19},
                    {9803,"zhao",18} };
   fun(students + 1);//函数调用
	return 0;
}

这里,students + 1表示数组中第二个元素的地址(即&students[1])。因此,fun(students + 1)会打印出students[1]的name成员,即"wang"。

返回结构体变量

函数不仅可以接收结构体变量作为参数,还可以返回结构体变量。例如,我们可以编写一个函数来创建一个新的学生记录:

struct stu create_student(int num, const char *name, int age)
{
    struct stu student;
    student.num = num;
    strcpy(student.name, name);
    student.age = age;
    return student;
}

这个函数接收学生的编号、姓名和年龄作为参数,创建一个新的struct stu变量,并将其返回。

四、程序分析与输出结果

现在,让我们回到最初的问题。我们有一个程序,它的代码如下:

struct stu
{
    int num;
    char name[10];
    int age;
};

void fun(struct stu *p)
{
    printf("%s\n", (*p).name);
    return;
}

int main()
{
    struct stu students[3] = {
        {9801, "zhang", 20},
        {9802, "wang", 19},
        {9803, "zhao", 18}
    };
    fun(students + 1);
    return 0;
}

我们需要确定程序的输出结果。根据前面的分析,我们知道:

  • students是一个包含3个元素的struct stu数组。
  • students + 1表示数组中第二个元素的地址(即&students[1])。
  • fun(students + 1)会打印出students[1]的name成员。

故,程序的输出结果是"wang"。 所以,正确答案是: C. wang

五、结构体的高级特性

结构体在C语言中不仅仅是一个简单的数据组合工具,它还支持一些高级特性,这些特性使得结构体在复杂的应用场景中更加灵活和强大。

结构体嵌套

结构体可以嵌套,即一个结构体可以包含另一个结构体作为成员。例如,我们可以定义一个学生信息结构体,它包含一个地址信息结构体:

struct address
{
    char street[50];
    char city[30];
    char state[20];
    int zip;
};

struct stu
{
    int num;
    char name[10];
    int age;
    struct address addr;
};

这里,struct stu包含了一个struct address类型的成员addr。

我们可以通过点运算符访问嵌套结构体的成员:

struct stu student = {1001, "Alice", 20, {"123 Main St", "Springfield", "IL", 62704}};

printf("Student Name: %s, Address: %s, %s, %s, %d\n", student.name, student.addr.street, student.addr.city, student.addr.state, student.addr.zip);

结构体与联合体

联合体(union)是一种特殊的数据类型,它允许不同的数据类型共享同一块内存。结构体和联合体可以结合使用,实现一些有趣的功能。例如,我们可以定义一个结构体,它包含一个联合体成员:

struct stu
{
    int num;
    char name[10];
    int age;
    union {
        char gender;
        int id;
    } info;
};

这里,info是一个联合体成员,它既可以存储一个字符(gender),也可以存储一个整数(id)。我们可以通过联合体的成员名来访问它:

struct stu student = {1001, "Alice", 20};
student.info.gender = 'F';
printf("Student Name: %s, Gender: %c\n", student.name, student.info.gender);

结构体与位字段

位字段是结构体的一个特殊特性,它允许我们定义结构体成员的位宽度。这在处理硬件接口或需要节省内存的场景中非常有用:

struct stu
{
    int num : 16;  // num占用16位
    int age : 8;   // age占用8位
};

这里,num成员占用16位,age成员占用8位。
不过,位字段的使用需要谨慎一些,因为它的行为可能会因编译器而异


总结

结构体是C语言中一个非常重要的概念,它允许我们将多个不同类型的数据组合在一起,形成一个逻辑上的整体。

关注窝,每三天至少更新一篇优质c语言题目详解~

[专栏链接QwQ] :⌈c语言日寄⌋CSDN
[关注博主ava]:siy2333
感谢观看~ 我们下次再见!!


http://www.kler.cn/a/518667.html

相关文章:

  • 工业数据分析:解锁工厂数字化的潜力
  • 单片机基础模块学习——数码管(二)
  • python生成图片和pdf,快速
  • 云计算的概念与特点:开启数字化时代的新篇章
  • 代码随想录算法训练营day31(补0124)
  • 【Matlab高端绘图SCI绘图模板】第05期 绘制高阶折线图
  • Arcgis国产化替代:Bigemap Pro正式发布
  • OpenHarmony5.0 AVPlayer新特性开发指导(二)
  • 基于本地事务表+MQ实现分布式事务
  • 计算机工程:解锁未来科技之门!
  • Spring Boot Actuator 集成 Micrometer(官网文档解读)
  • 警企联动齐发力、共筑反诈“防护墙”
  • 2025美赛B题-问题B:管理可持续旅游
  • 如何使用 MySQL 的 EXPLAIN 语句进行查询分析?
  • 数据结构测试题2
  • day1代码练习
  • 在 DevOps 实践中,如何构建自动化的持续集成和持续交付(CI/CD)管道,以提高开发和测试效率?
  • 浅谈Redis
  • c语言分支和循环
  • ros动态调参界面的修改
  • Linux内核中IPoIB驱动模块的初始化与实现
  • 什么是COLLATE排序规则?
  • WPF基础 | WPF 基础概念全解析:布局、控件与事件
  • 2025-01-22 Unity Editor 1 —— MenuItem 入门
  • 2025美赛数学建模MCM/ICM选题建议与分析,思路+模型+代码
  • 寒假1.23