深度解析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://www.mzph.cn/web/49615.shtml

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

相关文章

tof系统标定流程步骤详解

1、tof标定概述 系统校准是一个减少ToF系统中系统误差影响的过程,如图1.1所示。本文件旨在介绍校准方法、设备和软件 1.1 系统误差 1.1.1 周期误差 谐波失真导致的相位(距离)相关误差。 1.1.2 固定相位模式噪声 由于解调信号的时延取决于可见像素位置以及VCSEL和传感器…

【Golang 面试基础题】每日 5 题(十)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/UWz06 &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏…

【机器学习】解开反向传播算法的奥秘

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 解开反向传播算法的奥秘反向传播算法的概述反向传播算法的数学推导1. 前向传播2…

Linux进程——程序地址空间详解

文章目录 程序地址空间地址空间与物理内存什么是程序地址空间管理程序地址空间虚拟地址与物理地址的映射页表的结构及其作用程序地址空间的作用 程序地址空间 我们之前学习内存的时候&#xff0c;有说内存的分布大概是这样的 其中堆由下而上&#xff0c;栈由上而下 除此之外&…

LeetCode:删除排序链表中的重复元素(C语言)

1、问题概述&#xff1a;给定一个已排序链表的头&#xff0c;删除重复元素&#xff0c;返回已排序的链表 2、示例 示例 1&#xff1a; 输入&#xff1a;head [1,1,2] 输出&#xff1a;[1,2] 示例 2&#xff1a; 输入&#xff1a;head [1,1,2,3,3] 输出&#xff1a;[1,2,3] 3…

2024年国际高校数学建模大赛(IMMCHE)问题A:金字塔石的运输成品文章分享(仅供学习)

2024 International Mathematics Molding Contest for Higher Education Problem A: Transportation of Pyramid Stones&#xff08;2024年国际高校数学建模大赛&#xff08;IMMCHE&#xff09;问题A&#xff1a;金字塔石的运输&#xff09; 古埃及金字塔石材运输优化模型研究…

2024最新Selenium面试题(附带答案),建议收藏备用

一.你在TestNG中使用了哪些注解&#xff1f; TestBeforeSuiteAfterSuiteBeforeTestAfterTestBeforeClassAfterClassBeforeMethodAfterMethod 二.如何从Excel中读取数据&#xff1f; FileInputStream fs new FileInputStream(“excel文件路径”); Workbook wb WorkbookFact…

探索智慧校园资产入库功能,构建高效校园资产管理体系

在智慧校园的资产管理框架下&#xff0c;资产入库功能作为资产生命周期管理的开端&#xff0c;扮演着至关重要的角色。这一功能确保了新购置或转入的资产能够迅速而准确地被记录在系统中&#xff0c;从而无缝融入日常的管理流程。当资产入库时&#xff0c;系统要求详细登记一系…

2024最新前端学习路线指南!

2024最新前端学习路线指南&#xff01; 如果你正在寻找一份全面的前端学习路线图&#xff0c;那么这份精心打造的学习大纲恰好符合您的需求。无论您是新手还是经验丰富的开发者&#xff0c;这份路线图都能够帮助您系统地掌握前端开发的关键知识点&#xff0c;并在实践中不断提…

<PLC><HMI><汇川>在汇川HMI画面中,如何为UI设置全局样式?

前言 汇川的HMI软件是使用了Qt来编写的,因此在汇川的HMI程序编写过程,是支持使用qt的样式来自定义部件样式的,即qss格式。 概述 汇川的软件本身提供三个系统的style样式,我们可以直接使用,但是,如果系统提供的样式不符合你的需求,那么你可以对其进行修改,或者自己新建…

修改linux服务器上的mariadb/mysql数据库的密码

文章目录 一、查看数据库的状态二、修改密码 可能我们在最初安装数据库时没有设置密码或者已经设置了但是又想修改另一个密码&#xff0c;可以这样操作来修改我们的密码。 以数据库 mariadb 为例。 一、查看数据库的状态 使用命令 systemctl is-active mariadb 查看当前数据库…

Github 2024-07-27开源项目日报 Top10

根据Github Trendings的统计,今日(2024-07-27统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量非开发语言项目2C++项目2C项目2TypeScript项目1JavaScript项目1Java项目1Python项目1C#项目1免费编程学习平台:freeCodeCamp.org 创建周期:33…

JMeter接口测试:测试中奖概率!

介绍 Apache JMeter 是 Apache 组织基于 Java 开发的压力测试工具&#xff0c;用于对软件做压力测试。JMeter 最初被设计用于 Web 应用测试&#xff0c;但后来扩展到了其他测试领域&#xff0c;可用于测试静态和动态资源&#xff0c;如静态文件、Java 小服务程序、CGI 脚本、J…

Redis 缓存

安装 安装 Redis 下载&#xff1a; Releases tporadowski/redis (github.com) winr ----services.msc-----将redis 设置为手动(只是学习&#xff0c;如果经常用可以设置为自动) 安装 redis-py 库 pip install redis-py Redis 和 StrictRedis redis-py 提供 Redis 和 Str…

Java高频面试题分享

文章目录 1. 策略模式怎么控制策略的选取1.1 追问&#xff1a;如果有100种策略呢&#xff1f;1.2 追问&#xff1a;什么情况下初始化Map 2. 什么是索引&#xff1f;什么时候用索引&#xff1f;2.1 追问&#xff1a;怎么判断系统什么时候用量比较少2.2 追问&#xff1a;如何实时…

C++多态的底层原理

目录 1.虚函数表 &#xff08;1&#xff09;虚函数表指针 &#xff08;2&#xff09;虚函数表 2.虚函数表的继承--重写&#xff08;覆盖&#xff09;的原理 3.观察虚表的方法 &#xff08;1&#xff09;内存观察 &#xff08;2&#xff09;打印虚表 虚表的地址 函数 传参…

SSM电子商务系统-计算机毕业设计源码68470

基于SSM框架的电子商务系统的设计与实现 摘 要 随着电子商务的迅猛发展和计算机信息技术的全面跃升&#xff0c;网上购物系统由于其迎合了人们诉求和期望而渗入社会生活各个层面和角落。本文设计并实现了一个基于SSM框架的电子商务系统。该系统旨在为用户提供一个舒适且快捷的…

Python基础——第一个Python程序

Python基础——第一个Python程序 一、编写和运行代码的工具1.1 为什么需要工具1.2 默认的交互式环境1.3 文本编辑神器 - Visual Studio Code1.4 专业的集成开发环境 - PyCharm 二、编写第一个Python程序2.1 在PyCharm中编写“Hello, World!”程序2.2 运行“Hello, World!”程序…

Windows 11+Visual Studio 2022 环境OpenCV+CUDA 12.5安装及踩坑笔记

周六日在家捣腾了一下&#xff0c;把过程记录下来。 前置条件 Visual Studio C 生成工具和本机显卡适配的CUDA与CUDA匹配的cuDNNPython 3NumPyOpenCV源代码以及对应版本的OpenCV-contrib模块源码CMake Visual Studio 下载Visual Studio&#xff08;我本机的是VS2022&#xf…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 智能驾驶(200分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 👏 感谢大家的订阅➕ 和 喜欢💗 🍿 最新华为OD机试D卷目录,全、新、准,题目覆盖率达 95% 以上,支持题目在线评测,专栏文章质量平均 93 分 最新华为OD机试目录: …