自定义类型详解(上)
结构体
1 结构体的声明
1.1 结构的基础知识
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
1.2 结构的声明
struct tag//struct是结构体的标志,tag是标签;名字。
{member-list;//成员变量
}variable-list;//变量列表
struct Stu
{char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号
}; //分号不能丢 #define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
struct Stu
{//成员变量char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号}s4,s5,s6;//分号不能丢 //全局变量
int main()
{struct Stu s1;//局部变量struct Stu s2;struct Stu s3;return 0;
} 这里的是s1,s2,s3,s4,s5,s6基本都是一样的,唯一不同的是一个是全局变量,另一个是局部变量。
1.3 特殊的声明
在声明结构的时候,可以不完全的声明。
//匿名结构体类型
struct
{int a;char b;float c;
}x;
struct
{int a;char b;float c;
}a[20], *p; 上面的两个结构在声明的时候省略掉了结构体标签( tag )。那么问题来了?
//在上面代码的基础上,下面的代码合法吗?
p = &x;
警告:编译器会把上面的两个声明当成完全不同的两个类型。(即使它们的成员变量相同且都是匿名结构体类型)所以是非法的。
1.4 结构的自引用
在结构中包含一个类型为该结构本身的成员是否可以呢?

//代码1
struct Node
{int data;struct Node next;
};
//可行否?
如果可以,那sizeof(struct Node)是多少?
不行,因为已经有个data的数据了,你再加个next的数据,就乱套了,没有下一个地址接收,所以会一直循环下去。大小无法求。
正确的自引用方式:
//代码2
struct Node
{int data;struct Node* next;
};
struct Node
{int data;//4struct Node* next;//4/8
};int main()
{struct Node n1;struct Node n2;n1.next = &n2;return 0;
}
补:
typedef struct
{int data;char c;
} S;
这里用typedef struct中typedef的使用:这个结构体的S是该结构体的类型名。没有typedef的话,该S则是一个变量。
//代码3
typedef struct
{int data;Node* next;
}Node;
//这样写代码,可行否?
//不行 因为都还没有完整的Node就直接在后面Node 前后矛盾了
//解决方案:
typedef struct Node
{int data;struct Node* next;
}Node;
1.5 结构体变量的定义和初始化
有了结构体类型,那如何定义变量?
struct Point
{int x;int y;
}p1; //声明类型的同时定义变量p1
struct Point p2; //定义结构体变量p2
//初始化:定义变量的同时赋初值。
struct Point p3 = {x, y};
struct Stu //类型声明
{char name[15];//名字int age; //年龄
};
struct Stu s = {"zhangsan", 20};//初始化
struct Node
{int data;struct Point p;struct Node* next;
}n1 = {10, {4,5}, NULL}; //结构体嵌套初始化
struct Node n2 = {20, {5, 6}, NULL};//结构体嵌套初始化

(.)操着直接访问
结构体里面定义指针
struct S
{char name[100];int* ptr;
};
int main()
{struct S s = { "abcdef",NULL };return 0;
}
1.6 结构体内存对齐
我们已经掌握了结构体的基本使用了。现在我们深入讨论一个问题:计算结构体的大小。这也是一个特别热门的考点: 结构体内存对齐。
为什么上图的s1,s2,s3的打印结果是8,12,12? 为什么不是按照类型大小打印?为什么不是打印5,6,7? 往下看......
结构体存放内存是要对齐的!!
考点如何计算 ?首先得掌握结构体的对齐规则:1. 第一个成员在与结构体变量偏移量为 0 的地址处。2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。对齐数 = 编译器默认的一个对齐数 与 该成员大小的 较小值 。VS 中默认的值为 83. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
//练习1 struct S1 {char c1;int i;char c2; }; printf("%d\n", sizeof(struct S1)); //练习2 struct S2 {char c1;char c2;int i; }; printf("%d\n", sizeof(struct S2)); //练习3 struct S3 {double d;char c;int i; }; printf("%d\n", sizeof(struct S3));![]()
为什么存在内存对齐 ?大部分的参考资料都是如是说的:1. 平台原因 ( 移植原因 ) :不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。2. 性能原因 :数据结构 ( 尤其是栈 ) 应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。总体来说:结构体的内存对齐是拿 空间 来换取 时间 的做法。
那在设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到:让占用空间小的成员尽量集中在一起。//例如: struct S1 {char c1;int i;char c2; }; struct S2 {char c1;char c2;int i; };S1 和 S2 类型的成员一模一样,但是 S1 和 S2 所占空间的大小有了一些区别。
1.7 修改默认对齐数
之前我们见过了 #pragma 这个预处理指令,这里我们再次使用,可以改变我们的默认对齐数。
#include <stdio.h>
#pragma pack(8)//设置默认对齐数为8
struct S1
{char c1;int i;char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
#pragma pack(1)//设置默认对齐数为1
struct S2
{char c1;int i;char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
int main()
{//输出的结果是什么?printf("%d\n", sizeof(struct S1));printf("%d\n", sizeof(struct S2));
return0;
}

结论:结构在对齐方式不合适的时候,我么可以自己更改默认对齐数。
1.8 结构体传参
直接上代码:
struct S
{int data[1000];int num;
};
struct S s = {{1,2,3,4}, 1000};
//结构体传参
void print1(struct S s)
{printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{printf("%d\n", ps->num);
}
int main()
{print1(s); //传结构体print2(&s); //传地址return 0;
}
上面的 print1 和 print2 函数哪个好些?答案是:首选 print2 函数。原因:函数传参的时候,参数是需要压栈,会有时间和空间上的系统开销。如果传递一个结构体对象的时候,结构体过大,参数压栈的的系统开销比较大,所以会导致性能的 下降。
结论:结构体传参的时候,要传结构体的地址。
THE END
这是今日份关于自定义函数的一些分享,希望可以帮助到大家!如果有什么不足的地方也请家人们给小叶一些好的建议,我会不断优化文章的!那就让我们一起加油吧!哈哈哈哈哈
相关文章:
自定义类型详解(上)
结构体 1 结构体的声明 1.1 结构的基础知识 结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。 1.2 结构的声明 struct tag//struct是结构体的标志,tag是标签;名字。 {member-list;//成员变量 }variable-list;//变量列…...
【数据库——MySQL】(9)函数、查询练习及讲解
目录 1. 题目1.1 函数练习1.2 数据库查询 2. 解答2.1 函数练习2.2 数据库查询 1. 题目 1.1 函数练习 求圆周率的值,保留 6 位小数。生成两个 100 到 200 间的随机数。将”武汉大学”,”数学学院”,”计算数学”连接成一个字符串。求字符串中第三个字符为 A 的所有…...
【数据结构与算法——C语言】“串操作与算法”之“找出最长串及其长度”
目录 1. 实验内容及上机实验所用平台1.1 实验内容1.2 实验平台软件 2. 流程图3. 源代码4. 用例测试5. 实验总结 1. 实验内容及上机实验所用平台 1.1 实验内容 【问题描述】 给定两个字符串 s1 和 s2,求最长的 s1 前缀 ss 使得 ss 为 s2 的最长后缀,输出…...
泡泡玛特:一家中国潮玩品牌的出海之旅
泡泡玛特的出海之旅,可以为中国出海企业提供怎样的启示和借鉴? 中国潮玩品牌的出海之旅 如果在年轻人群体中聊起泡泡玛特,那么估计无人不知无人不晓。这家成立于2010年的潮玩企业,凭借琳琅满目让消费者爱不释手的创新产品…...
淘宝商品sku信息抓取接口api
在电商行业中,SKU是一个经常被使用的术语,但是对于很多人来说,这个词可能还比较陌生。在这篇文章中,我们将详细解释什么是SKU,以及在电商业务中它的作用和意义。 什么是SKU? SKU是“Stock Keeping Unit”…...
MySQL 多表关系(多表查询 一)
多表关系描述 MySQL是一种关系型数据库管理系统,它支持多表关系,这在数据库设计和查询中非常重要。 项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务…...
【面试高高手】——JavaIO篇(23题)
文章目录 1.什么是Java IO?2.如何从数据传输方式理解IO流?3.Java IO设计上使用了什么设计模式?4.什么是Java NIO?5.什么时BIO?6.什么是AIO?7.你怎么理解同步IO和异步IO?8.你怎么理解阻塞IO和非阻塞IO?9.IO中的输入流和输出流有…...
图像采集 deep OCR
按照芯片类型可以分为CCD相机、CMOS相机 按照传感器的结构特性可以分为线阵相机、面阵相机 按照扫描方式可以分为隔行扫描相机、逐行扫描相机 按照分辨率大小可以分为普通分辨率相机、高分辨率相机按照输出信号方式可以分为模拟相机、数字相机 按照输出色彩可以分为单色(黑白)相…...
Linux 终端命令总结
一、常用的七条命令 命令 对应英文作用lslist查看当前文件夹下的内容pwdprint work directory查看当前所在文件夹cd [目录名]change directory切换文件夹 touch [文件名]touch如果文件不存在新建文件mkdir [目录名]make directory创建目录rm[文件名]remo…...
中国核动力研究设计院使用 DolphinDB 替换 MySQL 实时监控仪表
随着仪表测点的大幅增多和采样频率的增加,中国核动力研究设计院仪控团队原本基于 MySQL 搭建的旧系统已经无法满足大量数据并发写入、实时查询和聚合计算的需求。他们在研究 DB-Engines 时序数据库榜单时了解到国内排名第一的 DolphinDB。经过测试,发现其…...
速看!软考中项100条重要知识点集锦!
1. 项目的特点有哪些? 2. 项目的组织方式有哪些?分别具有什么优缺点? 3. 项目管理过程组有哪些? 4. 怎么样才能成为一位优秀的项目经理? 5. PMO的主要职能有哪些? 6. 项目经理(PMÿ…...
Pycharm在进行debug时出现collecting data如何解决?
Pycharm在进行debug时变量界面出现collecting data,问题如下: 解决方法:打开Setting界面,在Python Debugger选项中勾选下图中的Gevent compatible即可。...
【算法分析与设计】算法概述
目录 一、学习要点二、算法的定义三、算法的性质四、程序(Program)五、问题求解(Problem Solving)六、算法的描述七、算法分析的目的八、算法复杂性分析(一)算法时间复杂性分析(二)算法渐近复杂性1、渐进上界记号-大O符号2、渐进下…...
如何进一步全面提高项目估算精准度?
项目估算非常重要,这直接关系着项目的成本和收入,如果估算不准确,将为项目带来较大风险。一般软件规模可以用多种方式进行估算,但是用功能点估算方式更准确,而自动估算让估算更快速,我们以CoCode开发的估算…...
Git学习笔记4
GitHub是目前最火的开源项目代码托管平台。它是基于web的Git仓库,提供公有仓库和私有仓库,但私有仓库是需要付费的。 到Github上找类似的项目软件。 GitLab可以创建免费的私有仓库。 GitLab是利用 Ruby开发的一个开源的版本管理系统,实现一个…...
【红外与可见光图像融合】离散平稳小波变换域中基于离散余弦变换和局部空间频率的红外与视觉图像融合方法(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
成都睿趣科技:抖音开通橱窗带货需要钱吗
随着社交媒体和电子商务的蓬勃发展,抖音作为一种流行的短视频平台,也推出了自己的“抖音橱窗”功能,让内容创作者能够通过视频展示和销售产品,从而实现商业化。那么,抖音橱窗带货是否需要费用呢? 首先,要开…...
中间件 - 分布式协调服务Zookeeper
目录 一. 前言 二. 树状结构 2.1. ZNode 2.1.1. stat 2.1.2. ACL 三. NameService命名服务 四. Configuration 配置管理 五. GroupMembers 集群管理 六. 集群三个角色及状态 七. 选举算法 八. Watcher 九. 设计目的 十. 典型使用场景 一. 前言 Zookeeper是一个分布…...
golang的实用工具
golang的实用工具 Go 语言提供了许多实用的工具,以下是其中一些常用的工具: 1. go run:用于直接运行 Go 源代码文件,无需显式编译。 2. go build:用于将 Go 代码编译成可执行文件或库。 3. go test:用于…...
图层混合模式(三)
差值模式 差值模式:查看每个通道的数值,用基色减去混合色或用混合色减去基色。具体取决于混合色与基色那个通道的数值更大。白色与任何颜色混合得到反相色,黑色与任何颜色混合颜色不变。 计算公式:结果色 绝对值(混合…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...




