struct详解

news2025/2/3 0:06:13

导入

我们有没有这种情况,总想有一个数组,其中可以有int,double,char。。。各种类型,但是对于内置的数据类型显然是做不到的,于是就有了结构体类型
结构体是将多种不同的结构打包在一起,形成全新的类型进行使用

struct

struct声明以及定义

struct Base
{
	char a;
	int b;
	float c;
	double d;
}name,*p_name;//记得这里的分号,一定不能少
//这里可以一次定义多个变量名
int main()
{
	//也可以后面定义
	struct Base* p;
	
	return 0;
}

同时还有匿名结构体类型

匿名结构体类型

struct
{
	int a;
	int b;
	int d;
};

我们需要特别注意的是,匿名结构体类型只能立即使用,不然就找不到了—无法在后面申请变量

struct
{
	int a;
	int b;
	int d;
}name,*p_name;
int main()
{
	name.a = 20;
	p_name = &name;
}

这样使用都是没有问题的
至于为什么后面就不能使用了,我们可以想一下,声明结构体的时候需要写出结构体的类型,但是你现在只有struct,计算机怎么知道你是那个结构体,所以计算机就给我抛出了警告

结构体的自引用

顾名思义就是自己套自己

struct Base
{
	int a;
	char b;
	struct Base* next;//这种就是自己引用自己
};

在自己引用自己的时候需要注意的是,不能写成下面这种情况

struct Base
{
	int a;
	char b;
	struct Base* next;
	struct Base nn;
};

在这里插入图片描述
因为根本无法判断这个结构体的大小到底是多少,自己中套自己,俄罗斯套娃一直套下去,根本不知道这个结构体的大小到底是多少,所以如果要自引用的话只能使用指针,指针的大小是一定的 struct不能包含自己

struct 的定义和初始化

定义

struct Base1
{
	int a;
	int b;
}p;
int main()
{
	//定义法1---直接定义
	//定义法2---适时定义
	struct Base1* pf;

	return 0;
}

初始化

#include<stdio.h>
struct Base2
{
	int a;
	char b;
	struct Base2* next;
};
struct Base1
{
	int a;
	int b;
}p = { 1,2 };
struct Base3
{
	struct Base1 mem1;
	int a;
	struct Base2* p;
};
int main()
{
	//初始化法1---直接初始化
	
	//初始化法2---定义时初始化
	struct Base1 son1 = { 3,4 };

	//含有自引用的初始化
	struct Base2 son2;
	struct Base2 nn = { 1,'a',&son2 };
	struct Base3 mem = { {1,2},3,NULL };
}

初始化的时候根据结构体中的元素进行初始化就行了,遇见结构体嵌套结构体的情况直接使用{}进行初始化

结构体的对齐

开始之前我们先计算一下结构体的大小

#include<stdio.h>
struct Base
{
	int a;
	char b;
	double c;
};
int main()
{
	struct Base s;
	printf("%d", sizeof(s));
	return 0;
}

应该会有同学认为因该是int+char+double=13字节
运行结果
我们现在来介绍相应的规则:

  1. 第一个成员在与结构体变量偏移量为0的地址处。
  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
    对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
    VS中默认的值为8
    Linux中没有默认对齐数,对齐数就是成员自身的大小
  3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
  4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
    体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
    看了没看懂,怎么办,看附图
    例1
    画图讲解

验证结果正确
例2
在这里插入图片描述
在这里插入图片描述

对齐规则
运行结果

默认对齐数的修改

法一

#pragma pack(8)//默认对齐数为8

法二
第一步
第二步

结构体传参

传参的方式是传值和传址
因为结构体大小可能很大,而指针的大小只有4/8个字节,而且地址更容易操作,所以使用传地址的方式进行传递

struct S
{
	int a;
	int b;
	char c;
};
int add(struct S* p)
{
	return p->a + p->b;
}

位段

注意事项

1.位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型
2.开辟的时候是根据类型的大小进行开辟的int—4字节,char—1字节
3.位段不能跨平台使用

位段的内存分配

我们已经学习了结构体的内存分配那么我们先来猜一猜位段的内存分配情况
位段空间开辟问题

#include<stdio.h>
struct S
{
	char a : 3;
	char b : 4;
	char c : 5;
	char d : 4;
};
int main()
{
	struct S s = { 10,12,3,4 };
	printf("struct S s:%d\n", sizeof(struct S));
	return 0;
}

运行结果
位段内存分配方式
每次申请1个字节,如果空间大小小于一个字节数那么每次都必须存储在同一个字节中,否则就需要重新开辟字节,就像c,d,使用c的时候还有3个bit位,但是下一个4bit大于剩余的bit位数,就要开辟新的空间进行存储
但是我们困惑的是他到底是从左向右使用空间的还是从右向左使用空间的呢???
根据观察,计算,vs2019是从左向右使用空间的最后的结果是
运行结果
但是有些编辑器会从右向左进行存储的,所以绝对不能进行跨平台的移植

枚举类型

enum Color
{
	RED,GREEN,WHITE,YELLOW
};

每一个元素都是枚举常量,每个常量都是从0开始递增,同时每个也是可以初始化的

enum Day
{
	MON=1,TUES,WED,THUR,FRI,SAT,SUN
};

在初始化之后的会按照初始化的进行递增
运行结果

注意事项

需要注意的是:枚举类型的变量只能使用枚举的值进行初始化

enum Color//颜色
{
 RED=1,
 GREEN=2,
 BLUE=4
};
enum Color clr = GREEN;//只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。
clr = 5;               //错误

c语言编译
c语言编译结果
c语言居然能编译的过去,你是不是耍我!!!
不要着急我们来看看c++能不能过得去
c++运行结果
我们发现了,因为c++检查的更加的严格,所以我们还是只能使用枚举常量进行赋值

联合体(共用体)

公用同一片空间

联合体的声明

union U
{
	int a;
	char b;
};
联合的成员是共用同一块内存空间的,这样一个联合变量的大小,
至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。

union内存分析
union un2运行结果
总结
struct很强大,要想彻底掌握还需要多多练习,慢慢感悟

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

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

相关文章

Spring的两种事务管理机制,面试这样答当场入职!

前言&#xff1a; 博主在最近的几次面试中&#xff0c;大中小厂都问到了Spring的事务相关问题&#xff0c;这块知识确实是面试中的重点内容&#xff0c;因此结合所看的书籍&#xff0c;在这篇文章中总结下。该专栏比较适合刚入坑Java的小白以及准备秋招的大佬阅读&#xff0c;感…

刻录到光盘功能看不见怎么办

刻录到光盘功能看不见怎么办 1、 打开组策略 同时按键WINR&#xff0c;打开运行对话框&#xff0c;输入gpedit.msc&#xff0c;打开组策略&#xff08;如果发现输入gpedit.msc后无法打开组策略&#xff0c;请参照文件后面的方法进行操作&#xff09; 2 、查找“删除CD刻录…

Java开发基础系列(五):对象方法参数

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; Java开发基础系列(五)&#xff1a;对象方法参数 ⏱️ 创作时间&#x…

Pycharm 搭建 Django 项目,看完这一篇就够了

1. 安装需求 在使用 python 框架 Django 需要注意下面事项 Pycharm 版本是专业版而不是社区版本Pycharm 配置好了 python 解释器 &#xff08;一般我们现在用的都是python3&#xff09;我自己使用的是 Pycharm 版本是2020.1.2 2. 准备工作 2.1 新建项目 首先我们打开 Pycharm …

opencv -10 基础运算之 图像加权和(图像融合图像修复视频合成)

什么是图像加权和&#xff1f; 所谓图像加权和&#xff0c;就是在计算两幅图像的像素值之和时&#xff0c;将每幅图像的权重考虑进来&#xff0c;可以用公式表示为&#xff1a; dst saturate(src1 &#x1d6fc; src2 &#x1d6fd; &#x1d6fe;)式中&#xff0c;satu…

无缝集成:基于FastAPI实现AI模型服务与nacos的完美融合

1 场景介绍 当我们使用python构建AI模型算法的过程中&#xff0c;经常会遇到如下的问题&#xff1a; 这个模型如何提供给其他微服务调用&#xff08;比如JAVA构建的微服务&#xff09;&#xff1f;这个模型如何做到多个服务节点的负载均衡&#xff1f;这个模型如何做到服务的…

Python高光谱遥感数据处理与高光谱遥感机器学习方法深度应用

提供一套基于Python编程工具的高光谱数据处理方法和应用案例。 本文涵盖高光谱遥感的基础、方法和实践。基础篇&#xff0c;用通俗易懂的语言解释高光谱的基本概念和理论&#xff0c;深入理解科学原理。方法篇结合Python编程工具&#xff0c;专注于解决高频技术难题&#xff0c…

工欲善其事,必先利其器之—react-native-debugger调试react native应用

调试react应用通常利用chrome的inspector的功能和两个最常用的扩展 1、React Developer Tools &#xff08;主要用于debug组件结构) 2、Redux DevTools &#xff08;主要用于debug redux store的数据&#xff09; 对于react native应用&#xff0c;我们一般就使用react-nativ…

C++无锁编程——无锁队列

C无锁编程——无锁队列 贺志国 2023.7.11 上一篇博客给出了最简单的C数据结构——堆栈的几种无锁实现方法。队列的挑战与栈的有些不同&#xff0c;因为Push()和Pop()函数在队列中操作的不是同一个地方。因此同步的需求就不一样。需要保证对一端的修改是正确的&#xff0c;且对…

TCP/IP网络编程 第十二章:I/O复用

基于I/O复用的服务器端 多进程服务器端的缺点和解决方法 为了构建并发服务器&#xff0c;只要有客户端连接请求就会创建新进程。这的确是实际操作中采用的种方案&#xff0c;但并非十全十美&#xff0c;因为创建进程时需要付出极大代价。这需要大量的运算和内存空间&#xff…

Vue列表排序

开始前先回顾一下sort排序用法&#xff1a; 定义一串数组arr&#xff0c;使用sort排序&#xff0c;会收到前后两个数据项设置两个参数a&#xff0c;b。 注意&#xff1a;a-b 是升序 b-a 是降序 a-b升序&#xff1a; <script>let arr [12,11,2,5,76,33]arr.sort((a,b…

家居商城小程序:打造舒适家居生活的优选平台

随着人们对家居生活品质的追求&#xff0c;家居商城小程序成为提供便捷购物和个性化服务的不可或缺的工具。通过家居商城小程序&#xff0c;用户可以浏览并购买各类家居商品&#xff0c;如家具、装饰品、家纺等。同时&#xff0c;家居商城小程序能提供热销商品推荐、客户评价和…

浅析高校用电问题及智慧电力监管平台的构建 安科瑞 许敏

摘 要&#xff1a;介绍了当前高校用电存在的问题&#xff0c;进行了原因分析&#xff0c;由此提出建立高校用电智慧监管平台。对高校用电智慧监管平台的构架进行设计&#xff0c;运用物联网技术&#xff0c;实现各回路实时自主控制&#xff0c;并细化管理权限&#xff0c;实现…

Swift 周报 第三十三期

文章目录 前言新闻和社区App 内购买项目和订阅即将实行价格与税率调整为家庭提供安全的 App 体验 提案正在审查的提案 Swift论坛推荐博文话题讨论关于我们 前言 本期是 Swift 编辑组自主整理周报的第二十四期&#xff0c;每个模块已初步成型。各位读者如果有好的提议&#xff…

公网访问的Linux CentOS本地Web站点搭建指南

文章目录 前言1. 本地搭建web站点2. 测试局域网访问3. 公开本地web网站3.1 安装cpolar内网穿透3.2 创建http隧道&#xff0c;指向本地80端口3.3 配置后台服务 4. 配置固定二级子域名5. 测试使用固定二级子域名访问本地web站点 前言 在web项目中,部署的web站点需要被外部访问,则…

常规函数和箭头函数之间的主要区别

常规函数和箭头函数之间的主要区别 在 JavaScript 中&#xff0c;函数是设计用于执行特定任务的代码块。函数允许使用函数将大型程序分解为多个更小、更易于管理的组件。因此&#xff0c;我们就不再需要重复编写相同的代码。 JavaScript中有两种类型的函数 常规函数箭头函数…

jmeter如何进行web脚本录制

目录 录制web脚本 &#xff08;1&#xff09;jmeter中设置HTTP代理 &#xff08;2&#xff09;浏览器中设置代理 &#xff08;3&#xff09;页面操作 &#xff08;4&#xff09;查看录制的web脚本 &#xff08;5&#xff09;脚本内容过滤 &#xff08;6&#xff09;脚本优化…

练习 数列前n项和(递归函数)

C++自学精简教程 目录(必读) 数列的前n项和 S = 1 + 2 + 3 + ...... + n 之前我们用for循环求解数列前n项和,本文用递归函数求解。 代码如下 #include <iostream> using namespace std;int f(int a) {if (a == 1){return 1;}else{return a + f(a - 1);} }int main(…

APP外包开发中的H5框架

在开发APP的技术中&#xff0c;除了原生开发外也可以使用H5框架来开发。原生开发的特点是质量高&#xff0c;用户体验更好&#xff0c;但成本高&#xff0c;适用于对质量要求高的APP项目。H5框架的特点是通用性较强&#xff0c;对开发人员的要求相对较低&#xff0c;成本也低&a…

从小众到大热:海外网红营销的成功之道

在当今数字时代&#xff0c;社交媒体已经成为人们获取信息、沟通交流的主要渠道之一。而在这个社交媒体的浪潮中&#xff0c;海外网红营销逐渐从小众走向大热。它以其独特的营销模式和广泛的受众群体&#xff0c;成为许多品牌和企业的首选营销方式。本文Nox聚星将详细介绍海外网…