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

news2024/9/20 16:47:30

目录

结构体的三种初始化

结构体的两种引用

结构体数组

结构体大小

结构体实现位段操作

联合体

 内存对齐

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 A
    printf("真");
#endif

// 二路分支
#if A
    printf("A");
#elif B
    printf("B");
#endif

// 多路分支
#if A
    printf("A");
#elif B
    printf("B");
#elif C
    printf("C");
#endif

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

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

#ifndef stdio
#define stdio

void printf。。。

。。。scanf。。。

。。。int。。。

。。。float。。。


#endif

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

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

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

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

相关文章

unity 实现图片的放大与缩小(根据鼠标位置拉伸放缩)

1创建UnityHelper.cs using UnityEngine.Events; using UnityEngine.EventSystems;public class UnityHelper {/// <summary>/// 简化向EventTrigger组件添加事件的操作。/// </summary>/// <param name"_eventTrigger">要添加事件监听的UI元素上…

Memcached开发(十四):常见问题与故障排除

目录 1. 内存使用问题 1.1 内存不足 1.2 内存泄漏 2. 连接问题 2.1 连接超时 2.2 连接断开 3. 数据一致性问题 3.1 缓存穿透 3.2 缓存雪崩 3.3 缓存击穿 4. 性能问题 4.1 响应时间过长 4.2 吞吐量不足 5. 安全问题 5.1 未授权访问 5.2 数据泄露 6. 版本兼容问…

驾驭代码的无形疆界:动态内存管理揭秘

目录 1.:为什么要有动态内存分配 2.malloc和free 2.1:malloc 2.2:free 3.calloc和realloc 3.1:calloc 3.1.1:代码1(malloc) 3.1.2:代码2(calloc) 3.2:realloc 3.2.1:原地扩容 3.2.2:异地扩容 3.2.3:代码1(原地扩容) 3.2.3:代码2(异地扩容) 4:常见的动态内存的错误…

AR 眼镜之-充电动画定制-实现方案

目录 &#x1f4c2; 前言 AR 眼镜系统版本 充电动画 1. &#x1f531; 技术方案 1.1 方案介绍 1.2 实现方案 关机充电动画 亮屏/锁屏充电动画 2. &#x1f4a0; 关机充电动画 2.1 关机充电动画核心处理类与路径 2.2 实现细节 步骤一&#xff1a;1&#xff09;定制 …

Javascript前端面试基础5【每日更10】

let与var的区别 let命令不存在变量提升&#xff0c;如果在let前使用&#xff0c;会导致报错&#xff08;var存在变量提升&#xff09;如果块区中存在let和const命令&#xff0c;就会形成封闭作用域不允许重复声明&#xff0c;因此&#xff0c;不能在函数内部重新声明参数 m…

Pcl读取stl文件,并转换成pcd文件,同时显示stl模型和pcd点云

由于不同版本的pcl兼容范围不一样&#xff0c;这里有2个版本的代码&#xff0c;里面的文件路径需要实际情况修改即可&#xff0c;希望对您有所参考或帮助 pcl1.8.1和vs2015版本代码 #include <iostream> #include <pcl/io/io.h> #include <pcl/io/pcd_io.h>…

序列化与反序列化的本质

1. 将对象存储到本地 假如有一个student类&#xff0c;我们定义了好几个对象&#xff0c;想要把这些对象存储下来&#xff0c;该怎么办呢 from typing import List class Student:name: strage: intphones: List[str] s1 Student("xiaoming",10,["huawei&quo…

大模型微调部署实战及类GPT工具的高效使用

大家好&#xff0c;我是herosunly。985院校硕士毕业&#xff0c;现担任算法研究员一职&#xff0c;热衷于大模型算法的研究与应用。曾担任百度千帆大模型比赛、BPAA算法大赛评委&#xff0c;编写微软OpenAI考试认证指导手册。曾获得阿里云天池比赛第一名&#xff0c;CCF比赛第二…

《RMT: Retentive Networks Meet Vision Transformers》CVPR2024

论文&#xff1a;RMT: Retentive Networks Meet Vision Transformers - AMiner 摘要 这篇论文探讨了将Retentive Network&#xff08;RetNet&#xff09;的概念引入到计算机视觉领域&#xff0c;并与Vision Transformer结合&#xff0c;提出了一种新的模型RMT&#xff08;Ret…

牛津剑桥等发现:AI 训 AI 惨遭投毒 9 次大崩溃

【新智元导读】9 次迭代后&#xff0c;模型开始出现诡异乱码&#xff0c;直接原地崩溃&#xff01;牛津、剑桥等机构的一篇论文登上了 Nature 封面&#xff0c;称合成数据就像近亲繁殖&#xff0c;效果无异于投毒。有无破解之法&#xff1f;那就是 —— 更多使用人类数据&#…

护眼灯有没有护眼的效果?一文揭秘用护眼灯到底好不好

护眼灯有没有护眼的效果&#xff1f;在现在这个时代&#xff0c;无论是在学习还是办公&#xff0c;都很难离开一款好用的台灯&#xff0c;所以&#xff0c;为了避免会挑选到质量不好的台灯&#xff0c;我们应该要先避开一些网红小品牌&#xff0c;优先选择有专业技术支持的&…

ClickHouse 24.6 版本发布说明

本文字数&#xff1a;14127&#xff1b;估计阅读时间&#xff1a;36 分钟 作者&#xff1a;ClickHouse team 本文在公众号【ClickHouseInc】首发 又到了发布新版本的时间&#xff01; 发布概要 本次ClickHouse 24.6 版本包含了23个新功能&#x1f381;、24项性能优化&#x1f6…

maven介绍 搭建Nexus3(maven私服搭建)

Maven是一个强大的项目管理工具&#xff0c;它基于项目对象模型&#xff08;POM&#xff1a;Project Object Model&#xff09;的概念&#xff0c;通过XML格式的配置文件&#xff08;pom.xml&#xff09;来管理项目的构建 Maven确实可以被视为一种工程管理工具或项目自动化构…

使用flutter做圆形进度条 (桌面端)

前言 最近收到一个需求&#xff0c;需要使用flutter 来做一个圆形进度条&#xff0c;这可难倒我了&#xff0c;毕竟我是做前端的&#xff0c;flutter 之前接触的也少&#xff0c;但没办法&#xff0c;既然需求有了&#xff0c;也得硬着头皮上了&#xff0c;先来看看做的效果。…

简过网:大学生考公,一定要先好好看看这篇文章!

大家好&#xff0c;我是简过网&#xff0c;今天这篇文章我们来聊聊关于大学生考公的那些事儿&#xff0c;希望能给大学生们一点点的帮助&#xff01; 首先&#xff0c;可能有朋友会问了&#xff0c;大学生一般从什么时候开始备考公务员呢&#xff0c;在这里小编建议大家从大三…

《昇思25天学习打卡营第24天|基于MindSpore通过GPT实现情感分类》

基于MindSpore通过GPT实现情感分类 %%capture captured_output # 实验环境已经预装了mindspore2.2.14&#xff0c;如需更换mindspore版本&#xff0c;可更改下面mindspore的版本号 !pip uninstall mindspore -y !pip install -i https://pypi.mirrors.ustc.edu.cn/simple mind…

yolov5-7环境搭建训练自己的模型

1.下载代码 git clone https://github.com/ultralytics/yolov5 # clone可以切到5-7版本&#xff0c;也可以去github选标签下载 2.配置好conda环境&#xff0c;网上教程比较多&#xff0c;不做讲解&#xff0c;python3.8即可。 3.在环境里安装pyrtorch 按自己的需求选取&am…

每日一练,java05

目录 题目知识点&#xff1a;1.12.13.1 题目 选自牛客网 1.下列表述错误的是&#xff1f;&#xff08;&#xff09; A.int是基本类型&#xff0c;直接存数值&#xff0c;Integer是对象&#xff0c;用一个引用指向这个对象。 B.在子类构造方法中使用super()显示调用父类的构造…

第T6周:使用TensorFlow实现好莱坞明星识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 文章目录 一、前期工作1.设置GPU&#xff08;如果使用的是CPU可以忽略这步&#xff09;2. 导入数据3. 查看数据 二、数据预处理1、加载数据2、数据可视化3、再…

【论文速读】| LLMCloudHunter:利用大语言模型(LLMs)从基于云的网络威胁情报(CTI)中自动提取检测规则

本次分享论文&#xff1a;LLMCloudHunter: Harnessing LLMs for Automated Extraction of Detection Rules from Cloud-Based CTI 基本信息 原文作者&#xff1a;Yuval Schwartz, Lavi Benshimol, Dudu Mimran, Yuval Elovici, Asaf Shabtai 作者单位&#xff1a;Ben-Gurion…