当前位置: 首页 > article >正文

5.编译链接和宏**

1. 宏(考察很多)-要求轻松实现宏,很容易出错

#define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏或定义宏。

下面是宏的声明方式:

#define name(参数列表) 内容

参数列表的左括号必须与name紧邻,如果两者间存在空白,参数列表就会被解释成内容的一部分。

#define SQUARE(x) x*x

这个宏接收一个参数x,如果写SQUARE(5),预处理器就会用5*5这个表达式替换SQUARE(5)。

但是这个宏存在一个问题:

#define SQUARE(x) x*xint main()
{int a = 5;printf("%d\n", SQUARE(a+1));return 0;
}

我们想象中应该是6×6=36,但是实际结果居然是11,为什么呢?

SQUARE(a+1) 实际上被替换成了 a+1*a+1,并不是(a+1)*(a+1),所以结果是11。

应该在宏定义上加上两个括号:

#define SQUARE(x) (x)*(x)

如果是这样一个宏,我们吸取经验在每个x上加上括号:

#define DOUBLE(x) (x)+(x)int main()
{int a = 5;// printf("%d\n", SQUARE(a+1));printf("%d\n", 10*DOUBLE(a));return 0;
}

我们想象中是10×10=100,但是实际上是55,我们展开替换DOUBLE,实际上是10*(5)+(5)

先算10*5 = 50, 最后再+5,等于55。

所以我们要在外面也加上括号。

#define DOUBLE(x) ((x)+(x))

所以用于对数值表达式进行求值的宏定义都应该用这种方式加上括号,避免在使用宏时由于参数中的操作符或邻近操作符之间不可预料的相互作用。

当宏参数在宏的定义中出现超过一次时,如果参数带有副作用,那么在使用这个宏的时候就可能出现危险,导致不可预测的后果。副作用就是表达式求值的时候出现永久性的效果

x++就是带有副作用

#define MAX(x, y) ((x)>(y)?(x):(y))int x = 5;int y = 8;int z = MAX(x++, y++);printf("%d %d %d\n", x, y, z);

预处理器处理后的结果是:

z = ((x++) > (y++) ? (x++) : (y++))

 (x++) > (y++) 都会走,走完x=6, y=9,然后走y++,z=9,y=10,最后的结果就是6,10,9。

某笔试题:

写一个宏,计算结构体中某变量相对于首地址的便宜,并给出说明

#define OFFSET_OF(type, member) ((size_t)&(((type *)0)->member))

说明:

  1. type: 结构体的类型。

  2. member: 结构体中的成员变量。

  3. ((type *)0): 将地址 0 强制转换为指向 type 类型的指针。这相当于假设结构体的首地址是 0

  4. &(((type *)0)->member): 获取成员变量 member 的地址。由于结构体的首地址是 0,这个地址就是成员变量相对于结构体首地址的偏移量。

  5. (size_t): 将偏移量转换为 size_t 类型,通常用于表示内存地址或偏移量的大小。

struct example 
{int a;char b;double c;
};int main() 
{printf("Offset of 'a': %zu\n", OFFSET_OF(struct example, a));printf("Offset of 'b': %zu\n", OFFSET_OF(struct example, b));printf("Offset of 'c': %zu\n", OFFSET_OF(struct example, c));return 0;
}
Offset of 'a': 0
Offset of 'b': 4
Offset of 'c': 8

2. 编译链接的过程(考的不多)

1. 预处理(Preprocessing)

预处理是编译过程的第一步,主要处理源代码中的预处理指令(以 # 开头的指令)。

主要任务:

  • 宏展开:将所有的宏定义展开。

  • 头文件包含:将 #include 指定的头文件内容插入到源文件中。

  • 条件编译:根据 #if#ifdef 等条件编译指令,选择性地包含或排除代码。

  • 删除注释:删除源代码中的注释。

输入输出:

  • 输入:.c 源文件。

  • 输出:.i 预处理后的文件。

gcc -E main.c -o main.i

2. 编译(Compilation)

编译阶段将预处理后的代码转换为汇编代码。

主要任务:

  • 词法分析:将源代码分解为 token(如关键字、标识符、运算符等)。

  • 语法分析:根据语法规则构建抽象语法树(AST)。

  • 语义分析:检查语义是否正确(如类型检查)。

  • 代码优化:对代码进行优化。

  • 生成汇编代码:将高级语言代码转换为目标机器的汇编代码。

输入输出:

  • 输入:.i 预处理后的文件。

  • 输出:.s 汇编文件。

gcc -S main.i -o main.s

3. 汇编(Assembly)

汇编阶段将汇编代码转换为机器代码(目标文件)。

主要任务:

  • 将汇编代码翻译为机器指令。

  • 生成目标文件(通常是 .o.obj 文件),包含机器代码和符号表。

输入输出:

  • 输入:.s 汇编文件。

  • 输出:.o 目标文件。

gcc -c main.s -o main.o

4. 链接(Linking)

链接阶段将多个目标文件和库文件合并为一个可执行文件。

主要任务:

  • 符号解析:解析目标文件中的未定义符号(如函数和变量)。

  • 地址分配:为代码和数据分配最终的内存地址。

  • 重定位:根据最终的内存地址调整代码中的引用。

  • 合并目标文件:将多个目标文件合并为一个可执行文件。

  • 链接库文件:将静态库或动态库链接到可执行文件中。

输入输出:

  • 输入:.o 目标文件和库文件。

  • 输出:可执行文件(如 a.outmain.exe)。

gcc main.o -o main

相关文章:

5.编译链接和宏**

1. 宏(考察很多)-要求轻松实现宏,很容易出错 #define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏或定义宏。 下面是宏的声明方式: #define name(参数列表) 内容 参数列表的左括号必…...

《灵珠觉醒:从零到算法金仙的C++修炼》卷三·天劫试炼(43)阴阳镜照连通 - 岛屿数量(DFS、BFS)

《灵珠觉醒:从零到算法金仙的C++修炼》卷三天劫试炼(43)阴阳镜照连通 - 岛屿数量(DFS、BFS) 哪吒在数据修仙界中继续他的修炼之旅。这一次,他来到了一片神秘的阴阳镜湖,湖面上倒映着一片由二维网格构成的岛屿世界。湖边有一块巨大的石碑,上面刻着一行文字:“欲破此湖…...

Odoo18 Http鉴权+调用后端接口

最近在调研Odoo18,包括它的前后端原理、源码等。发现官方的开发文档并不十分实用,比如标题这种简单的实用需求,竟然浪费了一点时间,特此记录。 官方文档:External API — Odoo 18.0 documentation 前提:首…...

TSN CB:恢复算法与潜在错误检测

1.概述 基础恢复功能位于排序功能中。它评估从较低层向上传递的一个或多个成员流的数据包的sequence_number子参数,以丢弃重复的数据包。基本恢复功能的给定实例化可以作为序列恢复功能或单个恢复功能。 序列恢复功能有两种序列恢复算法,因此它既可用于间…...

【sql靶场】第11、12关-post提交注入

目录 【sql靶场】第11、12关-post提交注入 POST 一、URL 二、核心组成部分 三、数据编码规范 四、应用场景与请求方法 第十一关 方法一 步骤一 步骤二 步骤三 步骤四 步骤五 步骤六 步骤七 方法二 步骤一 步骤二 步骤三 步骤四 步骤五 步骤六 步骤七 第…...

框架、云原生、微服务的基本概念

架构 互联网应用的架构设计随着业务需求的增长和技术的发展经历了从单一架构到垂直架构,再到分布式架构的演变。以下是这三种架构的定义、特点以及具体的例子: 1. 单一架构(Monolithic Architecture) 定义 单一架构是一种将所有…...

Discuz建站教程之论坛头部logo跳转链接怎么修改?

在修改头部logo跳转链接前&#xff0c;我们需要知道对应代码在哪个文件目录&#xff0c;进入宝塔或是服务器&#xff0c;找到文件&#xff1a;\template\default\common\header.htm&#xff0c;编辑器打开&#xff0c;搜索以下代码&#xff0c;大概在135行 <a href"{i…...

AI重构SEO关键词布局

内容概要 在搜索引擎优化&#xff08;SEO&#xff09;领域&#xff0c;AI技术的深度应用正在颠覆传统关键词布局逻辑。通过机器学习算法与语义分析模型&#xff0c;智能系统能够实时解析海量搜索数据&#xff0c;构建动态词库并精准捕捉用户意图。相较于依赖人工经验的关键词筛…...

贪心算法简介(greed)

前言&#xff1a; 贪心算法&#xff08;Greedy Algorithm&#xff09;是一种在每个决策阶段都选择当前最优解的算法策略&#xff0c;通过局部最优的累积来寻求全局最优解。其本质是"短视"策略&#xff0c;不回溯已做选择。 什么是贪心、如何来理解贪心(个人对贪心的…...

OpnenHarmony 开源鸿蒙北向开发——1.开发环境搭建(DevEco Studio 5.03)

我这边是基于window下对OpenHarmony开源鸿蒙进行北向开发。 一、安装DevEco Studio 1、下载 下载中心 | 华为开发者联盟-HarmonyOS开发者官网&#xff0c;共建鸿蒙生态 2、安装 下载完成之后进行解压 双击进行安装 按照我的步骤进行 选择安装目录&#xff0c;全部配置完成后…...

钉钉(excel)能让表格中不是‘北京’的字符串自动加亮显示(方便查看)以及隔行填充严颜色是斑马色(方便查看)嘛

在钉钉在线表格中&#xff0c;虽然功能相对Excel有所简化&#xff0c;但仍然可以通过条件格式实现对特定内容的高亮显示。以下是具体步骤&#xff1a; 一、在钉钉在线表格中设置条件格式 1. 打开钉钉在线表格 登录钉钉&#xff0c;进入“钉钉在线表格”应用。 打开你需要操作…...

【工具】ReConPlot一个可视化和解释基因组重排的R包

文章目录 介绍代码案例加载R包导入数据 参考 介绍 人类肿瘤的全基因组测序研究表明&#xff0c;复杂形式的结构变异&#xff0c;统称为复杂基因组重排&#xff08;cgr&#xff09;&#xff0c;在不同类型的癌症中普遍存在。cgr的检测、分类和机制解释需要对体细胞拷贝数畸变&a…...

OSPF-2 邻接建立关系

上一期我们说了OSPF的邻居建立关系以及OSPF邻居关系建立中建立失败的因素以及相关实验案例 这一期我们来说说OSPF的邻接关系建立时需要交互哪些报文以及失败因素及原因和相关实验案例 一、概述 在运行了OSPF的网络当中为了交互链路状态信息和路由信息,互相之间需要建立邻接关…...

最完美的WPF无边框设计!

常规的无边框方法设计 常规的WPF无边框设计方法都是通过AllowsTransparency="True"和WindowStyle=“None”,并且使用WindowChrome样式来实现,但是这样会有问题就是,窗体最大化的时候将底部任务栏给挡住了,另外最大化的时候不能拖动窗体。参考这个大佬的设计@ 若…...

无限使用Typora

下载 Typora https://www.typora.net/#home 安装 找到 /Applications/Typora.app/Contents/Resources/TypeMark/page-dist/static/js/LicenseIndex.180dd4c7.5b0f7af9.chunk.js 文件 打开文件 搜索 e.hasActivated"true"e.hasActivated,修改成 e.hasActivated&…...

工作记录 2017-01-12

序号 工作 相关人员 1 协助BPO进行Billing的工作。 处理Amazing Charts的数据查询。 修改BillingJobPoster&#xff0c;处理CCDA 的自动导入&#xff0c;预计还需一天才能完成。 修改录入Code的界面&#xff08;code 移动到指定位置&#xff09;&#xff0c;预计明天更新。…...

【Linux】从互斥原理到C++ RAII封装实践

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文由 JohnKi 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f4e2;未来很长&#…...

爬虫案例十三js逆向模拟登录中大网校

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、网站分析二、代码 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; js 逆向模拟登录中大网校 提示&#xff1a;以下是本篇文章正文内…...

WPF窗口读取、显示、修改、另存excel文件——CAD c#二次开发

效果如下&#xff1a; using System.Data; using System.IO; using System.Windows; using Microsoft.Win32; using ExcelDataReader; using System.Text; using ClosedXML.Excel;namespace IfoxDemo {public partial class SimpleWindow : Window{public SimpleWindow(){Initi…...

01 | Go 项目开发极速入门课介绍

提示&#xff1a; 所有体系课见专栏&#xff1a;Go 项目开发极速入门实战课。 你好&#xff0c;欢迎学习本课程。本课程是一个 Go 项目开发极速入门课程。旨在帮助刚学习完 Go 基础语法的 Go 开发者&#xff0c;快速掌握如何开发一个功能相对全面的 Go 项目。 根据课程设计目标…...

Spring Cloud LoadBalancer 原理与实践

背景 当前我们的微服务架构基于Spring Cloud Alibaba体系&#xff0c;通过定制NacosRule实现了跨集群访问和灰度发布功能。但随着Spring Cloud与Nacos版本升级&#xff0c;官方已弃用Ribbon转向LoadBalancer&#xff0c;这要求我们完成以下技术升级&#xff1a; 负载均衡机制…...

Vmware下的openEuler

1.下载openEuler操作系统镜像 https://repo.openeuler.org/openEuler-20.03-LTS/ISO/ 2.在VM新建虚拟机 3.虚拟机联网 我是出现了没有网络&#xff0c;ping不通的问题 参考&#xff1a;https://blog.csdn.net/FHY26828/article/details/140941234 修改文件&#xff1a; 在…...

spring security学习入门指引

学习 Spring Security 可以从以下几个方面逐步深入&#xff0c;结合理论与实践&#xff0c;以下是具体的学习路径建议&#xff1a; 1. 基础准备 • 熟悉 Spring 框架&#xff1a; 先掌握 Spring Core、Spring MVC 和 Spring Boot 的基础&#xff0c;理解依赖注入&#xff08;D…...

【瞎折腾/Dify】使用docker离线部署Dify

文章目录 说在前面安装Docker(外网)获取Dify源码(外网)拉取docker镜像(外网)导出镜像(内网)导入镜像(内网)运行问题 说在前面 外网操作系统&#xff1a;windows内网操作系统&#xff1a;ubuntu外网docker desktop版本&#xff1a;4.29.0外网docker版本&#xff1a;version 26.0…...

Java EE Web环境安装

Java EE Web环境安装 一、JDK安装与测试&#xff08;Windows环境&#xff09; 1. 安装JDK 官网下载&#xff1a;Oracle JDK&#xff08;选择Windows x64 Installer&#xff09;双击安装包&#xff0c;按向导完成安装 ​ 2. 环境变量配置 右键【此电脑】→【属性】→【高级…...

Node.js中HTTPS模块应用详解

1. HTTPS 模块的概念 HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;是 HTTP 的安全版本&#xff0c;通过 SSL/TLS 协议对数据进行加密&#xff0c;确保数据在传输过程中不被窃取或篡改。在 Node.js 中&#xff0c;https 模块提供了创建 HTTPS 服务器和客户…...

我测试了AI搜索:试图替代谷歌搜索

随着人工智能工具的不断进步,探讨它们是否能够取代传统搜索引擎如谷歌,已成为一个引人入胜的话题。 有一点是确定的:并非所有的人工智能都可用。它们需要的主要特性是能够访问互联网以获取最新信息,这就排除了Anthropic的Claude。 人工智能在某些方面可以增强或改进谷歌搜…...

大语言模型基础之‘显存优化‘

上一篇可扩展的训练技术(二)中&#xff0c;我们介绍了零冗余优化器&#xff08;Zero Redundancy Optimizer, Zero&#xff09;&#xff0c;该技术由DeepSpeed代码库提出&#xff0c;主要用于解决数据并行中的模型冗余技术&#xff0c;即在数据并行训练中&#xff0c;每个GPU上都…...

【Nexus】Maven 私服搭建以及上传自己的Jar包

Nexus 安装 docker run -d -uroot --name nexus3 --restartalways -p 8081:8081 -v /data/nexus-data/blobs:/nexus-data/blobs -v /etc/localtime:/etc/localtime sonatype/nexus3这里也提供一下docker-composer的方法 .env 文件 VERSIONlatest CONTAINER_NAMECONTAINER_N…...

css模拟雷达扫描动画

<div class"radar-scan"><div class"radar-container" /></div> 样式&#xff1a; .radar-scan {background-image: linear-gradient(0deg,transparent 24%,rgba(32, 255, 77, 0.15) 25%,rgba(32, 255, 77, 0.15) 26%,transparent 27%,…...