阿里巴巴网站优化/新的数据新闻

阿里巴巴网站优化,新的数据新闻,如何搭建一个app,如何做公司的网站C语言中自定义类型 结构体结构体变量的创建和初始化结构体传参结构体内存对齐(如何存储) 联合体(共用体)联合体创建和初始化联合体大小(如何存储) 枚举类型枚举类型创建枚举类型初始化枚举的优点(相较于define) 前言 C语言中有内置类型和自定义类型,内置类型就像int…

C语言中自定义类型

  • 结构体
    • 结构体变量的创建和初始化
    • 结构体传参
    • 结构体内存对齐(如何存储)
  • 联合体(共用体)
    • 联合体创建和初始化
    • 联合体大小(如何存储)
  • 枚举类型
    • 枚举类型创建
    • 枚举类型初始化
    • 枚举的优点(相较于define)

前言
C语言中有内置类型和自定义类型,内置类型就像int 、double等等,其自带的一些类型,但有时候这些类型满足不了一些特定的要求,所以C语言也提供了一些自定义类型:结构体、联合、枚举


结构体

struct tag
{//结构体成员变量member-list;
}variable-list;//结构体变量名称
//可以在使用时候创建,也可以在创建结构体时创建

例如:创建一个学生的结构体

struct Stu {char name[20];int age;char sex[5];
}; //这里的分号不可以省略

这上面就相当于一个结构体的声明,创建了一个结构体类型,那如何使用呢?

结构体变量的创建和初始化

可以创建的同时初始化

struct Stu {char name[20];int age;char sex[5];
};int main() 
{
//创建结构体类型变量并初始化struct Stu s = { "张三",18,"male" };struct Stu s1 = {"lisi",18,"male"};
}
#include<stdio.h>
struct Stu {char name[20];int age;char sex[5];
};int main() 
{
//创建一个结构体变量并初始化struct Stu s = { "张三",18,"male" };printf("%s\n", s.name);printf("%d\n", s.age);printf("%s\n", s.sex);//可以使用指针来指向这个结构体,来进行访问struct Stu* p = &s;printf("%d\n", (*p).age);printf("%s\n", p->name);return 0;
}
这里使用变量名.结构体成员来访问
如果是一个指针指向一个结构体的话,有两种访问形式
变量名->成员变量
(*变量名).结构体成员

运行结果如下
在这里插入图片描述

结构体传参

结构体传参分为传值调用和传址调用

#include<stdio.h>
struct Stu {int age;char name[20];
};
//传值
void print1(struct Stu p)
{printf("%d\n", p.age);
}
//传址
void print2(struct Stu* p)
{printf("%d\n", (*p).age);
}
int main()
{struct Stu s = { 18,"sansan" };print1(s);print2(&s);return 0;
}

运行结果如下
在这里插入图片描述
传址调用可以修改结构体变量的值,但是传值调用则不可以

#include<stdio.h>
struct Stu {int age;char name[20];
};
//传值
void print1(struct Stu p)
{p.age = 19;
}
//传址
void print2(struct Stu* p)
{(*p).age = 20;
}
int main()
{struct Stu s = { 18,"sansan" };print1(s);printf("调用传值调用后age:%d\n", s.age);print2(&s);printf("调用传址调用后age:%d\n", s.age);return 0;
}

这里我们通过传值调用和传地址调用,发现这里的传地址调用可以修改结构体的变量的值,但是传值调用则不可以
在这里插入图片描述
结构体在进行传参的时候,传递地址比较好,因为如果传值调用的话,形参是实参的一份临时拷贝,如果这个结构体变量非常大,这可能在是将和空间上的开销比较大,所以传地址调用更好一点

结构体内存对齐(如何存储)

上面我们已经对结构体有所了解了,但是这有个新问题,结构体存储的时候是占多少字节呢?这就引出了:结构体内存对齐

对齐规则

1.结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处
2.剩下的成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。
这里的对⻬数=编译器默认的⼀个对⻬数与该成员变量⼤⼩整数倍的较⼩值
-VS 编译器中默认的值为 8
-Linux系统中gcc没有默认对⻬数,对⻬数就是成员⾃⾝的⼤⼩
3.结构体总⼤⼩为最⼤对⻬数(结构体中每个成员变量都有⼀个对⻬数,所有对⻬数中最⼤的)的整数倍。
4.如果嵌套了其他结构体的情况,嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处,这个结构体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体中成员的对⻬数)的整数倍
也就是要考虑结构体变量以及嵌套结构体变量其中的最大对齐数

我们就以下面这两个结构体来举例

#include<stdio.h>
struct S1
{char c1;int i;char c2;
};
struct S2
{char c1;char c2;int i;
};
int main()
{//计算S1与S2分别的字节大小printf("%zd\n", sizeof(struct S1));printf("%zd\n", sizeof(struct S2));return 0;
}

运行结果如下
在这里插入图片描述

从运行结果我们发现一个问题这里的结构体变量的大小,并不是简单的成员变量所占字节数相加,而是经过内存对齐得出的结果
S1 和 S2结构体带下分析如下

在这里插入图片描述


在这里插入图片描述
这里的两个结构体S1大小为12,S2大小8

嵌套类型的结构体总大小计算

#include<stdio.h>
struct S3
{double d;char c;int i;
};//结构体嵌套问题 
struct S4
{char c1;struct S3 s3;double d;
};
int main()
{printf("%zd\n", sizeof(struct S3));printf("%zd\n", sizeof(struct S4));return 0;
}

在这里插入图片描述


在这里插入图片描述
这里我们在VS2022这个编译器下,分析的结果是结构体S3的总大小是16,S4的总大小是32

运行结果如下
和我们推测一样
在这里插入图片描述
为什么要有这种对齐规则呢

1.平台原因(硬件原因)
不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,
否则出现硬件异常
2.性能原因
数据结构(尤其是栈)应该尽可能地在⾃然边界上对⻬,原因是这种访问需要访问两次,假设一个编译器只能8个地
地址进行存储,这样我们每次保证存储是8的倍数,这样就方便访问,提高效率
3.我们可以发现上面结构体就是按照对齐规则存储,这是为了快捷访问,相当于牺牲了一部分空间来换取时间

但是我们可以减少浪费
在这里插入图片描述
就像上面的两个结构体S1和S2,虽然成员变量的一样,但位置不同结果也不同,我们可以让占用小的空间尽量集中一起,这样可以节省空间

我们这里的VS2022有自己对齐规则,我们可以修改其 默认的对齐数,来改变其大小
#pragma 这个预处理指令,可以改变编译器的默认对⻬数

#include<stdio.h>
#pragma pack(1)//设置默认对⻬数为1 
struct S
{char c1;int i;char c2;
};int main()
{//输出的结果是什么? printf("%zd\n", sizeof(struct S));return 0;
}

在这里插入图片描述
我们如果按照VS编译器的话,这里的大小是12,但是我们这里设置默认对齐数为1,也就是每个变量是紧挨着存储,所以这里大小是其相加也就是6

联合体(共用体)

联合体创建和初始化

联合体和结构体类似,都是由多个成员组成,这些成员可以是不同类型
但是与结构体不同的是,联合体是所有成员共用同一块内存,所以联合体也叫做共用体

union tag
{//成员变量member-list;
}variable-list;

创建了一个共用体类型

#include<stdio.h>
union Un 
{char c1;int i;char c2;
};

共用体创建和初始化
以及共用体是所有成员占用一块内存吗?我们以下面这个代码来举例

union Un 
{char c1;int i;char c2;
};
int main()
{union Un un = { 0 };printf("%zd\n", sizeof(un));return 0;
}

运行结果如下
在这里插入图片描述
从结果上可以看出,它并不是连续存储,也不像结构体那样根据对齐原则存储,那他是如何存储的呢
上面的联合体的大小是4个字节,因为这里的最大成员变量是int 占4个字节,并且是最大对齐的数4的整数倍

联合体大小(如何存储)

联合体大小计算

联合的⼤⼩⾄少是最⼤成员的⼤⼩。
当最⼤成员⼤⼩不是最⼤对⻬数的整数倍的时候,就要对⻬到最⼤对⻬数的整数倍

那我们来看下面的代码

#include<stdio.h>
union Un1
{char c[5];int i;
};
union Un2
{short c[7];int i;
};
int main()
{//下⾯输出的结果是什么? //最大的是5,但又要是最大对齐数4的整数倍数,所以这里是8printf("%zd\n", sizeof(union Un1));//最大是14,但又要是最大对齐数4的整数倍,所以结果是16printf("%zd\n", sizeof(union Un2));return 0;
}

运行结果如下
在这里插入图片描述

在这里插入图片描述

他们真的是占用同一块内存吗?

#include<stdio.h>
union Un 
{char c1;int i;char c2;
};
int main()
{union Un un = { 0 };//%p是打印地址的,我们看他们是不是真的存储在同一内存printf("%p\n", &(un.c1));printf("%p\n", &(un.i));printf("%p\n", &(un.c2));return 0;
}

运行结果如下
在这里插入图片描述
从这个结果可以看出,共用体它们所占用的是同一个内存
这里如果修改一个成员数值有成员的结果就会改变

#include<stdio.h>
union Un 
{char c1;int i;char c2;
};
int main()
{union Un un = { 0 };//%p是打印地址的,我们看他们是不是真的存储在同一内存un.i = 200;printf("%d\n", un.c1);printf("%d\n", un.c2);printf("%d\n", un.i);return 0;
}

在这里插入图片描述

在这里插入图片描述
char类型的范围是-128 ~ 127,如果超过范围结果是怎样呢
在这里插入图片描述

虽然它们占用同一块内存,但所占的字节数不同,这也导致结果不一样,就像这里的char只会占1个字节8个比特位,而int占4个字节,32比特位,所以这里的char类型打印的和int类型数值不同

枚举类型

枚举顾名思义就是将其成员一一列举
就像生活中一年有12个月,一周有7天一样可以一一列举

枚举类型创建

enum Day//星期
{Mon,Tues,Wed,Thur,Fri,Sat,Sun
};
enum Color//三颜⾊
{Red,Green,Blue
};

这里的enum Day 和 enum Color都是枚举类型
{ }下都是可能取值,枚举常量
这些枚举常量都是从0开始,依次增加当然我们也可以给它赋值

枚举类型初始化

默认初始化
我们知道枚举常量都是从0开始,我们那上面的Color枚举来举例

#include<stdio.h>
enum Color//三颜⾊
{Red,//默认存储的是0Green,//1Blue//2
};
int main()
{//创建一个c来接收Redenum Color c = Red;printf("%d\n", c);//0printf("%d\n", Red);//0printf("%d\n", Green);//1printf("%d\n",Blue);//2return 0;
}

运行结果如下
在这里插入图片描述

从结果中可以看出,枚举常量是都是从0开始的,依次增加,并且创建的变量也是存储其常量值

为什么我们这里是说这是枚举常量
在这里插入图片描述

这里我们给枚举常量进行修改,发现是不可以的,因为常量值是不可以修改的,枚举常量是常量

就地初始化
全部初始化

#include<stdio.h>
enum Color//三颜⾊
{Red = 1,Green = 3,Blue = 7
};
int main()
{printf("%d\n", Red);printf("%d\n", Green);printf("%d\n",Blue);return 0;
}

这里我们对Color这个枚举中的枚举常量全部都初始化了,但是不可以在枚举类型外部修改
运行结果如下
在这里插入图片描述
那如果我们只是部分初始化

#include<stdio.h>
enum Color//三颜⾊
{Red = 1,Green,Blue
};
int main()
{printf("%d\n", Red);printf("%d\n", Green);printf("%d\n",Blue);return 0;
}

这里原本第一个是从0开始的,但是我们初始化为1,但是依旧满足依次增加的原则,所以结果为
在这里插入图片描述
那我们只修改中间的呢,依然满足上面依次增加的规则,如果初始化的话,按照初始化的值
就像下面这个,我们只初始化了前面两个枚举常量,那第三个常量值就是第二个常量值+1
在这里插入图片描述

枚举的优点(相较于define)

我们可以使⽤ #define 定义常量,为什么⾮要使⽤枚举?
就像上面的代码,我们用#define来写

#include<stdio.h>
#define Red 1
#define Green 2
#define Blue 3
int main()
{printf("%d\n", Red);printf("%d\n", Green);printf("%d\n", Blue);return 0;
}

运行结果如下,可以生成与枚举类型相同的结果
我们可以发现这里的#define每次只能定义一个,而枚举类型一个可以定义多个对象
在这里插入图片描述

枚举的优点
1.可以增强代码的可读性 ,因为define只是简单的代码替换,无法调试观察
2.和#define使用枚举比较严谨
3.方便使用,可以连续创建多个常量,而#define依次只能定义一个

到这里就结束了,希望大家有所帮助,欲知后事如何,请听下回分解

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

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

相关文章

【Linux操作系统——学习笔记二】Linux简单导航命令操作

一、前言 学习Linux&#xff0c;本质上是学习在命令行下熟练使用Linux的各类命令。 命令行&#xff1a;是一种通过输入命令和参数与计算机系统进行交互的方式&#xff0c;可以使用各种字符化命令对系统发出操作指令&#xff0c;打开Linux终端&#xff0c;进入命令行界面。 …

新安装的cursor安装不了插件

我安装的cursor版本0.47.5 直接说解决办法 找到安装路径cursor\resources\app下的product.json 修改https://marketplace.cursorapi.com为https://marketplace.visualstudio.com

HTML5扫雷游戏开发实战

HTML5扫雷游戏开发实战 这里写目录标题 HTML5扫雷游戏开发实战项目介绍技术栈项目架构1. 游戏界面设计2. 核心类设计 核心功能实现1. 游戏初始化2. 地雷布置算法3. 数字计算逻辑4. 扫雷功能实现 性能优化1. DOM操作优化2. 算法优化 项目亮点技术难点突破1. 首次点击保护2. 连锁…

Qt之自定义界面组件 一

通过qt中的painter绘图事件绘制一个电池电量图的变化。效果如下图 创建一个基于界面widget工程&#xff0c;在wdiget界面添加一个widget界面,将添加的widget界面的类提升为Tbattery.在Tbattery类中重写painEvent电池电量代码 文件目录结构 主要部分代码 //Tbattery.cpp #inc…

LeRobot源码剖析——对机器人各个动作策略的统一封装:包含ALOHA ACT、Diffusion Policy、VLA模型π0

前言 过去2年多的深入超过此前7年&#xff0c;全靠夜以继日的勤奋&#xff0c;一天当两天用&#xff0c;抠论文 抠代码 和大模型及具身同事讨论&#xff0c;是目前日常 而具身库里&#xff0c;idp3、π0、lerobot值得反复研究&#xff0c;故&#xff0c;近期我一直在抠π0及l…

数据结构篇——线索二叉树

一、引入 遍历二叉树是按一定规则将二叉树结点排成线性序列&#xff0c;得到先序、中序或后序序列&#xff0c;本质是对非线性结构线性化&#xff0c;使结点&#xff08;除首尾&#xff09;在线性序列中有唯一前驱和后继&#xff1b;但以二叉链表作存储结构时&#xff0c;只能获…

汽车保养记录用什么软件记录,汽车维修记录查询系统,佳易王汽车保养维护服务记录查询管理系统操作教程

一、概述 本实例以佳易王汽车保养维护服务记录查询管理系统为例说明&#xff0c;其他版本可参考本实例。试用版软件资源可到文章最后了解&#xff0c;下载的文件为压缩包文件&#xff0c;请使用免费版的解压工具解压即可试用。 软件特点&#xff1a;1、功能实用&#xff0c;操…

Python IP解析器 ip2region使用

说明&#xff1a;最近需要在python项目内使用IP定位所在城市的需求&#xff0c;没有采用向外部ISP服务商API请求获取信息的方案&#xff0c;则翻了翻&#xff0c;在搞Java时很多的方案&#xff0c;在Python端反而可选择范围很小。 # 示例查询 ips ["106.38.188.214"…

python开发订单查询功能(flask+orm bee)

1. 搭建python环境。 可以参考其它文档。 此处python使用 3.12 IDE随意&#xff0c;PyCharm 或 Eclipse PyDev也可以。 2. Flask 2.1 安装Flask pip install Flask 2.2 一个最简单的flask实例 创建一个工程&#xff0c; 新建一个 main.py文件&#xff0c; 输入以下内容…

哈尔滨服务器租用托管流程

哈尔滨服务器租用托管流程可分为三个阶段实施&#xff0c;具体操作如下&#xff1a; 一、前期准备阶段 业务需求评估 明确计算资源需求&#xff1a;CPU核心数/线程数、内存容量、存储类型(HDD/SSD/NVMe)及容量、带宽标准(独享/共享) 确定网络架构要求&#xff1a;多线接入、国际…

音频大语言模型可作为描述性语音质量评价器

论文《AUDIO LARGE LANGUAGE MODELS CAN BE DESCRIPTIVE SPEECH QUALITY EVALUATORS》学习 推动多模态代理从"能听"到"懂好坏"的进化 摘要&#xff1a; . 研究背景与问题 核心内容&#xff1a;现有音频大语言模型缺乏对输入语音质量的感知能力&#xff…

我在哪,要去哪

在直播间听到一首好听的歌《我在哪&#xff0c;要去哪》-汤倩。 遇见的事&#xff1a;21~24号抽调去招生。 感受到的情绪&#xff1a;公假吗&#xff1f;给工作量吗&#xff1f;月工作量不够扣钱吗&#xff1f;报销方便吗&#xff1f;有事情&#xff0c;从来不解决后顾&#x…

某快餐店用户市场数据挖掘与可视化

1、必要库的载入 import pandas as pd import matplotlib.pyplot as plt import seaborn as sns2、加载并清洗数据 # 2.1 加载数据 df pd.read_csv(/home/mw/input/survey6263/mcdonalds.csv)# 2.2 数据清洗 # 2.2.1 检查缺失值 print(缺失值情况&#xff1a;) print(df.isn…

Easysearch 索引生命周期管理实战

如果你的使用场景是对时序型数据进行分析&#xff0c;可能你会更重视最新的数据&#xff0c;并且可能会定期对老旧的数据进行一些处理&#xff0c;比如减少副本数、forcemerge、 删除等。Easysearch 的索引生命周期管理功能&#xff0c;可以自动完成此类索引的管理任务。 创建…

Modbus通信协议基础知识总结

1. 数据类型与存储区分类 Modbus协议将数据分为四类存储区&#xff0c;通过存储区代号区分&#xff1a; 输出线圈&#xff08;0x&#xff09;&#xff1a;可读写&#xff0c;对应二进制开关量&#xff08;如继电器状态&#xff09;&#xff0c;地址范围000001-065536&#xff…

LeetCode 2614.对角线上的质数:遍历(质数判断)

【LetMeFly】2614.对角线上的质数&#xff1a;遍历(质数判断) 力扣题目链接&#xff1a;https://leetcode.cn/problems/prime-in-diagonal/ 给你一个下标从 0 开始的二维整数数组 nums 。 返回位于 nums 至少一条 对角线 上的最大 质数 。如果任一对角线上均不存在质数&…

linux 安全 xshell 使用

目录和文件 ls -l 查看目录和文件的权限的设置情况 加固方法 对于重要目录&#xff0c;建议执行如下类似操作 Chmod -R 750 /etc/rc.d/init.d/* 这样只有root可以读写和执行这个目录下的脚本 新建了一个用户Q 写入了一些信息 发现在root用户下可以进行文件打开 接下来用普通用…

自动驾驶背后的数学:特征提取中的线性变换与非线性激活

在上一篇博客「自动驾驶背后的数学&#xff1a;从传感器数据到控制指令的函数嵌套」—— 揭秘人工智能中的线性函数、ReLU 与复合函数中&#xff0c;我们初步探讨了自动驾驶技术中从传感器数据到控制指令的函数嵌套流程&#xff0c;其中提到了特征提取模块对传感器数据进行线性…

杨校老师课堂之编程入门与软件安装【图文笔记】

亲爱的同学们&#xff0c;热烈欢迎踏入青少年编程的奇妙世界&#xff01; 我是你们的授课老师杨校 &#xff0c;期待与大家一同开启编程之旅。 1. 轻松叩开编程之门 1.1 程序的定义及生活中的应用 程序是人与计算机沟通的工具。在日常生活中&#xff0c;像手机里的各类 APP、电…

DeepSeek 3FS 与 JuiceFS:架构与特性比较

近期&#xff0c;DeepSeek 开源了其文件系统 Fire-Flyer File System (3FS)&#xff0c;使得文件系统这一有着 70 多年历时的“古老”的技术&#xff0c;又获得了各方的关注。在 AI 业务中&#xff0c;企业需要处理大量的文本、图像、视频等非结构化数据&#xff0c;还需要应对…