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

news2025/1/22 14:26:47

在这里插入图片描述

【作者主页】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.coloradmin.cn/o/2280411.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux系统的第一个进程是什么?

Linux进程的生命周期从创建开始&#xff0c;直至终止&#xff0c;贯穿了一个进程的整个存在过程。我们可以通过系统调用fork()或vfork()来创建一个新的子进程&#xff0c;这标志着一个新进程的诞生。 实际上&#xff0c;Linux系统中的所有进程都是由其父进程创建的。 既然所有…

5. 马科维茨资产组合模型+AI金融智能体(qwen-max)识别政策意图方案(理论+Python实战)

目录 0. 承前1. AI金融智能体1.1 What is AI金融智能体1.2 Why is AI金融智能体1.3 How to AI金融智能体 2. 数据要素&计算流程2.1 参数集设置2.2 数据获取&预处理2.3 收益率计算2.4 因子构建与预期收益率计算2.5 协方差矩阵计算2.6 投资组合优化2.7 持仓筛选2.8 AI金融…

PostMan最新版本及离线安装指南

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;PostMan是一款流行的API测试工具&#xff0c;它提供了一个直观的用户界面&#xff0c;方便Web开发者和测试人员进行接口测试。本文将指导你如何安装最新版的PostMan&#xff0c;包括在线安装和离线安装两种方法。…

记录一次k8s起不来的排查过程

我在k8s集群&#xff0c;重启了一个node宿主机&#xff0c;竟然发现kubelet起不来了&#xff01;报错如下 这个报错很模糊&#xff0c;怎么排查呢。这样&#xff0c;开两个界面&#xff0c;一个重启kubelet&#xff0c;一个看系统日志(/var/log/message:centos&#xff0c;/va…

grafana + Prometheus + node_exporter搭建监控大屏

本文介绍生产系统监控大屏的搭建&#xff0c;比较实用也是实际应用比较多的方式&#xff0c;希望能够帮助大家对监控系统有一定的认识。 0、规划 grafana主要是展示和报警&#xff0c;Prometheus用于保存监控数据&#xff0c;node_exporter用于实时采集各个应用服务器的事实状…

2024年博客之星主题创作|从零到一:我的技术成长与创作之路

2024年博客之星主题创作&#xff5c;从零到一&#xff1a;我的技术成长与创作之路 个人简介个人主页个人成就热门专栏 历程回顾初来CSDN&#xff1a;怀揣憧憬&#xff0c;开启创作之旅成长之路&#xff1a;从平凡到榜一的蜕变持续分享&#xff1a;打卡基地与成长复盘四年历程&a…

Golang的网络编程安全

Golang的网络编程安全 一、Golang网络编程的基本概念 作为一种现代化的编程语言&#xff0c;具有优秀的并发特性和网络编程能力。在Golang中&#xff0c;网络编程是非常常见的需求&#xff0c;可以用于开发各种类型的网络应用&#xff0c;比如Web服务、API服务、消息队列等。Go…

【2024年华为OD机试】(C/D卷,200分)- 5G网络建设 (JavaScriptJava PythonC/C++)

一、问题描述 题目描述 现需要在某城市进行5G网络建设&#xff0c;已经选取N个地点设置5G基站&#xff0c;编号固定为1到N。接下来需要各个基站之间使用光纤进行连接以确保基站能互联互通。不同基站之间假设光纤的成本各不相同&#xff0c;且有些节点之间已经存在光纤相连。 …

消息队列篇--原理篇--RabbitMQ和Kafka对比分析

RabbitMQ和Kafka是两种非常流行的消息队列系统&#xff0c;但它们的设计哲学、架构特点和适用场景存在显著差异。对比如下。 1、架构设计 RabbitMQ&#xff1a; 基AMQP协议&#xff1a;RabbitMQ是基于AMQP&#xff08;高级消息队列协议&#xff09;构建的&#xff0c;支持多…

玻璃样式的登录界面

AI越来越火了,我们想要不被淘汰就得主动拥抱。推荐一个人工智能学习网站,通俗易懂,风趣幽默,最重要的屌图甚多,忍不住分享一下给大家。点击跳转到网站 先看样式: 源码: <div class="wrapper">

Python数据可视化(够用版):懂基础 + 专业的图表抛给Tableau等专业绘图工具

我先说说文章标题中的“够用版”啥意思&#xff0c;为什么这么写。 按照我个人观点&#xff0c;在使用Python进行数据分析时&#xff0c;我们有时候肯定要结合到图表去进行分析&#xff0c;去直观展现数据的规律和特定&#xff0c;那么我们肯定要做一些简单的可视化&#xff0…

物联网网关Web服务器--CGI开发实例BMI计算

本例子通一个计算体重指数的程序来演示Web服务器CGI开发。 硬件环境&#xff1a;飞腾派开发板&#xff08;国产E2000处理器&#xff09; 软件环境&#xff1a;飞腾派OS&#xff08;Phytium Pi OS&#xff09; 硬件平台参考另一篇博客&#xff1a;国产化ARM平台-飞腾派开发板…

HTML新春烟花

系列文章 序号目录1HTML满屏跳动的爱心&#xff08;可写字&#xff09;2HTML五彩缤纷的爱心3HTML满屏漂浮爱心4HTML情人节快乐5HTML蓝色爱心射线6HTML跳动的爱心&#xff08;简易版&#xff09;7HTML粒子爱心8HTML蓝色动态爱心9HTML跳动的爱心&#xff08;双心版&#xff09;1…

从结构嵌套的幻梦里:递归与数据构建的精巧和鸣

大家好啊&#xff0c;我是小象٩(๑ω๑)۶ 我的博客&#xff1a;Xiao Xiangζั͡ޓއއ 很高兴见到大家&#xff0c;希望能够和大家一起交流学习&#xff0c;共同进步。 这一节我们来学习递归的相关知识 函数递归 一、什么是递归1.1 递归的思想 二、递归的限制条件三、递归的…

【Linux系统】—— 编译器 gcc/g++ 的使用

【Linux系统】—— 编译器 gcc/g 的使用 1 用 gcc 直接编译2 翻译环境2.1 预处理&#xff08;进行宏替换&#xff09;2.2 编译&#xff08;生成汇编&#xff09;2.3 汇编&#xff08;生成机器可识别代码&#xff09;2.4 链接2.5 记忆小技巧2.6 编译方式2.7 几个问题2.7.1 如何理…

【Unity3D】3D物体摆放、场景优化案例Demo

目录 PlaceManager.cs(放置管理类) Ground.cs(地板类) 和 GroundData.cs(地板数据类) 额外知识点说明 1、MeshFilter和MeshRenderer的Bounds区别 2、Gizmos 绘制一个平行于斜面的立方体 通过网盘分享的文件&#xff1a;PlaceGameDemo2.unitypackage 链接: https://pan.baid…

智能系统的感知和决策

智能系统在感知和决策过程中具备的关键能力表现在智能感知/自主判定上&#xff0c;下面可以从感知的本质、自主判断的含义及其在智能系统中的作用进行深入分析。 1、智能感知&#xff1a;信息获取与理解 智能感知是指智能系统通过传感器或其他数据采集手段获取环境中的信息&…

Spring 中的事件驱动模型

事件驱动的基本了解 事件模式也就是观察者模式&#xff0c;当一个对象改变的时候&#xff0c;所有依赖的对象都会收到一个通知。 Subject&#xff1a;抽象主题 Observer&#xff1a;具体主题 Concrete Subject&#xff1a;抽象观察者&#xff0c;在得到更新通知之后去更新自…

linux-FTP服务配置与应用

也许你对FTP不陌生&#xff0c;但是你是否了解FTP到底是个什么玩意&#xff1f; FTP 是File Transfer Protocol&#xff08;文件传输协议&#xff09;的英文简称&#xff0c;而中文简称为 “文传协议” 用于Internet上的控制文件的双向传输。同时&#xff0c;它也是一个应用程序…

linux-NFS网络共享存储服务配置

1.NFS服务原理 NFS会经常用到&#xff0c;用于在网络上共享存储&#xff0c;这样讲&#xff0c;你对NFS可能不太了解&#xff0c;举一个例子&#xff0c; 加入有三台机器A,B,C&#xff0c;它们需要访问同一个目录&#xff0c;目录中都是图片&#xff0c;传统的做法是把这些 图…