C++知识补充(一)

这篇具有很好参考价值的文章主要介绍了C++知识补充(一)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C++知识补充

由于之前有系统的学过 C 语言,现在在学习 C++ 的过程中采用的是对比学习方式,C 语言中没有涉及到的会补充记录一下。

内联函数

内联函数(Inline Function)是 C++ 中一种特殊的函数,其定义直接在每个调用点展开,这意味着编译器会尝试将函数调用替换为函数本身的代码,这样可以减少函数调用的开销,尤其是在小型函数中。

特点

  1. 减少函数调用开销:内联函数通常用于优化小型、频繁调用的函数,因为它断免了函数调用的常规开销(如参数传递、栈操作等)。
  2. 编译器决策:即使函数被声明为内联,编译器也可能决定不进行内联,特别是对于复杂或递归函数。
  3. 适用于小型函数:通常只有简单的、执行时间短的函数适合做内联。
  4. 定义在每个使用点:内联函数的定义(而非仅仅是声明)必须对每个使用它的文件都可见,通常意味着将内联函数定义在头文件中。

使用方法

通过在函数声明前添加关键字 inline 来指示编译器该函数适合内联

inline int max(int x, int y)
{
    return x > y ? x : y;
}
#include <iostream>

inline int add(int a, int b)
{
    return a + b;
}
int main()
{
    int result = add(5,3);// 编译器可能会将此替换为:int result = 5 + 3;
    std::cout << "Result:" << result << std::endl;
    return 0;    
}
// 在这个示例中,函数 add 被定义为内联函数。当它被调用时,编译器可能会将函数调用替换为函数体内的代码。

注意事项

  1. 过度使用的风险:不应滥用内联函数,因为这可能会增加最终程序的大小(代码膨胀),对于大型的函数或递归函数,内联可能导致性能下降。
  2. 编译器的决定:最终是否将函数内联是由编译器决定的,即使函数被标记为 inline。
  3. 适用场景:最适合内联的是小型函数和在性能要求高的代码中频繁调用的函数。

内联函数是一种用于优化程序性能的工具,但需要合理使用,以确保代码的可维护性和性能的平衡。

Lambda表达式

Lambda 表达式是 C++11引入的一种匿名函数的方式,它允许你在需要函数的地方内联地定义函数,而无需单独命名函数。
Lambda表达式的基本语法如下:

[capture clause](parameters) -> return_type
{
    // 函数体
    // 可以使用捕获列表中的变量
    return expression; // 可选返回语句
}

Lambda 表达式由以下部分组成:

  1. 捕获列表(Capture clause):用于捕获外部变量,在Lambda 表达式中可以访问这些变量,捕获列表可以为空,也可以包含变量列表[var1,var2, …]。
  2. 参数列表(Parameters):与普通函数的参数列表类似,可以为空或包含参数列表(param1,param2,…)。
  3. 返回类型(Return type):Lambda 表达式可以自动推断返回类型,也可以显式指定返回类型 -> return_type。如果函数体只有一条返回语句,可以省略返回类型。
  4. 函数体(Body):Lambda 表达式的函数体,包含需要执行的代码。

Lambda表达式最简单的案例是在需要一个小型函数或临时函数时直接便用它,以下是一个非常简单的例子,其中使用Lambda 表达式来定义一个加法操作,并立即使用它来计算两个数的和。

// 使用 Lambda 表达式进行加法
#include <iostream>

int main()
{
    int x = 50;
    int y = 20;
    auto add = [](int a, int b) -> int{
        return a + b;
    };
    int ret = add(x, y);
    std::cout << ret;
    return 0;
}
// 使用匿名 Lambda 函数来返回两个数中较大的数
#include <iostream>

using namespace std;

//bool compare(int a, int b)
//{
//    return a > b;
//}

int getMax(int a, int b, bool (*pcompare)(int a, int b))
{
    if(pcompare(a, b))
    {
        return a;
    }else{
        return b;
    }
}

int main()
{
    int x = 30;
    int y = 20;
    // int max = getMax(x, y, compare);
    // 下面改写为 Lambda 表达式
    int max = getMax(x, y, [](int a, int b) -> bool{
        return a > b;
    });
    cout << max << endl;
    return 0;
}

带参数捕获的 Lambda 表达式

#include <iostream>

using namespace std;

int main()
{
    int x = 10;
    int y = 20;
    auto add = [x, y]() -> int{
        // x++;
        // x = 15; 这种方式捕获,不能修改变量值,只能用(可读)
        return x + y;
    };

    int ret = add();
    cout << ret << endl;

    int z = 5;
    auto mul = [=]() -> int{
        // x++;
        // x = 15; 这种方式捕获所有变量,不需要去列表中写明,不能修改变量值,只能用(可读)
        return x * y * z;
    };
    ret = mul();
    cout << ret << endl;

    // 用引用的方式捕获,引用类似指针,进行地址访问
    auto modifyMul = [&]() -> int{
        // x++;
        x = 15; // 引用的方式进行所有变量的捕获,可读可写(即可以修改变量的值)
        return x * y * z;
    };

    ret = modifyMul();
    cout << ret << endl;
    cout << "x = " << x << endl;
    return 0;
}
/*
第一个 Lambda 表达式  sum 按值捕获了 x 和 y (即它们的副本)。这意味 sum 内的 x 和 y 是在 Lambda 定义时的值的拷贝。
第二个 Lambda 表达式 mul使用 [=] 捕获列表,这表示它按值捕获所有外部变量。
第三个 Lambda 表达式 modifyMul使用 [&] 捕获列表,这表示它按引用捕获所有外部变量,因此,它可以修改 x 和 y 的原始值。
*/

这个示例展示了如何使用不同类型的捕获列表(按值和按引用)来控制 Lambda 表达式对外部变量的访问和修改。按值捕获是安全的,但不允许修改原始变量,而按引用捕获允许修改原始变量,但需要注意引用的有效性和生命周期问题。

Lambda 函数和内联函数在 C++ 中的相似之处和区别:

特性 Lambda 函数 内联函数
定义 一种匿名函数,通常用于定义在需要他们的地方 一种常规函数,通过 inline 关键字定义
用途 提供一种快捷方式来定义临时的、小型的函数 用于优化小型函数,减少函数调用的开销
语法 使用 [capture] ( params ) { body }的形式定义 使用常规函数定义语法,但在前边加上 inline 关键字
生命周期 在定义他们的作用域内有效 在整个程序执行期间有效
捕获外部变量 可以捕获外部作用域中的变量(按值或按引用) 不能直接捕获外部变量,只能通过参数传递
调用方式 作为函数对象,可直接调用 像普通函数一样调用
优化 可以被编译器自动内联化,但取决于编译器优化策略 明确请求编译器尝试内联,但实际内联化也取决于编译器
可见性 通常只在定义他们的局部作用域内可见 可以在定义它的任何作用域内可见
使用场景 适合于一次性使用的场景,如作为回调、在算法中使用等 适合于频繁调用的小型函数

虽然 Lambda 函数和内联函数在某些方面有相似之处,如它们都可以被编译器优化以减少调用开销,但它们在设计和用途上有明显的不同。Lambda 函数的核心优势在于它们的匿名性和对外部变量的捕获能力,而内联函数则主要关注于提高小型函数的性能。文章来源地址https://www.toymoban.com/news/detail-792801.html

到了这里,关于C++知识补充(一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【VisualStudio】基于 Visual Studio 使用 C++ 语言开发 Qt 环境配置教程

    知识不是单独的,一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏:Visual Studio。 先上一张效果图,具体步骤主要分为以下三步。 这一步不再赘述,注意一定要安装 C++ 语言。 可以参考这个教程 Visual Studio 2022安装与使用教程。 这一步也不再赘述,网上搜索教

    2024年02月15日
    浏览(60)
  • 【Visual Studio】报错 C2653,使用 C++ 语言,配合 Qt 开发串口通信界面

    知识不是单独的,一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏:Visual Studio。 这个 Bug 是我做这个工程时遇到的:【Visual Studio】Qt 的实时绘图曲线功能,使用 C++ 语言,配合 Qt 开发串口通信界面。 使用 C++ 语言,配合 Qt 开发串口通信界面,在添加 Widget 做

    2024年02月11日
    浏览(46)
  • WPF快速开发(1):静态计算器知识点补充

    本篇章主要介绍如何使用布局元素和简单控件 WPF是一个MVVM框架 是一个只能运行在Windows平台上的程序 WPF的后继者:UWP,MAUI等能进行跨平台。 WPF是断代更新: 官方不会再发布新的版本,而是启用其他的全新框架。 第三方库还是在持续更新 优点: 第三方库不需要考虑版本适

    2024年02月16日
    浏览(36)
  • 一般开发Unity 使用什么语言,需要学习什么知识

    一般来说,开发Unity使用的是C#语言。要学习Unity开发,你需要学习的知识包括: C#语言的基础知识 Unity的基本使用方法 常用的游戏编程模式,如游戏循环、场景切换、碰撞检测等 了解游戏对象、资源、动画、物理等概念 了解常用的游戏开发插件和工具,如脚本编辑器、版本

    2024年02月13日
    浏览(52)
  • Unity 游戏开发、02 基础篇 | 知识补充、简单使用动画、动画状态机

    Unity 游戏开发、01 基础篇 Q 手型工具(鼠标中键): 上下左右移动场景 ALT + 鼠标左键: 以视图为中心旋转 鼠标右键: 以观察者为中心旋转 SHIFT + Gizmo方块: Y轴归位 物体节点 + F: 观察者定位至物体 3D项目一般窗口布局如下 全局光照GI(Glballlumination)(编辑模式下才能生成

    2024年02月09日
    浏览(61)
  • 【C++精华铺】6.C++类和对象(下)类与对象的知识补充及编译器优化

    目录 1. 再谈构造 1.1 成员变量的初始化(初始化列表) 1.2 初始化列表的行为 1.3 explicit  2. 类中的static成员 2.1 静态成员变量 2.2 静态成员函数 3. 友元 3.1 友元函数 3.1 友元类 4. 内部类  5. 匿名对象  6. 对象拷贝时候的编译器优化           为什么还要去看初始化的问

    2024年02月13日
    浏览(37)
  • 【Visual Studio】报错 ASSERT: “i >= 0 && i < size()“,使用 C++ 语言,配合 Qt 开发串口通信界面

    知识不是单独的,一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏:Visual Studio。 这个 Bug 是我做这个工程时遇到的:【Visual Studio】Qt 的实时绘图曲线功能,使用 C++ 语言,配合 Qt 开发串口通信界面。 使用 C++ 语言,配合 Qt 开发串口通信界面,在调试动态绘图

    2024年02月11日
    浏览(46)
  • C++项目实战——基于多设计模式下的同步&异步日志系统-③-前置知识补充-设计模式

    🌸作者简介: 花想云 ,在读本科生一枚,C/C++领域新星创作者,新星计划导师,阿里云专家博主,CSDN内容合伙人…致力于 C/C++、Linux 学习。 🌸 专栏简介:本文收录于 C++项目——基于多设计模式下的同步与异步日志系统 🌸 相关专栏推荐: C语言初阶系列 、 C语言进阶系列

    2024年02月09日
    浏览(38)
  • 【C++学习】类和对象--多态【待补充】

    多态是C++面向对象三大特性之一 静态多态:         函数重载和运算符重载属于静态多态,复用函数名(函数地址早绑定,编译阶段确定函数地址) 动态多态:         派生类和虚函数实现运行时多态(函数地址晚绑定,运行阶段确定函数地址)  案例: 输出:  但

    2024年02月02日
    浏览(29)
  • FreeRTOS 学习相关笔记 附C语言内容补充

    学习视频为【正点原子】手把手教你学FreeRTOS实时系统 裸机 裸机:前后台系统,前台系统指中断服务函数,后台系统指大循环。 裸机中断:是一瞬间的事情,不能处理太多问题。可以用来设置标志位,把执行函数放在主函数里面。 RTOS 1、高优先任务只有处于阻塞状态,才会

    2024年01月21日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包