C++入门自学Day1-- C语言的宏函数和C++内联函数

一、函数调用开销

函数调用会涉及:

  • 参数压栈(或寄存器传参)

  • 跳转到函数体

  • 返回值处理

  • 栈帧销毁

这个过程对小函数来说可能非常浪费,因此,宏函数和内联函数的目的就是避免“函数调用的开销”,通过代码展开(替换)来实现“零调用成本”。

 二、C语言的宏函数

1、 定义方式

宏函数使用 #define 宏定义语法:

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

2、实现原理

  • 预处理器阶段完成替换

  • 所有使用 SQUARE(x) 的地方,都会被文本替换为 ((x)*(x))(简单地字符串替换)

  • 不是函数调用,也没有类型检查

优点

  • 快!展开是直接替换,没有函数调用的成本

  • 支持各种类型(无类型限制)

缺点

  • 不安全:可能造成副作用

SQUARE(i++)  → ((++i) * (++i))  // i 被加了两次!

#define SQUARE(x) ((x)*(x))int main(){int i = 5;cout << "6*6 = " << SQUARE(++i);
}

输出:

        6*6 = 42  ❌;因为++i加了两次,所以是6*7;

        调试困难:宏不是函数,没法打断点进去

        没有作用域控制:容易污染命名空间

 三、C++ 的内联函数(inline function)

1、定义方式

inline int square(int x) {return x * x;
}

只是在常规的函数定义之前加个 “inline”。

2、实现原理

  • 编译器在 编译阶段 判断是否将调用处用函数体替代(不保证一定 inline,只是建议)

  • 真实函数、具有类型检查、作用域、安全。

  • 利用空间换时间的原理 。

 优点

       安全、类型检查完整

  • 可以用调试器调试

  • 支持递归(编译器可能不展开)

  • 支持模板和泛型

  • 可以与 constexpr、template 配合

 缺点

        内联函数不建议声明和定义分离,分离会导致连接错误。因为inline被展开了,就没有了函数地址,链接就找不到了。

  • 滥用内联会导致代码膨胀(code bloat),生成的可执行文件变大

  • 只适合小函数,复杂函数不一定 inline,(代码小于二十行,递归)。

  • 编译器有最终决定权,inline 是一种建议而非强制

四、对比总结表

特性

宏函数(C)

内联函数(C++)

执行阶段

预处理阶段

编译阶段

类型检查

❌ 无类型检查

✅ 有完整类型检查

安全性

❌ 易出错,有副作用

✅ 安全,作用域清晰

调试性

❌ 不可调试

✅ 可调试

递归支持

❌ 不支持

✅ 支持(是否内联由编译器决定)

用法建议

仅限非常简单的表达式

小函数、频繁调用的函数

性能提升

✅(暴力替换)

✅(编译器优化,智能展开)

五、【面试题】

1、宏的优缺点?

2、c++有哪些技术可以替代宏?

        利用常量定义换用const。

#define N 10;

替换为

const int N = 10;

        短小函数定义,换用内联函数。

宏函数定义 -->利用内联函数替换

#define MAX(a, b) ((a) > (b) ? (a) : (b))// 改写为模板内联函数
template <typename T>
inline T Max(T a, T b) {return a > b ? a : b;
}

3、 宏和内联函数的本质区别是什么?

考点: 宏是预处理阶段处理,内联函数是编译阶段处理。

  • 宏在预处理阶段展开,是文本替换,没有类型检查,也没有作用域限制;

  • 内联函数是真正的函数,有类型检查,有作用域,并能调试。

4、 什么是内联函数?什么时候应该使用?

考点: 减少函数调用开销,提升性能。

  • 适合小函数,如 getters/setters;

  • 不建议用于递归、虚函数、复杂函数;

  • 编译器可以不采纳 inline 建议(非强制)。

5、内联函数会影响编译时间和可执行文件大小吗?

考点:

  • 增加编译时间(编译器要展开多次);

  • 增加可执行文件大小(代码膨胀);

  • 但可以减少函数调用栈的开销。

好了本期有关于c语言宏定义知识回顾和c++内联函数的分享就到这里结束了,谢谢大家的支持和点赞收藏👍。

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

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

相关文章

Pytorch混合精度训练最佳实践

混合精度训练&#xff08;Mixed Precision Training&#xff09;是一种通过结合单精度&#xff08;FP32&#xff09;和半精度&#xff08;FP16/FP8&#xff09;计算来加速训练、减少显存占用的技术。它在保持模型精度的同时&#xff0c;通常能带来 2-3 倍的训练速度提升&#x…

Qt C++动态库SDK在Visual Studio 2022使用(C++/C#版本)

01 将C SDK 集成到 IDE 中以下是在 Microsoft Visual Studio 平台下 SDK 的集成。2.1 Visual Studio 平台下 C/C环境配置及集成到 IDE 中xxx.lib 和 xxx.dll 适合在 Windows 操作系统平台使用&#xff0c;这里以 VS2022 环境为例。2.1.1 C/C 工程环境配置与集成1、C# SDK 接口…

大语言模型 LLM 通过 Excel 知识库 增强日志分析,根因分析能力的技术方案(2):LangChain + LlamaIndex 实现

文章大纲 1 技术原理总览 2 详细实现步骤(含代码) 2.1 环境准备 2.2 Excel → LlamaIndex 节点 2.3 构建向量索引(FAISS 本地) 2.4 Google Cloud 向量检索(可选替换 FAISS) 2.5 LangChain 问答链 A. RAG 模式(向量检索 + LLM 生成) B. SQL 模式(无 RAG,直接查表) 2.…

提升ARM Cortex-M系统性能的关键技术:TCM技术解析与实战指南

文章目录引言一、TCM基础架构与工作原理1.1 TCM的物理特性1.2 与缓存机制的对比1.3 ARM Cortex-M系列对TCM的支持二、TCM的典型应用场景2.1 实时中断处理2.2 低功耗模式下的待机代码2.3 高性能算法执行2.4 系统初始化阶段的关键代码三、实战指南&#xff1a;在STM32H7上配置和优…

大数据之路:阿里巴巴大数据实践——大数据领域建模综述

为什么需要数据建模 核心痛点 数据冗余&#xff1a;不同业务重复存储相同数据&#xff08;如用户基础信息&#xff09;&#xff0c;导致存储成本激增。计算资源浪费&#xff1a;未经聚合的明细数据直接参与计算&#xff08;如全表扫描&#xff09;&#xff0c;消耗大量CPU/内存…

实战演练1:实战演练之命名实体识别

实战演练1:实战演练之命名实体识别 命名实体识别简介 代码 命名实体识别简介 什么是命名实体识别任务 命名实体识别(Named Entity Recognition,简称NER)是指识别文本中具有特定意义的实体,主要包括人名、地名、机构名、专有名词等。通常包括两部分: (1)实体边界识别。(2)确定…

数据结构基础内容(第七篇:堆、哈夫曼树)

# 堆 Heap 优先队列(Priority Queue) 结构性:用 *数组* 表示的完全二叉树; 有序性:任一结点的关键字是其子树所有结点的最大值(或最小值) * “最大堆(MaxHeap)”,也称“大顶堆”:最大值 * “最小堆(MinHeap)”,也称“小顶堆” :最小值 主要操作有: • MaxHeap Create( i…

CS231n-2017 Lecture7训练神经网络(二)笔记

本节主要是神经网络的动态部分&#xff0c;也就是神经网络学习参数和搜索最优超参数的过程梯度检查&#xff1a;进行梯度检查&#xff0c;就是简单地把解析梯度与数值计算梯度进行比较&#xff0c;防止反向传播的逻辑出错&#xff0c;仅在调试过程中使用。有如下技巧 &#xff…

IntelliJ IDEA 中左上方未显示项目根目录问题

问题&#xff1a; 在IDEA中编写代码时&#xff0c;发现左上方只显示项目的子模块&#xff0c;未显示根项目名称。 如图所示&#xff0c;未显示子模块的根项目&#xff1a;问题分析 顶层根目录未被识别为项目根目录&#xff0c;需要手动添加识别。 问题解决 进入File – Project…

OpenCV 图像变换全解析:从镜像翻转到仿射变换的实践指南

前言处理图像时&#xff0c;翻转、旋转、平移等操作很常用。OpenCV 提供了简单的方法实现这些变换&#xff0c;本文带你快速学会用它做图像翻转和仿射变换。1 图像翻转(图像镜像旋转)在OpenCV中&#xff0c;图片的镜像旋转是以图像的中心为原点进行镜像翻转的。cv2.flip(img,fl…

【运维】Linux运维命令记录

重置root密码使用命令重新设置一下root账户的密码 passwd root根据提示设置一下密码&#xff0c;然后使用sudo -i 时输入密码就可以切换到root账户了ssh登陆以后&#xff0c;要用sudo -i命令给用户提权&#xff0c;提到超级管理员&#xff0c;然后输入密码才有用

PandasAI连接LLM进行智能数据分析

1. 引言 Pandas是一个数据分析开源组件库&#xff0c;提供了高性能、易用的数据结构和数据分析工具。它的核心的功能是其DataFrame对象&#xff0c;这是一个带有行和列标签的二维表格数据结构&#xff0c;支持缺失数据处理、时间序列功能、灵活的数据输入输出方法、数据对齐和…

Spring之【Bean的生命周期】

目录 1、生成BeanDefinition BeanDefinitionRegistry接口 DefaultListableBeanFactory实现类 2、合并BeanDefnition AbstractBeanFactory类 3、BeanFactoryPostProcessor的方法回调 AbstractApplicationContext类 PostProcessorRegistrationDelegate类 4、BeanPostPro…

搜狐新闻直播间适配HarmonyOs实现点赞动画

01背景介绍随着新闻客户端鸿蒙单框架系统适配工作的推进&#xff0c;从原来的基础功能到现在已经适配全功能的85%以上。与此同时&#xff0c;我们也在持续深入挖掘鸿蒙系统的特性&#xff0c;以提升整体应用的质量与用户体验。在这一过程中&#xff0c;动画作为增强交互与视觉体…

83、设置有人DTU设备USR-M100采集传感器数据,然后上传阿里云服务

基本思想:设置M100 采集传感器数据 一、首先将DTU设备USR-M100连接路由器上,然后使用python代码搜索同一局域网设备, import platform import sys import os import time import threadinglive_ip = 0def get_os():os = platform.system()if os == "Windows":re…

P1019 [NOIP 2000 提高组] 单词接龙

题目描述单词接龙是一个与我们经常玩的成语接龙相类似的游戏&#xff0c;现在我们已知一组单词&#xff0c;且给定一个开头的字母&#xff0c;要求出以这个字母开头的最长的“龙”&#xff08;每个单词都最多在“龙”中出现两次&#xff09;&#xff0c;在两个单词相连时&#…

详解力扣高频SQL50题之1633. 各赛事的用户注册率【简单】

传送门&#xff1a;1633. 各赛事的用户注册率 题目 用户表&#xff1a; Users -------------------- | Column Name | Type | -------------------- | user_id | int | | user_name | varchar | -------------------- user_id 是该表的主键(具有唯一值的列)。 该表中的每行包…

FROM stakater/java8-alpine 构建cocker镜像

在 Dockerfile 中&#xff0c;FROM stakater/java8-alpine 是第一条也是最核心的指令&#xff0c;它定义了构建新镜像所基于的「基础镜像」。以下是逐层解析&#xff1a;&#x1f50d; 关键字拆解 1. FROM —— 起点指令 ✅ 作用&#xff1a;声明当前镜像的起点&#xff08;父镜…

Word2Vec模型训练全流程解析:从数据预处理到实体识别应用

请添加图片描述 训练Word2Vec模型 概述 问题 我们如何训练Word2Vec模型&#xff1f;在特定数据集上训练Word2Vec模型何时是有利的&#xff1f; 目标 理解在自有数据上训练Word2Vec模型而非使用预训练模型的优势 Colab环境配置 运行以下代码以启用辅助函数并重新读取数据…

在Ubuntu上使用QEMU学习RISC-V程序(2)gdb调试

文章目录一、准备工作二、基本调试流程1. 设置断点2. 执行程序3. 查看源代码/汇编三、查看寄存器1. 查看通用寄存器2. 查看特殊寄存器四、查看内存1. 内存查看命令2. 内存修改命令五、调试实战示例六、高级调试技巧1. 条件断点2. 自动显示3. 内存断点&#xff08;观察点&#x…