【C++起飞之路】初级—— auto、范围for循环、宏函数和内联函数

auto、范围for、内联函数、宏函数和nullptr

  • 一、auto — 类型推导的魔法(C++ 11)
    • 1、auto 是什么?
    • 2、工作原理
    • 3、优势
    • 4、限制和注意事项
  • 二、范围for (C++11)
    • 1、基本语法
    • 2、优势
    • 3、工作原理
    • 4、注意事项
    • 5、C++11: 范围 for 循环的扩展:
  • 三、宏函数
    • 1、优势
    • 2、宏函数的危险
  • 四、内联函数
    • 1、基本概念
    • 2、工作原理
    • 3、优势
    • 4、注意事项
    • 5、内联函数与编译器优化

一、auto — 类型推导的魔法(C++ 11)

C++11 引入的 auto 关键字在现代 C++ 编程中扮演着重要的角色。它不仅使代码更加简洁,还提供了更好的可读性和灵活性

1、auto 是什么?

auto 是 C++ 中的一个关键字,用于实现类型推导。它允许编译器在变量声明时根据初始化表达式的类型自动推导变量的类型
→ 这样,我们可以避免显式指定变量类型,减少代码冗余,同时保持类型安全。

typeid 可以查看对象类型,需要#include<typeinfo>
用法: typeid(c).name(),c是变量名
在这里插入图片描述

2、工作原理

在编译过程中,auto 关键字的使用会被编译器替换为实际的类型。

编译器会通过初始化表达式来推导变量的类型,然后将推导出的类型替换到 auto 处。这意味着 auto 并不是一个新的数据类型,而只是一种方便的声明方式。

3、优势

  • a. 简洁: 使用 auto 可以省略变量类型的冗长声明,使代码更加简洁。

  • b. 可读性: auto 提供了更清晰的代码,读者可以更容易地理解代码的含义,而不必深入研究类型。

  • c. 容器迭代: 在遍历容器时,auto 的使用可以避免手动指定容器类型,从而提高可读性和灵活性。

  • d. 跨平台性: auto 在一些情况下可以帮助提高代码的可移植性,因为它减少了对特定数据类型大小的依赖。

4、限制和注意事项

  • a. 必须在声明时进行初始化: auto 变量必须在声明时进行初始化,以便编译器能够推导出其类型。

  • b. 不适用于函数参数和返回值: auto 通常用于声明变量,而不适用于函数参数和返回值的类型。

  • c. 可能导致意外推导: 对于某些表达式,auto 的推导可能与预期不符,需要小心处理。

  • d. 不适用于非静态成员变量: auto 不适用于非静态成员变量的声明。

  • e.不能定义数组 :※auto arr[ ] = {1,2,2,1}; //wrong

♥ 数组是一种比较特殊的数据结构,其大小和元素类型都是数组类型的一部分,而不是表达式的一部分

auto 关键字不能直接用于定义数组,是因为数组的大小和元素类型是数组类型的一部分,而 auto 只关注初始化表达式的类型推导,无法同时推导数组的大小和元素类型。

例如,一个 int 数组和一个 double 数组的类型是不同的,即使它们的大小相同。而 auto 关键字在推导类型时只关注初始化表达式的类型,无法同时推导出数组的大小和元素类型。
然而,在 C++11 引入的标准中,我们可以使用 decltype 关键字来间接推导数组类型:
在这里插入图片描述

  • 注意定义变量a的时候就不可以加[ ]

使用 decltype 可以将数组的类型精确地推导出来,但是仍然无法推导数组的大小

二、范围for (C++11)

1、基本语法

范围 for 循环是一种用于遍历容器的现代方式,它的基本语法如下:

for (element_declaration : container) 
{// 循环体
}

在这里,element_declaration 是一个声明,用于指定在每次迭代中存储容器中的元素。container 则是要遍历的容器,可以是数组、标准容器(如 vector、list、map 等)或用户自定义的容器类型。

2、优势

  • a. 可读性提高: 语法上更加简洁,将遍历的核心逻辑更突出,减少了迭代器和索引的干扰。

  • b. 避免越界错误: 避免了手动管理迭代器或索引的问题,从而减少了越界错误和其他低级错误的可能性。

  • c. 自动推导元素类型: 自动推导出容器中的元素类型,无需显式指定,减少冗余信息。

3、工作原理

范围 for 循环实际上是使用迭代器来遍历容器的。编译器会在幕后自动生成迭代器的代码,以便访问容器中的每个元素。对于不同类型的容器,编译器会使用适当的迭代器,因此开发者无需担心不同容器类型的迭代器实现。

4、注意事项

  • a. 不适用于修改元素: 范围 for 循环在遍历容器时只能读取元素,不能修改元素的值。如果需要修改元素,应该使用传统的 for 循环或迭代器。chu

  • b. 自动推导类型限制: 范围 for 循环中的元素类型是自动推导的,因此可能会受到类型推导的限制。对于需要精确类型控制的场景,可能需要使用传统 for 循环。

  • c. for循环迭代的范围必须是确定的:对于数组而言,第一个元素 -> 最后一个元素 即是数组的范围;但是对于函数传参而言,传递数组的时候是以指针传过去的,无法确定范围。

5、C++11: 范围 for 循环的扩展:

在 C++11 以后的版本中,范围 for 循环的功能得到了扩展。

除了遍历容器,还可以遍历初始化列表、数组、字符串等。甚至可以使用 auto 关键字来自动推导元素类型。

遍历的原理:自动取遍历目标的每一个元素,再放到给定的临时变量中,自动判断结束。
auto 会根据遍历目标的元素类型自动推导

std::initializer_list<int> numbers = {1, 2, 3, 4, 5};
for (auto num : numbers) 
{// ...
}

👆 就是取 numbers 的元素放到 num 中,自动判断循环结束。(直接写数组的类型也可以 )

三、宏函数

宏函数是 C++ 中的一种预处理技术,使用预定义的宏名称将代码片段替换为文本
这种替换在编译前进行(→ 不会在运行时引入额外的开销),不进行类型检查或语法分析

例如,我们可以使用 #define 来定义宏函数:

#define Add(x, y) ((x) + (y)) 

但是如果写成#define Add(x, y) (x + y) 就麻烦了,因为是“替换”而不是“调用”,x和y有可能是表达式,计算结果就有可能与期望值不符

1、优势

  • a. 强大的代码生成能力: 宏函数可以生成复杂的代码片段,减少重复性工作,提高开发效率。

  • b. 参数灵活: 宏函数可以接受任意数量和类型的参数,使其在某些情况下比普通函数更灵活。

  • c. 编译前处理: 宏函数的替换发生在编译前,因此不会在运行时引入额外的开销。

2、宏函数的危险

  • a. 缺乏类型安全: 宏函数的替换是文本级别的,不进行类型检查。这可能导致意外的类型问题。

  • b. 难以调试: 宏函数的错误可能在编译后才会暴露,难以追踪和修复

  • c. 可读性和维护性: 复杂的宏函数可能会降低代码的可读性和可维护性,因为它们隐藏了实际的逻辑。

随着现代 C++ 的发展,许多宏函数的使用场景已经被更安全和可读性更好的特性取代,比如:内联函数可以提供类似宏函数的性能优势,同时也会进行类型检查,增加代码的安全性。

四、内联函数

内联说明:只是向编译器发出的一个请求,编译器可以选择忽略这个请求

1、基本概念

内联函数是通过在函数声明前加上 inline 关键字来定义的函数。

它告诉编译器,在每次函数调用处将函数体直接插入,而不是传统的函数调用-返回过程。这样可以避免函数调用的开销,提高程序的性能。

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

2、工作原理

内联函数的核心思想是 在编译器将函数调用处的代码直接替换为函数体,类似于代码的复制粘贴。空间换时间的思想

这样,避免了函数调用和返回的开销,但也可能会增加代码的体积。编译器会在合适的情况下自动进行内联,不过也可以使用 inline 关键字来显式指示。

3、优势

  • a. 减少函数调用开销: 可以大幅减少函数调用时的开销,特别是对于短小、需要频繁调用的函数

  • b. 提高程序性能: 能够在一定程度上减少函数调用的开销,从而提高程序的执行速度。

  • c. 代码可读性: 将函数体直接嵌入到调用处,使代码更加紧凑,特别是对于简单的计算型函数。

4、注意事项

  • a. 适用范围: 内联函数适用于函数体简单且函数调用频繁的情况。对于复杂的函数体,内联可能会导致代码体积增大,影响缓存效率。

  • b. 编译器决策: 编译器会根据代码的复杂度和上下文来决定是否内联函数。可以使用编译器指示来强制内联,但也需要权衡代码大小和性能。

  • c. 大型函数不适合内联: 大型函数的内联可能会导致代码膨胀,甚至适得其反。在这种情况下,更适合使用传统的函数调用方式。

5、内联函数与编译器优化

现代编译器在优化代码时会考虑是否将函数内联。然而,编译器的优化决策可能因编译器版本、编译选项和具体代码而异。因此,我们应该了解编译器的优化行为,可以使用编译器特定的指示来控制内联行为~~

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

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

相关文章

软件测试基础篇——LAMP环境搭建

LAMP 1、Linux系统的其他命令 find命令&#xff1a;在目录下查找文件 ​ 格式一&#xff1a;find 路径 参数 文件名 ​ 路径&#xff1a;如果没有指定路径&#xff0c;默认是在当前目录下 ​ 参数&#xff1a;-name 根据文件名来查找&#xff0c;区分大小写&#xff1b; -…

适配器模式(C++)

定义 将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 应用场景 在软件系统中&#xff0c;由于应用环境的变化&#xff0c;常常需要将“一些现存的对象 ”放在新的环境中应用&#xff0c;但是新环境要求…

sql高频面试题-连续完成两个指定动作的用户统计

用户行为分析 业务背景 某购物APP最近上线了一个新功能&#xff0c;用户签到后可以跳转到大转盘抽奖&#xff0c;抽奖获得的奖金可以抵消购物的费用&#xff0c;以此来培养用户使用app的习惯。 数据表介绍 现有一张用户行为表action_log&#xff0c;主要字段如下&#xff0c…

Styletron: 面向组件的样式设计工具包

styletron官网&#xff1a; styletron的GitHub链接&#xff1a; styletron-react 一. 介绍 Styletron是一个通用的component-oriented&#xff08;面向组件的&#xff09;样式工具。它属于css-in-js类别。Styletron可以很好地与React配合使用&#xff0c;但也可以与其他框架或…

docker复现nginx错误配置漏洞

目录 一、nginx环境搭建 1.1搭建步骤 二、docker复现Nginx配置漏洞 2.1安装docker 2.2复现过程 2.1CRLF(carriage return/line feed)注入漏洞 2.2.目录穿越 一、nginx环境搭建 1.1搭建步骤 1.先创建Nginx的目录并进入&#xff08;命令如下&#xff09; mkdir /soft &&…

Android Framework底层原理之WMS的启动流程

一 概述 今天&#xff0c;我们介绍 WindowManagerService&#xff08;后续简称 WMS&#xff09;的启动流程&#xff0c;WMS 是 Android 系统中&#xff0c;负责窗口显示的的服务。在 Android 中它也起着承上启下的作用。 如下图&#xff0c;就是《深入理解 Android》书籍中的…

【C++】STL初识

1.STL的基本概念 2.vector存放内置数据类型 #include <iostream> using namespace std; #include <vector> #include <algorithm>void MyPrint(int val) {cout << val << endl; }void test01() {//创建vector容器对象&#xff0c;并且通过模板参…

Harbor企业镜像仓库部署(本地)

简述&#xff1a; Docker 官方镜像仓库是用于管理公共镜像的地方&#xff0c;大家可以在上面找到想要的镜像&#xff0c;也可以把自己的镜像推送上去。但是有时候服务器无法访问互联网&#xff0c;或者不希望将自己的镜像放到互联网上&#xff0c;那么就需要用到 Docker Regis…

Leetcode-每日一题【剑指 Offer 15. 二进制中1的个数】

题目 编写一个函数&#xff0c;输入是一个无符号整数&#xff08;以二进制串的形式&#xff09;&#xff0c;返回其二进制表达式中数字位数为 1 的个数&#xff08;也被称为 汉明重量).&#xff09;。 提示&#xff1a; 请注意&#xff0c;在某些语言&#xff08;如 Java&…

【Docker】Windows下docker环境搭建及解决使用非官方终端时的连接问题

目录 背景 Windows Docker 安装 安装docker toolbox cmder 解决cmder 连接失败问题 资料获取方法 背景 时常有容器方面的需求&#xff0c;经常构建调试导致测试环境有些混乱&#xff0c;所以想在本地构建一套环境&#xff0c;镜像调试稳定后再放到测试环境中。 Windows …

多线程与高并发--------线程池

线程池 一、什么是线程池 在开发中&#xff0c;为了提升效率的操作&#xff0c;我们需要将一些业务采用多线程的方式去执行。 比如有一个比较大的任务&#xff0c;可以将任务分成几块&#xff0c;分别交给几个线程去执行&#xff0c;最终做一个汇总就可以了。 比如做业务操…

Windows电脑快速搭建FTP服务教程

FTP介绍 FTP&#xff08;File Transfer Protocol&#xff09;是一种用于在计算机网络上进行文件传输的标准协议。它提供了一种可靠的、基于客户端-服务器模型的方式来将文件从一个主机传输到另一个主机。在本文中&#xff0c;我将详细介绍FTP的工作原理、数据传输模式以及常见…

数据结构【第4章】——栈与队列

队列是只允许在一端进行插入操作、而在另-端进行删除操作的线性表。 栈 栈与队列&#xff1a;栈是限定仅在表尾进行插入和删除操作的线性表。 我们把允许插入和删除的一端称为栈顶&#xff08;top&#xff09;&#xff0c;另一端称为栈底&#xff08;bottom&#xff09;&…

VBA技术资料MF42:VBA_从Excel中上面的单元格复制公式

【分享成果&#xff0c;随喜正能量】唯有梦想才配让你不安&#xff0c;唯有行动才能解除你的不安.绳锯木断&#xff0c;水滴石穿。也许你现在做的事情很小&#xff0c;只要你能日积月累的坚持下去&#xff0c;才会发现意义非凡。所谓的成功&#xff0c;便是别人失败的时候你还在…

微服务与Nacos概述-2

微服务间消息传递 微服务是一种软件开发架构&#xff0c;它将一个大型应用程序拆分为一系列小型、独立的服务。每个服务都可以独立开发、部署和扩展&#xff0c;并通过轻量级的通信机制进行交互。 应用开发 common模块中包含服务提供者和服务消费者共享的内容 provider模块是…

10-1_Qt 5.9 C++开发指南_Data Visualization实现数据三维显示

Data Visualization 是 Qt 提供的用于数据三维显示的模块。在 Qt 5.7 以前只有商业版才有此模块&#xff0c;而从Qt5.7 开始此模块在社区版本里也可以免费使用了。Data Visualization 用于数据的三维显示&#xff0c;包括三维柱状图、三维空间散点、三维曲面等。Data Visualiza…

鉴源实验室丨汽车网络安全攻击实例解析(二)

作者 | 田铮 上海控安可信软件创新研究院项目经理 来源 | 鉴源实验室 社群 | 添加微信号“TICPShanghai”加入“上海控安51fusa安全社区” 引言&#xff1a;汽车信息安全事件频发使得汽车行业安全态势愈发紧张。这些汽车网络安全攻击事件&#xff0c;轻则给企业产品发布及产品…

高效数据传输:轻松上手将Kafka实时数据接入CnosDB

本篇我们将主要介绍如何在 Ubuntu 22.04.2 LTS 环境下&#xff0c;实现一个KafkaTelegrafCnosDB 同步实时获取流数据并存储的方案。在本次操作中&#xff0c;CnosDB 版本是2.3.0&#xff0c;Kafka 版本是2.5.1&#xff0c;Telegraf 版本是1.27.1 随着越来越多的应用程序架构转…

无涯教程-Perl - redo函数

描述 此函数将重新启动当前循环,而不会强制判断控制语句。块中不再执行任何语句。如果存在继续块,将不会执行。如果指定了LABEL,则在LABEL标识的循环开始时重新开始执行。 语法 以下是此函数的简单语法- redo LABELredo返回值 此函数不返回任何值。 例 以下是显示其基本…

用友时空KSOA SQL注入漏洞复现(HW0day)

0x01 产品简介 用友时空KSOA是建立在SOA理念指导下研发的新一代产品&#xff0c;是根据流通企业最前沿的I需求推出的统一的IT基础架构&#xff0c;它可以让流通企业各个时期建立的IT系统之间彼此轻松对话&#xff0c;帮助流通企业保护原有的IT投资&#xff0c;简化IT管理&#…