【C++入门】内联函数、auto与基于范围的for循环
💞💞 前言
hello hello~ ,这里是大耳朵土土垚~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹
💥个人主页:大耳朵土土垚的博客
💥 所属专栏:C++入门至进阶
这里将会不定期更新有关C++的内容,希望大家多多点赞关注💖💖
目录
- 💞💞 前言
- 1.内联函数
- 1.1内联函数概念
- 1.2内联函数特点
- 2.auto关键字(C++11)
- 2.1auto介绍
- 2.2 auto使用细则
- 2.3 auto不能推导的场景
- 3.基于范围的for循环(C++11)
- 3.1 范围for的语法
- 3.2 范围for的使用条件
- 4.C++98中的指针空值
- 5.结语
1.内联函数
1.1内联函数概念
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。
- 内联函数通常在函数定义处使用关键字
inline进行声明,例如:
inline int add(int a, int b)
{return a + b;
}
在使用内联函数时,编译器会将函数的代码直接插入到调用处。这样可以减少函数调用的开销,特别是对于频繁调用的小函数,可以提高程序的执行效率。
1.2内联函数特点
- inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用:
缺陷:可能会使目标文件变大 ;
优势:少了调用开销,提高程序运行效率;
- inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,有的可能会直接忽略内联函数而直接当成普通的函数调用;
一般建议将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。
- 内联函数的定义必须在调用点之前;
- inline不建议声明和定义分离,分离会导致链接错误(因为inline被展开,就没有函数地址了,链接就会找不到)
例如:
// F.h
#include <iostream>
using namespace std;
inline void f(int i);
// F.cpp
#include "F.h"
void f(int i)
{cout << i << endl;
}
// main.cpp
#include "F.h"
int main()
{f(10);return 0;
}
// 链接错误:main.obj : error LNK2019: 无法解析的外部符号 "void __cdecl f(int)" (?f@@YAXH@Z),该符号在函数 _main 中被引用
结果如下:

上述例子可以发现内联函数声明定义最好不要分离,否则会出现链接错误;
总而言之,内联函数是一种编程技术,可以用于提高函数调用的效率,但需要根据具体情况权衡使用。
2.auto关键字(C++11)
2.1auto介绍
auto是一个C++11引入的关键字,用于自动推导变量的类型。通过使用auto关键字,编译器可以根据变量的初始化表达式自动推断出其类型。
使用auto关键字可以简化变量类型的声明,特别是当变量的类型相当复杂或较长时。例如:
auto number = 42; // 推导为int类型
auto name = "Alice"; // 推导为const char*类型
auto result = add(3, 4); // 推导为函数返回值的类型
在上述示例中,auto关键字根据初始化表达式的类型来推断变量的类型,避免了显式地声明变量类型。
例如:
int TestAuto()
{
return 10;
}
int main()
{
int a = 10;
auto b = a;
auto c = 'a';
auto d = TestAuto();
cout << typeid(b).name() << endl;//typeid用来显示变量类型
cout << typeid(c).name() << endl;
cout << typeid(d).name() << endl;
//auto e; 无法通过编译,使用auto定义变量时必须对其进行初始化
return 0;
}
结果如下:

使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型。
需要注意的是,auto关键字在编译时进行类型推导,而不是运行时。这意味着一旦变量的类型被推导出来,就不可更改。
2.2 auto使用细则
- auto与指针和引用结合起来使用
用auto声明指针类型时,用auto和auto*没有任何区别,但是用auto声明引用类型时则必须加&。例如:
int main()
{int x = 10;auto a = &x;auto* b = &x;auto& c = x;cout << typeid(a).name() << endl;cout << typeid(b).name() << endl;cout << typeid(c).name() << endl;*a = 20;*b = 30;c = 40;cout << x << endl;cout << *a << endl;cout << *b << endl;cout << c << endl;return 0;
}
结果如下:

上述例子可以看出a,b都是指向变量x的指针,改动它们指向的值,对应的x也会改变;c是x的引用类似于别名,对于c的改动,x也会相应变化;所以最后x、*a、*b、c的值相同;
- 在同一行定义多个变量
当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。例如:
void TestAuto()
{auto a = 1, b = 2;auto c = 3, d = 4.0; // 该行代码会编译失败,因为c和d的初始化表达式类型不同
}
结果如下:

上述例子可以看成当在同一行声明多个变量时,这些变量必须是相同的类型才能编译成功;
- 此外,
auto关键字也可以与其它类型修饰符一起使用,例如const、&等。例如:
const auto pi = 3.14159; // 推导为const double类型
const auto* ptr = &someVariable; // 推导为指向常量的指针类型
总而言之,auto关键字可以简化变量类型的声明,并提高代码的可读性和可维护性。然而,过度使用auto可能降低代码的可读性,因此在使用时需要谨慎权衡。
2.3 auto不能推导的场景
- auto不能作为函数的参数:
// 此处代码编译失败,auto不能作为形参类型
//因为编译器无法对a的实际类型进行推导
void TestAuto(auto a)//错误的
{
//...
}
- auto不能直接用来声明数组:
void TestAuto()
{int a[] = {1,2,3};auto b[] = {4,5,6};//错误的
}
- 为了避免与C++98中的auto发生混淆,C++11只保留了auto作为类型指示符的用法;
- auto在实际中最常见的优势用法就是跟下面讲到的C++11提供的新式for循环,还有lambda表达式等进行配合使用。
3.基于范围的for循环(C++11)
3.1 范围for的语法
在C++98中如果要遍历一个数组,可以按照以下方式进行:
void TestFor()
{
int array[] = { 1, 2, 3, 4, 5 };
//1.遍历下标来打印
for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)array[i] *= 2;
//2.利用指针来打印
for (int* p = array; p < array + sizeof(array)/ sizeof(array[0]); ++p)cout << *p << endl;
}
- 对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。
- 因此C++11中引入了基于范围的for循环;
for循环后的括号由冒号“ :”分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围。
void TestFor()
{int array[] = { 1, 2, 3, 4, 5 };for (auto e : array)//这里可以用auto也可以用intcout << e << " ";cout << endl;for (auto& e : array)e *= 2;for (auto e : array)cout << e << " ";}
结果如下:

这里将auto改为int:

可以看到这里auto改为int也可以运行,因为数组元素的类型是int;此外使用基于范围的for循环除了可以打印出数组的元素外还可以修改打印的值,但是这里要注意,数组的值是没有被改变的(因为for循环左边用于迭代的变量是临时变量拷贝了数组的值,它改变是不影响数组的元素的)
3.2 范围for的使用条件
- for循环迭代的范围必须是确定的
对于数组而言,就是数组中第一个元素和最后一个元素的范围;对于类而言,应该提供begin和end的方法,begin和end就是for循环迭代的范围。
注意:以下代码就有问题,因为for的范围不确定
void TestFor(int array[])//函数传参并不把整个数组传过去而是传数组首元素地址,所以没办法确定数组大小
{for(auto& e : array)cout<< e <<endl;
}
- 迭代的对象要实现++和==的操作。(关于迭代器这个问题,现在大家了解一下就可以了)
4.C++98中的指针空值
在良好的C/C++编程习惯中,声明一个变量时最好给该变量一个合适的初始值,否则可能会出现不可预料的错误,比如未初始化的指针。如果一个指针没有合法的指向,我们基本都是按照如下
方式对其进行初始化:
void TestPtr()
{
int* p1 = NULL;
int* p2 = 0;
// ……
}
NULL实际是一个宏,在传统的C头文件(stddef.h)中,可以看到如下代码:
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
可以看到,NULL可能被定义为字面常量0,或者被定义为无类型指针(void*)的常量。不论采取何种定义,在使用空值的指针时,都不可避免的会遇到一些麻烦,比如:
void f(int)
{cout<<"f(int)"<<endl;
}
void f(int*)
{cout<<"f(int*)"<<endl;
}
int main()
{f(0);f(NULL);f((int*)NULL);return 0;
}
结果如下:

在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强制转换为(void*)0。
从上述例子中可以看到程序本意是想通过f(NULL)调用指针版本的f(int*)函数,但是由于NULL被定义成0,因此与程序的初衷相悖。
所以在C++11中引入了nullptr关键字来代表一个空指针,用于表示指针不指向任何内存地址;
注意:
-
在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入的。
-
在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
-
为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr。因为它是一个类型安全的空指针常量,可以隐式转换为任何指针类型。它还有助于避免由于模糊的空指针值引起的潜在错误。
5.结语
以上就是有关C++入门中内联函数、auto关键字、基于范围的for循环以及nullptr所有有关的内容啦~ 完结撒花 ~🥳🎉🎉
相关文章:
【C++入门】内联函数、auto与基于范围的for循环
💞💞 前言 hello hello~ ,这里是大耳朵土土垚~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 💥个人主页&#x…...
服务器停用,备份服务文件。
文章目录 引言I 文件备份1.1 数据库文件/证书1.2 redis1.3 nacosII JAVA流水线备份2.1 java构建2.2 镜像构建2.3 docker 部署2.4 子模块构建2.5 Dockerfile_prodIII VUE项目流水线备份3.1 Node.js 构建3.2 Dockerfile_prod...
基于Python的深度学习的中文情感分析系统(V2.0),附源码
博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…...
使用Postman发送跨域请求实验
使用Postman发送跨域请求 1 跨域是什么?2 何为同源呢?3 跨域请求是如何被检测到的?4 Postman跨域请求测试4.1 后端准备4.2 测试用例4.2.1 后端未配置跨域请求(1) 前端不跨域(2)前端跨域 4.2.2 后端配置跨域信息(1&…...
4、jvm-垃圾收集算法与垃圾收集器
垃圾收集算法 分代收集理论 当前虚拟机的垃圾收集都采用分代收集算法,这种算法没有什么新的思想,只是根据对象存活周期的不同将内存分为几块。一般将java堆分为新生代和老年代,这样我们就可以根据各个年代的特点选择合适的垃圾收集算法。 比如…...
[Excel]如何限制儲存格輸入格式? 以“字首為英文字母大寫,其餘為數字,共15碼“為範例
[Excel]如何限制儲存格輸入格式 需求: 當一個excel表格需要由多位使用者來輸入資料時,難免會出現資料輸入錯誤問題,尤其是料號,品號或是訂單號的長類型編碼。若是問題屬於輸入錯誤"資料"但格式未錯誤,則可能需要讓exce…...
错题记录-华为海思
华为 海思数字芯片 参考 :FPGA开发/数字IC笔试系列(5) 华为海思IC笔试解析 FPGA开发/数字IC笔试系列(6) 华为海思IC笔试解析 SystemVerilog Function与Task的区别 $readmemh与$readmemb这两个系统任务是用来从指定文件中读取数据到寄存器数组或者RAM、ROM中。除了…...
rspack 使用构建vue3脚手架
基于 Rust 的高性能 Web 构建工具。rspack 主要适配 webpack 生态,对于绝大多数 webpack 工具库都是支持的。 启动速度快;增量热更新快。兼容 webpack 生态;内置了 ts、jsx、css、css modules 等开箱即用。生产优化,tree shaking…...
maven之pom中的build标签
1、build标签分类 1.1、全局配置(project build) 针对整个项目的所有情况都有效。 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation"htt…...
Cesium.js--》探秘Cesium背后的3D模型魔力—加载纽约模型
今天简单实现一个Cesium.js的小Demo,加强自己对Cesium知识的掌握与学习,先简单对这个开源库进行一个简单的介绍吧! Cesium 是一个开源的地理空间可视化引擎,用于创建基于 Web 的三维地球应用程序。它允许开发人员在网页上呈现高度…...
.NET i18n 多语言支持与国际化
环境 WIN10 VS2022 .NET8 1.👋创建项目 2.👀创建Resources Controllers HomeController.en.resx HomeController.fr.resx HomeController.zh.resx 3.🌱Program.cs添加国际化支持 // 添加国际化支持 builder.Services.AddLocalization(…...
基于Pytorch实现图像分类——基于jupyter
分类任务 网络基本构建与训练方法,常用函数解torch.nn.functional模块nn.Module模块 MNIST数据集下载 from pathlib import Path import requestsDATA_PATH Path("data") PATH DATA_PATH / "mnist"PATH.mkdir(parentsTrue, exist_okTrue)U…...
如何将CSDN的文章以PDF文件形式保存到本地
1.F12 打开开发者工具窗口 2.console下输入命令 (function(){$("#side").remove();$("#comment_title, #comment_list, #comment_bar, #comment_form, .announce, #ad_cen, #ad_bot").remove();$(".nav_top_2011, #header, #navigator").remove…...
面试经典150题——删除有序数组中的重复项
面试经典150题 day3 题目来源我的题解方法一 双指针 题目来源 力扣每日一题;题序:26 我的题解 方法一 双指针 使用两个指针分别指向相同元素的左右边界,再利用一个count记录最终需要的数组长度。 时间复杂度:O(n) 空间复杂度&a…...
Unity3D知识点精华浓缩
一、细节 1、类与组件的关系 2、Time.deltaTime的含义 3、怎么表示一帧的移动距离 4、Update和LateUpdate的区别和适用场景 5、找游戏对象的方式(别的对象 / 当前对象的子对象) 6、组件1调用组件2中方法的方式 7、在面板中获取外部数据的方法 8、序列化属…...
HTML的文档说明
1.告诉浏览器当前网页的版本 2.写法: !以前的写法:要依据网页的HTML的版本去确定,紫萼发油很多很多。 具体的写法可以参考:W3C官网的文档说明 !新写法:W3C都推荐用h5的写法 <DOCTYPE ht…...
ubuntu 更新或更改GCC/G++
最近遇到一些问题,需要用到gcc-9/g-9,但是我自带的ubuntu18.04是gcc-7.5/g-7.5,所以升级一下,奈何文章太多而且很多无效,所以在此记录一下: 参考:https://stackoverflow.com/questions/19836858…...
Java --- Java语言基础
这个Java可是个好东西,是一门面对对象的程序设计语言,其语法很类似C,所以学过C的伙伴们就很好上手,另外Java对C进行了简化与提高,这个在后期学习会感受到,Java还有很多的类库API文档以及第三方开发包。 这…...
【C++算法竞赛 · 图论】图的存储
前言 图的存储 邻接矩阵 方法 复杂度 应用 例题 题解 邻接表 方法 复杂度 应用 前言 上一篇文章中(【C算法竞赛 图论】图论基础),介绍了图论相关的概念和一种图的存储的方法,这篇文章将会介绍剩下的两种方法ÿ…...
Spring AOP IOC
spring的优缺点 IOC集中管理对象,对象之间解耦,方便维护对象AOP在不修改原代码的情况下,实现一些拦截提供众多辅助类,方便开发方便集成各种优秀框架 紧耦合和松耦合 松耦合可以使用单一职责原则、接口分离原则、依赖倒置原则 …...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

