C语言基础之——结构体

前言:小伙伴们又见面啦,那么本篇文章,我们就将对C语言基础知识的最后一个章节——结构体展开讲解。

世上无难事,只要肯攀登!


目录

一.什么是结构体

二.结构体讲解

1.结构体的声明和变量的定义

2.结构体成员的类型

3.结构体变量的初始化

三.结构体成员的访问与传参

 总结


一.什么是结构体

结构体是为了用来描述复杂对象而创建的一种数据类型

结构体是一些值的集合,这些值被称作结构体的成员变量,结构体的每个成员可以是不同类型的变量

那么我们为什么要创造和使用结构体呢???

比如说:当我们要描述一个人时,需要接收这个人的名字、年龄、性别、电话等等,这些信息分别属于不同的数据类型,单单用一种数据类型无法完全描述,所以就出现了结构体这一能够将多个不同数据类型的变量集合起来集合性数据类型

二.结构体讲解

1.结构体的声明和变量的定义

struct name

{

        member-list;

}variable-list;

  • struct是创建一个结构体所必要的关键字,它表示我们要创建一个什么样的结构体类型。
  • name则是这个结构体的类型名字,可以自由选择。
  • member-list是你所需要的成员变量的列表,可以是多个。
  • variable-list是结构体类型的变量列表。

我们来实际创建一个学生类型的结构体:

#include<stdio.h>
struct Student
{//学生的各种属性成员char name[20];//名字是字符串,用数组存放int age;//年龄char sex[5];//性别是字符串,用数组存放int stunum[15];//学号也是一串数字,用数组存放
}s1, s2;//定义变量
int main()
{struct Student s3;//定义变量struct Student s4;//定义变量return 0;
}

学生有姓名、年龄、性别、学号等等属性成员。

s1、s2、s3、s4是我们分别定义的结构体类型的变量。其中s1、s2是全局变量,因为在main函数的外边,s3、s4则是局部变量。

我们看到上边对结构体局部类型变量的创建前边都需要struct来表示,其实我们还有另一种创建方式,不需要用到struct就可以创建局部变量:

#include<stdio.h>
typedef struct Student
{//学生的各种属性成员char name[20];//名字是字符串,用数组存放int age;//年龄char sex[5];//性别是字符串,用数组存放int stunum[15];//学号也是一串数字,用数组存放
}Student;//重命名产生的新类型
int main()
{Student s3;//变量Student s4;//变量struct Student s5;//变量return 0;
}

我们用到了typedef关键字,作用是类型定义。它用在结构体的开头时,我们就可以给结构体类型取一个新的名字,就比如我们结构体末尾的Student,随后就可以用这个新名字来定义变量啦。

当然struct在这样的定义下也是可以继续用的

2.结构体成员的类型

结构体的成员可以是标量、数组、指针、甚至是其他的结构体。

struct B
{char s;
};
struct A
{int a;char b;int* p;char arr[20];struct B ab;
};

3.结构体变量的初始化

我们还以学生为例:

#include<stdio.h>
struct Student
{//学生的各种属性成员char name[20];//名字是字符串,用数组存放int age;//年龄char sex[5];//性别是字符串,用数组存放int stunum[15];//学号也是一串数字,用数组存放
};
int main()
{struct Student s1;//定义变量struct Student s1 = { "zhangsan",18,"nan",{2,2,2,8,7,6,0,0,1} };return 0;
}

初始化结构体变量初始化时要用{},我们上述的初始化是按顺序全部初始化的,当然我们也可以不按顺序,来看方法:

struct Student
{//学生的各种属性成员char name[20];//名字是字符串,用数组存放int age;//年龄char sex[5];//性别是字符串,用数组存放int stunum[15];//学号也是一串数字,用数组存放
};
int main()
{struct Student s1 = { .age = 18,.name = "zhangsan" };return 0;
}

不按顺序初始化则需要用到'.'+变量名的形式,这样我们也可以不对全部的变量初始化。

此外,结构体也可以嵌套初始化

#include<stdio.h>
struct Student2
{char name[20];//名字是字符串,用数组存放int age;//年龄char sex[5];//性别是字符串,用数组存放int stunum[15];//学号也是一串数字,用数组存放
};
struct Student
{//学生的各种属性成员char name[20];//名字是字符串,用数组存放int age;//年龄char sex[5];//性别是字符串,用数组存放int stunum[15];//学号也是一串数字,用数组存放struct Student2 s2;
};
int main()
{struct Student s1 = { "zhangsan",18,"nan",{2,2,2,8,7,6,0,0,1},{ "lisi",20,"nv",{2,2,0,8,7,6,0,0,1}} };return 0;
}

我们后边初始化的李四的信息,就是嵌套初始化。

此外,我们还有一种初始化方法,用成员访问操作符来初始化。我们在下文结构体成员的访问中讲述。

三.结构体成员的访问与传参

结构体成员的访问有两种方法:

  • 结构体变量.成员名
  • 结构体指针->成员名

来看实例:

#include<stdio.h>
#include<string.h>
struct Student
{char name[20];int age;
};
void set_s(struct Student s)
{//用成员访问操作符来初始化s.age = 18;//s.name = "zhangsan";//错误写法,因为name是一个数组名,是一个地址//想要用成员访问操作符初始化数组类型的成员变量,要用到strcpystrcpy(s.name, "zhangsan");
}
void print_s(struct Student s)
{printf("%s %d",s.name, s.age);
}
int main()
{struct Student s;//写一个函数来给s中存放数据set_s(s);//写一个函数来打印s中的数据print_s(s);return 0;
}

这样我们便实现了用结构体变量.成员名来访问并初始化成员变量

但是我们上述的写法却忘记了一个非常重要的问题,那就是我们传递给函数的参数问题

我们知道,形参是实参的一份临时拷贝,改变形参的值并不会影响实参,所以我们如果想用用函数来访问初始化成员变量,就必须传址

#include<stdio.h>
#include<string.h>
struct Student
{char name[20];int age;
};
void set_s(struct Student *ps)
{//用成员访问操作符来初始化ps->age = 18;//s.name = "zhangsan";//错误写法,因为name是一个数组名,是一个地址//想要用成员访问操作符初始化数组类型的成员变量,要用到strcpystrcpy(ps->name, "zhangsan");
}
void print_s(struct Student s)
{printf("%s %d",s.name, s.age);
}
int main()
{struct Student s;//写一个函数来给s中存放数据set_s(&s);//写一个函数来打印s中的数据print_s(s);return 0;
}

接收地址便要用到指针,而用指针访问成员变量,就需要用到结构体指针->成员名。这样我们便可以得到结果:

 总结

关于结构体的基础知识到这里就要结束啦。

至此,博主也是讲完了有关C语言的各个章节的整体的基础知识。

后续将会不定时的更新一些难以理解或者是零碎的一些小知识点的讲解,敬请期待!

喜欢博主文章的小伙伴们不要忘记一键三连哦!

我们下期再见!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/116269.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

8. 损失函数与反向传播

8.1 损失函数 ① Loss损失函数一方面计算实际输出和目标之间的差距。 ② Loss损失函数另一方面为我们更新输出提供一定的依据。 8.2 L1loss损失函数 ① L1loss数学公式如下图所示&#xff0c;例子如下下图所示。 import torch from torch.nn import L1Loss inputs torch.tens…

mysql‘逻辑删除‘和‘唯一索引‘冲突的解决方案

一、冲突出现原因 在user表中将name字段设置唯一索引&#xff0c;添加逻辑删除字段del_flag&#xff08;1为删除&#xff0c;0为未删除&#xff09;之后&#xff0c;将name张四的字段删除&#xff0c;再添加一个name张四的记录则会出现冲突 二、解决 1.设置唯一索引组&#x…

【数学建模】清风数模正课7 多元线性回归模型

多元线性回归分析 回归分析就是&#xff0c;通过研究自变量X和因变量Y的相关关系&#xff0c;来解释Y的形成机制&#xff0c;从而达到通过X去预测Y的目的。 所以回归分析需要完成三个使命&#xff0c;首先是识别重要变量&#xff0c;其次是判断正负相关&#xff0c;最后是估计…

opencv-人脸识别

对https://blog.csdn.net/weixin_46291251/article/details/117996591这哥们代码的一些修改 import cv2 import numpy as np import os import shutil import threading import tkinter as tk from PIL import Image, ImageTkchoice 0# 首先读取config文件&#xff0c;第一行…

反射、Class

Class 获取实例化的三种方式

深入理解协同过滤算法及其实现

导语 个性化推荐系统在现代数字时代扮演着重要的角色&#xff0c;协助用户发现他们可能感兴趣的信息、产品或媒体内容。协同过滤是个性化推荐系统中最流行和有效的算法之一。 目录 协同过滤算法的原理 基于用户的协同过滤&#xff08;User-Based Collaborative Filtering&am…

在firefox浏览器下破解hackbar

目录 一、介绍&#xff1a; 二、安装教程 1、打开firefox浏览器插件管理扩展 2、在firefox浏览器下安装老版本Hackbar &#xff08;1&#xff09;首先删除之前安装的Hackbar插件&#xff1a; &#xff08;2&#xff09;采用从文件安装附件添加组&#xff1a; &#xff08;3…

大数据课程K16——Spark的梯度下降法

文章作者邮箱&#xff1a;yugongshiyesina.cn 地址&#xff1a;广东惠州 ▲ 本章节目的 ⚪ 了解Spark的梯度下降法&#xff1b; ⚪ 了解Spark的梯度下降法家族&#xff08;BGD&#xff0c;SGD&#xff0c;MBGD&#xff09;&#xff1b; ⚪ 掌握Spark的MLlib实现…

xx音乐app逆向分析

目标 看一下评论的请求 抓包 这里使用httpcanary 请求包如下 POST /index.php?rcommentsv2/getCommentWithLike&codeca53b96fe5a1d9c22d71c8f522ef7c4f&childrenidcollection_3_1069003079_330_0&kugouid1959585341&ver10&clienttoken7123ecc548ec46d…

五子棋游戏禁手算法的改进

五子棋游戏禁手算法的改进 五子棋最新的禁手规则&#xff1a; 1&#xff0e;黑棋禁手判负、白棋无禁手。黑棋禁手有“三三”&#xff08;包括“四三三”&#xff09;、“四四”&#xff08;包括“四四三”&#xff09;和“长连”。黑棋只能以“四三”取胜。 2&#xff0e;黑方…

Postman API测试之道:不止于点击,更在于策略

引言&#xff1a;API测试的重要性 在当今的软件开发中&#xff0c;API已经成为了一个不可或缺的部分。它们是软件组件之间交互的桥梁&#xff0c;确保数据的流动和功能的实现。因此&#xff0c;对API的测试显得尤为重要&#xff0c;它不仅关乎功能的正确性&#xff0c;还涉及到…

Idea安装免注册版ChatGPT

文章目录 一、前期准备二、开始使用 一、前期准备 1.准备Idea开发软件并打开&#xff08;VS Code同理&#xff09;! 2.【CtrlAltS】快捷键调出Settings窗口&#xff0c;如图 3.找到NexChatGPT 此插件不需要注册&#xff0c;可以直接使用&#xff08;高级一些的需要会员收费限…

Unity编辑器扩展 | 编辑器扩展基础入门

前言 Unity编辑器扩展 | 编辑器扩展基础一、基本概念二、核心知识点 简述三、相关API 总结 前言 当谈到游戏开发工具&#xff0c;Unity编辑器是一个备受赞誉的平台。它为开发者提供了一个强大且灵活的环境&#xff0c;使他们能够创建令人惊叹的游戏和交互式体验。然而&#xf…

视频集中存储/云存储/磁盘阵列/视频监控管理平台EasyCVR接入海康SDK后视频播放崩溃的问题排查

视频集中存储/云存储/磁盘阵列/视频监控管理平台EasyCVR可支持海量视频的轻量化接入与汇聚管理。在视频能力上&#xff0c;EasyCVR可实现视频直播、云端录像、检索与回放、云存储、告警上报、语音对讲、电子地图、H.265视频自动转码、服务器集群、AI智能分析接入以及平台级联等…

git文件夹内容详解

.git文件夹是Git版本控制系统在项目根目录下创建的隐藏文件夹&#xff0c;包含了Git仓库的所有相关信息。如下是.git文件夹中常见的一些内容及其作用&#xff1a; HEAD&#xff1a;指向当前所在的分支&#xff08;或者是一个特定的提交&#xff09;。 branches&#xff1a;存储…

yolov8机器视觉-工业质检

使用训练好的模型进行预测 yolo predict taskdetect model训练好的模型路径 source测试图片文件夹路径 showTrue效果展示 切换模型进行训练&#xff08;yolov8s&#xff09; 修改main.py训练参数文件 使用云gpu进行训练&#xff0c;很方便&#xff1a;点击链接转至在线云gpu…

SpringMVC-学习笔记

文章目录 1.概述1.1 SpringMVC快速入门 2. 请求2.1 加载控制2.2 请求的映射路径2.3 get和post请求发送2.4 五种请求参数种类2.5 传递JSON数据2.6 日期类型参数传递 3.响应3.1 响应格式 4.REST风格4.1 介绍4.2 RESTful快速入门4.3 简化操作 1.概述 SpringMVC是一个基于Java的Web…

Javase | IO流

目录&#xff1a; 1.输入 (Intput/Read)2.输出 (Output/Write)3.IO4.IO流5.IO流的分类&#xff1a;5.1 分类总述5.2 按照 “流的方向” 进行分类5.3 按照 “读取数据的方式” 进行分类 6.IO包下要重点掌握的流&#xff1a;6.1 文件专属 (流)6.2 转换流 ( 将字节流转换为字符流 …

复杂性分析与算法设计:解锁计算机科学的奥秘

文章目录 算法复杂性分析的基本概念时间复杂度空间复杂度 常见的算法设计策略1. 分治法2. 贪心法3. 动态规划 算法设计的实际应用1. 网络路由2. 图像处理3. 人工智能 算法的选择和性能分析结论 &#x1f389;欢迎来到数据结构学习专栏~复杂性分析与算法设计&#xff1a;解锁计算…

Rust 学习笔记(持续更新中…)

一、 编译和运行是单独的两步 运行 Rust 程序之前必须先编译&#xff0c;命令为&#xff1a;rustc 源文件名 - rustc main.rs编译成功之后&#xff0c;会生成一个二进制文件 - 在 Windows 上还会生产一个 .pdb 文件 &#xff0c;里面包含调试信息Rust 是 ahead-of-time 编译的…