深度解析Linux-C——结构体(初始化,结构体数组,结构体大小,位段操作,联合体,内存对齐,C的预处理,宏和带参宏,条件编译)

目录

结构体的三种初始化

结构体的两种引用

结构体数组

结构体大小

结构体实现位段操作

联合体

 内存对齐

C的预处理

 带参宏

 条件编译


结构体的三种初始化

定义如下结构体

struct  student 
{char name[100];  int age;  float  height;   
} ;

 1、定义变量时初始化

struct  student  xm = {"小明",18,175.3}

2、不按顺序的初始化

struct  student  xm ={.age=18, .height=175.3, .name="小明"};

3、在定义后初始化

struct  student  xm;
//xm.name = "小明"; // name是数组名是一个常量,常量不能赋值  
strcpy(xm.name,"小明");
xm.age = 18; 
xm.height=173.5;

 

结构体的两种引用

1、结构体变量是普通值时,使用变量名+  “   .   ”   访问

2、结构体变量是指针时,使用指针+   “   ->   ”   访问

结构体数组

定义:

struct student
{char name[1024]; // 姓名int id;          // 学号char clas[1024]; // 班级
};

初始化: 

struct student arry[50] = 
{{"小明", 1, "高一三班"},{"小东", 2, "高二三班"},{"小美", 3, "高三三班"},
};

 

结构体大小

结构体大小是根据 《最大的数据字节》对齐的原则进行分配的! 每次数据分配的空间都是《根据最大的字节数》进行对齐。

 参考:【C语言】结构体内存对齐_编译器默认对齐数-CSDN博客

结构体实现位段操作

位段操作允许程序员直接操作数据的特定位,而不是整个数据结构

从而在需要精确控制硬件或进行高效数据处理时非常有用。

 

带位段操作的结构体的大小

 

联合体

联合体的外在形式跟结构体非常类似,但它们有一个本质的区别:

结构体中的各个成员是各自独立的,而联合体中的各个成员却共用同一块内存,因此联合体也称为共用体。

整个联合体变量的尺寸,取决于联合体中尺寸最大的成员。

给联合体的某个成员赋值,会覆盖其他的成员,使它们失效。

联合体各成员之间形成一种“互斥”的逻辑,在某个时刻只有一个成员有效。

声明联合体:

union attr
{int x;char y;double z;  
};

定义联合体:

int main()
{// 定义联合体变量union attr n;
}// 普通初始化:第一个成员有效(即只有100是有效的,其余成员会被覆盖)
union attr at = {100, 'k', 3.14};// 指定成员初始化:最后一个成员有效(即只有3.14是有效的,其余成员会被覆盖)
union attr at = {.x  = 100,.y = 'k',.z = 3.14,
};

 联合体指针

union attr *p = &at;
p->x = 100;
p->y = 'k';
p->z = 3.14;  // 只有最后一个赋值的成员有效printf("%d\n", p->x);
printf("%c\n", p->y);
printf("%lf\n", p->z);

 内存对齐

1.修改一个数据的对齐原则 

char c __attribute__((aligned(32))); // 将变量 c 的值、内存对齐值设置为32   

attribute语法:
attribute 机制是GNU特定语法,属于C语言标准语法的扩展。
attribute 前后都是双下划线,aligned两边是双圆括号。
attribute 语句,出现在变量定义语句中的分号前面,变量标识符后面。
attribute 机制支持多种属性设置,其中 aligned 用来设置变量的 m 值属性。
一个变量的内存对齐值只能提升,不能降低,且只能为正的2的n次幂

2.不适用任何的对齐原则 ,直接以真实大小存储 

 __attribute__((packed));

内存对齐,是为了CPU 更高效率取读取,内存的资源进行处理。 修改空间虽然可以节省内存,但是会降低CPU的处理效率。
 

C的预处理

头文件:#include

定义宏:#define

取消宏:#undef

条件编译:#if、#ifdef、#ifndef、#else、#elif、#endif

显示错误:#error

修改当前文件名和行号:#line

向编译器传送特定指令:#progma

一个逻辑行只能出现一条预处理指令,多个物理行需要用反斜杠连接成一个逻辑行

如:

#define LONG_MACRO_NAME \
this is a long macro definition \
that spans multiple lines

 将    LONG_MACRO_NAME   替换为   this is a long macro definition that spans multiple lines

 可以通过如下编译选项来指定来限定编译器只进行预处理操作:

gcc example.c -o example.i -E

 带参宏

//使用 pf 来替换 printf("%d",参数);
#define  pf(参数)  printf("%d",参数);// 求两个数据的较大值
#define max(a, b) a > b ? a : b// 求两个数据的较小值
#define min(a, b) a < b ? a : b

注意事项:

带参宏的特点:

直接文本替换,不做任何语法判断,更不做任何中间运算。

宏在编译的预处理阶段就被替换掉,运行中不存在宏。

宏将在所有出现它的地方展开,这一方面浪费了内存空间,另一方面有节约了切换时间。

 使用双井号粘贴字串

#define LAYER_INITCALL(num, layer)  __zinitcall_##layer##_##num

如果使用 LAYER_INITCALL(service, 1),那么预处理器会将其展开为 __zinitcall_service_1;如果使用 LAYER_INITCALL(feature, 2),则会展开为 __zinitcall_feature_2。

如果字串出现在最末尾,则最后的双井号必须去除,如果粘贴的字串并非出现在最末尾,则前后都必须加上双井号

另外,如果字串本身拼接为字符串,那么只需要使用一个井号即可

例如:

#define domainName(a, b) "www." #a "." #b ".com"
int main()
{printf("%s\n", domainName(baidu, aaa));
}//输出www.baidu.aaa.com

 

 条件编译

#define A 0
#define B 1
#define C 2#if Aprintf("真");
#endif// 二路分支
#if Aprintf("A");
#elif Bprintf("B");
#endif// 多路分支
#if Aprintf("A");
#elif Bprintf("B");
#elif Cprintf("C");
#endif

 ifndef和endif语句判断头文件中函数是否被重复定义

如对C的标准库进行定义时:

#ifndef stdio
#define stdiovoid printf。。。。。。scanf。。。。。。int。。。。。。float。。。#endif

有时候多个头文件中包含了相同的函数声明或定义,或者一个程序中重复引用了某些头文件,这样做是为了防止其被重复引用
 

参考:
c语言结构体一篇懂_1.结构体变量的第一个成员在与结构体变量偏移量为0的地址处。-CSDN博客

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

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

相关文章

Redis从入门到超神-(十二)Redis监听Key的过期事件

前言 试想一个业务场景&#xff0c;订单超过30分钟未支付需要做自动关单处理,修改订单状态&#xff0c;库存回退等&#xff0c;你怎么实现&#xff1f;方案一&#xff1a;可以使用定时任务扫表&#xff0c;通过支付状态和下单时间来判断是否支付过期。但是这样的方案是非常消耗…

推荐一款.NET开源、简洁易用的Windows桌面小说阅读应用

前言 今天大姚给大家分享一款.NET开源、免费、简洁易用的Windows桌面小说阅读应用(是原生的 Windows 应用&#xff0c;为 Windows 11 系统设计)&#xff1a;CleanReader.Desktop。 该应用适合喜欢阅读网文或者是本地轻量阅读的用户。 系统要求 操作系统&#xff1a;Windows 11…

Llama + Dify,在你的电脑搭建一套AI工作流

theme: smartblue 点赞 关注 收藏 学会了 本文简介 最近字节在推Coze&#xff0c;你可以在这个平台制作知识库、制作工作流&#xff0c;生成一个具有特定领域知识的智能体。 那么&#xff0c;有没有可能在本地也部署一套这个东西呢&#xff1f;这样敏感数据就不会泄露了&…

Linux之基础IO(下)

目录 缓冲区的概念 深入理解文件系统 创建文件的整个过程 软链接 硬链接 上一节课我们学习了基础IO中的文件的读写操作&#xff0c;以及文件描述符的概念和重定向的基本原理&#xff0c;本期我们继续进行基础IO的学习。 缓冲区的概念 在讲缓冲区之前&#xff0c;大家先看…

Redis实战篇(黑马点评)笔记总结

一、配置前后端项目的初始环境 前端&#xff1a; 对前端项目在cmd中进行start nginx.exe&#xff0c;端口号为8080 后端&#xff1a; 配置mysql数据库的url 和 redis 的url 和 导入数据库数据 二、登录校验 基于Session的实现登录&#xff08;不推荐&#xff09; &#xf…

C++ - char*、const char*、char[]、string

const char* const char* 用来定义字符串常量。 char[ ] char型的字符数组是一种定长的数组&#xff0c;存储指定长度的字符序列&#xff0c;数组中的每个元素都是一个char类型的变量&#xff0c;如&#xff1a; char arr[] {h, a, l, l, o, \0}; char c arr[0]; // 访问…

使用 Windows 应用程序 SDK 构建下一代应用程序

微软面临的最大问题之一是如何让 Windows 再次成为吸引开发者的平台。无论用户使用什么设备和操作系统&#xff0c;都可以很容易地将 Web 前端放在支持桌面和移动用户的云原生应用程序上。 我们处在一个奇怪的境地&#xff0c;唯一能利用最新 PC 硬件的应用程序是 Office、Phot…

【中项第三版】系统集成项目管理工程师 | 第 11 章 规划过程组⑤ | 11.13 - 11.14

前言 第11章对应的内容选择题和案例分析都会进行考查&#xff0c;这一章节属于10大管理的内容&#xff0c;学习要以教材为准。本章上午题分值预计在15分。 目录 11.13 制定预算 11.13.1 主要输入 11.13.2 主要输出 11.14 规划质量管理 11.14.1 主要输入 11.14.2 主要工…

HTML前端面试题之<iframe>标签

面试题&#xff1a;iframe 标签的作用是什么?有哪些优缺点 ? 讲真&#xff0c;刷这道面试题之前我根本没有接触过iframe&#xff0c;网课没讲过&#xff0c;项目实战没用过&#xff0c;但却在面试题里出现了&#xff01;好吧&#xff0c;我只能说&#xff1a;前端路漫漫&…

数据挖掘-数据预处理

来自&#x1f96c;&#x1f436;程序员 Truraly | 田园 的博客&#xff0c;最新文章首发于&#xff1a;田园幻想乡 | 原文链接 | github &#xff08;欢迎关注&#xff09; 文章目录 3.3.1 数据的中心趋势平均数和加权平均数众数&#xff0c;中位数和均值描述数据的离散程度 &a…

快速搞定分布式RabbitMQ---RabbitMQ进阶与实战

本篇内容是本人精心整理&#xff1b;主要讲述RabbitMQ的核心特性&#xff1b;RabbitMQ的环境搭建与控制台的详解&#xff1b;RabbitMQ的核心API&#xff1b;RabbitMQ的高级特性;RabbitMQ集群的搭建&#xff1b;还会做RabbitMQ和Springboot的整合&#xff1b;内容会比较多&#…

火山引擎云搜索服务通过信通院向量数据库可信认证

7月16日&#xff0c;首届线下“可信数据库发展大会”在北京举办&#xff0c;会上中国信息通信研究院&#xff08;中国信通院&#xff09;公布了 2024 上半年“可信数据库”产品能力评测结果。火山引擎云搜索服务在基本功能、运维管理、安全性、兼容性、扩展性、高可用、工具生态…

【LeetCode 随笔】C++入门级,详细解答加注释,持续更新中。。。

文章目录 58.【简单】最后一个单词的长度&#x1f31f; &#x1f308;你好呀&#xff01;我是 山顶风景独好 &#x1f388;欢迎踏入我的博客世界&#xff0c;能与您在此邂逅&#xff0c;真是缘分使然&#xff01;&#x1f60a; &#x1f338;愿您在此停留的每一刻&#xff0c;都…

Html+Css网页开发之动态登录页面(默认Chrome)

>>效果展示图<< 一、需求分析与设计要求 实现了一个动态背景图案的效果&#xff0c;包括一个白色的容器&#xff0c;内部有一个标题、一个输入框、一个按钮和一些文本。 背景是一个渐变色的线性渐变&#xff0c;而在容器的周围&#xff0c;有一些随机的方形和圆形图…

Element快速学习

博客主页&#xff1a;音符犹如代码系列专栏&#xff1a;JavaWeb关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 什么是Element&#xff1f; Element&#xff1a;它是由饿了么团队开发的一个…

Dubbon-微服务通信(基本简介 基础实现)

目录 一、基本简介 二、基础实现 1. 提供统⼀业务api 2. 编辑服务提供者product 3. 编辑服务消费者order 4. 服务调⽤测试 一、基本简介 Dubbo是阿⾥巴巴开源的基于 Java 的⾼性能 RPC分布式服务框架&#xff0c;致⼒于提供⾼性能和透明化的RPC远程服务调⽤⽅案&…

springcloud使用openfegin进行服务调用

一、为什么需要使用Fegin 引言&#xff1a;在我们使用nacos的时候是不是也有一种服务调用的方法那个时候我们使用到RestTemplate去调用远程的服务&#xff0c;但是我们看下面的一个例子就可以知道RestTemplate这种方式对于维护和后期代码上来说是不合理的&#xff0c;以为会是…

【无标题】Git(仓库,分支,分支冲突)

Git 一种分布式版本控制系统&#xff0c;用于跟踪和管理代码的变更 一&#xff0e;Git的主要功能&#xff1a; 二&#xff0e;准备git机器 修改静态ip&#xff0c;主机名 三&#xff0e;git仓库的建立&#xff1a; 1.安装git [rootgit ~]# yum -y install git 2.创建一个…

针对datax-web 中Swagger UI接口未授权访问

application.yml 添加以下配置 实现访问doc.html 以及/v2/api-docs 接口时需要进行简单的校验 swagger:basic:enable: trueusername: adminpassword: 12345 配置重启后再进行相关访问则需要输入用户名和密码

【SQL 新手教程 2/20】关系模型 -- 主键

&#x1f497; 关系数据库建立在关系模型上⭐ 关系模型本质上就是若干个存储数据的二维表 记录 (Record)&#xff1a; 表的每一行称为记录&#xff08;Record&#xff09;&#xff0c;记录是一个逻辑意义上的数据 字段 (Column)&#xff1a;表的每一列称为字段&#xff08;Colu…