C语言基础之——结构体

news2025/1/12 23:06:47

前言:小伙伴们又见面啦,那么本篇文章,我们就将对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是一个数组名,是一个地址
	//想要用成员访问操作符初始化数组类型的成员变量,要用到strcpy
	strcpy(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是一个数组名,是一个地址
	//想要用成员访问操作符初始化数组类型的成员变量,要用到strcpy
	strcpy(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.coloradmin.cn/o/945110.html

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

相关文章

〖Python网络爬虫实战㉞〗- 图形验证码OCR识别

订阅&#xff1a;新手可以订阅我的其他专栏。免费阶段订阅量1000 python项目实战 Python编程基础教程系列&#xff08;零基础小白搬砖逆袭) 说明&#xff1a;本专栏持续更新中&#xff0c;订阅本专栏前必读关于专栏〖Python网络爬虫实战〗转为付费专栏的订阅说明作者&#xff1…

操作系统_文件管理(三)

目录 3. 文件系统 3.1 文件系统结构 3.2 文件系统布局 3.2.1 文件系统在磁盘中的结构 3.2.2 文件系统在内存中的结构 3.3 外存空闲空间管理 3.3.1 空闲表法 3.3.2 空闲链表法 3.3.3 位示图法 3.3.4 成组链接法 3.4 虚拟文件系统 3.5 分区和安装 3.6 小结 3. 文件系…

Javaweb入门

Spring Spring发展到今天已经形成一种开发生态圈&#xff0c;Spring提供若干个子项目&#xff0c;每个项目用于完成特定的功能。 Spring Boot可以帮助我们非常快速的构建应用程序、简化开发、提高效率 SpringBootWeb入门 需求&#xff1a;使用Spring Boot开发一个web应用&a…

不同代码写法的区别

目录 神经网络中输入在layer中写输入在build中写输入 输出format写法f代替format写法 zip不加*加* 打平Flatten方法reshape方法 数据打包(batch)tensorflowpytorch 神经网络中输入 在layer中写输入 layers.Dense(512, activationrelu, namelayer1,input_shape(784,)),此处784…

C语言 实现atoi函数

实现类似atoi函数&#xff0c;把字符串“123456”转换成数值123456 函数int atoi(char *str); 使用ubuntu进行多文件编译&#xff08;main.c head.h test.c&#xff09; head.h&#xff08;预处理&#xff09; #ifndef __HEAD_H__ #define __HEAD_H__#include <stdio.…

freertos之信号量

介绍 信号量这个名字很恰当&#xff1a; 信号&#xff1a;起通知作用 量&#xff1a;还可以用来表示资源的数量 当"量"没有限制时&#xff0c;它就是"计数型信号量"(Counting Semaphores) 当"量"只有0、1两个取值时&#xff0c;它就是"二进…

2023必备AIGC人工智能软件Top 6

随着人工智能技术的迅猛发展&#xff0c;越来越多的应用程序开始集成AIGC&#xff08;Artificial Intelligence Generated Content&#xff0c;人工智能生成内容&#xff09;功能&#xff0c;为用户提供更高效、更创造性的体验。在本文中&#xff0c;我们将分享6款实用的AIGC软…

C++ DAY7

一、类模板 建立一个通用的类&#xff0c;其类中的类型不确定&#xff0c;用一个虚拟类型替代 template<typename T> 类template ----->表示开始创建模板 typename -->表明后面的符号是数据类型&#xff0c;typename 也可以用class代替 T ----->表示数据类型…

php开发环境搭建_宝塔、composer

宝塔面板下载&#xff0c;免费全能的服务器运维软件 一 下载宝塔面板 解压安装 登录之后修改安全入口 1 进入软件商店下载nginx,mysql5.6,php7.2 2 将php的安装路径配置到环境变量中 此电脑--右键--点击属性---高级系统设置---环境变量---系统变量path---添加确定 输入php -v…

DC/DC开关电源学习笔记(三)开关频率和储能元件

&#xff08;三&#xff09;开关频率和储能元件 1.开关频率2.储能元件 1.开关频率 频率是开关电源的一个基本属性&#xff0c;它代表了直流电压开启和关断的速率。了解开关频率就可以了解实际应用中电源线路的工作原理。 开关电源利用开关动作将直流电转换为特定频率的脉冲电…

【教程】部署apprtc服务中安装google-cloud-cli组件的问题及解决

前置条件 已经安装完成node&#xff0c;grunt&#xff0c;node 组件和python pip包等。需要安装google-cloud-cli组件。 Ubuntu安装google-cloud-cli组件 apprtc项目运行需要google-cloud-cli前置组件&#xff0c;且运行其中的dev_appserver.py。 根据google官方的关于安装g…

应用于伺服电机控制、 编码器仿真、 电动助力转向、发电机、 汽车运动检测与控制的旋变数字转换器MS5905P

MS5905P 是一款 12bit 分辨率的旋变数字转换器。 片上集成正弦波激励电路&#xff0c;正弦和余弦允许输入峰峰值 幅度为 2.3V 到 4.0V &#xff0c;可编程激励频率为 10kHz 、 12kHz 、 15kHz 、 20kHz 。 转换器可并行或串行输出角度 和速度对应的数字量。 MS5905…

第 3 章 栈和队列(顺序栈,算法 3.1 、3.2、3.4)

1. 示例代码&#xff1a; 1) status.h /* DataStructure 预定义常量和类型头文件 */#ifndef STATUS_H #define STATUS_H/* 函数结果状态码 */ #define TRUE 1 /* 返回值为真 */ #define FALSE 0 /* 返回值为假 */ #define RET_OK 0 /* 返回值正确 */ #d…

Python Opencv实践 - Canny边缘检测

import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/pomeranian.png", cv.IMREAD_GRAYSCALE) print(img.shape)#图像Canny边缘检测 #cv.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradien…

【第1章 数据结构概述】

目录 一. 基本概念 1. 数据、数据元素、数据对象 2. 数据结构 二. 数据结构的分类 1. 数据的逻辑结构可分为两大类&#xff1a;a. 线性结构&#xff1b;b. 非线性结构 2. 数据的存储结构取决于四种基本的存储方法&#xff1a;顺序存储、链接存储、索引存储、散列存储 3. …

【Unity】终极移动指南-注解【理解移动到抓钩,再到贪吃蛇的实现】

文章目录 【Unity】终极移动指南-注解&#xff08;从移动、抓钩到贪吃蛇&#xff09;观前提醒链接地址&#xff1a; 内容一、 transform移动操作【1】transform.position变换位置【2】transform.Translate平移【3】transform.position 类似平移的操作【4】定向矢量【5】停在指定…

教你快速记单词。一套高效的单词记忆法,背单词技巧 英语没有一个单词需要死记硬背的,5天能不能记住1万个单词 CrazyEnglish视频学习

就是这些辅音是可以互换的&#xff0c;之后我们就是换元音来组成新的单词 整个欧洲基本说的都是方言&#xff0c;他们很多真的就是发音和书写在变 这张图片超级重要 其实跟我们小时候学的那个拼音的那个背记排序好像是一样的 &#xff08;看到这个视频的后面&#xff0c;你就…

Linux操作系统中特定软件的安装

Linux中特定软件的安装 1、yum仓库2、在Linux中安装JDK3、在Linux中安装MySQL4、VMware的安装5、在VMware中安装CentOS6、克隆虚拟机 1、yum仓库 yum install -y 安装包的名字 更换yum的base源&#xff1a; /etc/yum.repos.d/CentOS-Base.repo 1、需要把原先的数据源做一个备…

算法题打卡day45-背包问题 | 70. 爬楼梯 (进阶)、322. 零钱兑换、279.完全平方数

70. 爬楼梯 - 力扣&#xff08;LeetCode&#xff09; 状态&#xff1a;查看思路后AC。 除了常规的可以爬一或二级台阶&#xff0c;当题目稍微修改一下&#xff0c;变成可以爬m级台阶&#xff0c;之前的DP思路就有局限&#xff08;dp[i] dp[i-1] dp[i-2&#xff09;&#xff0…