【C++】C++入门(下)--内联函数 auto关键字 nullptr

目录

一 内联函数

1 内联函数概念和定义

 2 内联函数特性

二 auto关键字

1 auto概念

2 auto 的使用细则

(1) auto与指针和引用结合起来使用

(2) 在同一行定义多个变量

3 auto不能推导的场景

(1) auto不能作为函数的参数

(2) auto不能直接用来声明数组

4 基于范围的for循环

(1)使用

(2) 范围for的使用条件

三 指针空值nullptr(C++11)


一 内联函数

1 内联函数概念和定义

以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调 用建立栈帧的开销,内联函数提升程序运行的效率。

一定会展开 吗? 不一定,因为inline只是一种建议,需要看此函数是否能够成为内联函数

先看看宏

#define ADD(x, y) ((x) + (y))// 宏的缺点
// 1、容易出错,语法细节多
// 2、不能调试
// 3、没有类型安全的检查int main()
{//替换看int ret1 = ADD(2, 3)*5; // ((2)+(3))*5cout << ret1 << endl;return 0;
}

用内联函数替代宏函数

// 可以调试
// 效率高,会展开
// 好写,语法简单
inline int Add(int x, int y)
{int c = x + y;return c;
}int main()
{int ret1 = Add(1, 2);// 优点:不用建立栈帧,提高效率cout << ret1 << endl;return 0;
}

 2 内联函数特性

1. inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用,

缺陷:可能会使目标文件变大

优势:少了调用开销,提高程序运 行效率。

2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同

一般建议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、不是循环, 且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。

循环语句和递归语句违背内联函数本质

3. 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 

二 auto关键字

1 auto概念

在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量

C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一 个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得

#include<iostream>
using namespace std;
int Test()
{return 10;
}
int main()
{int a = 10;auto b = a;auto c = 'a';auto d = Test();auto e = &a;auto& f = a;// &是不能省略的cout << typeid(b).name() << endl;cout << typeid(c).name() << endl;cout << typeid(d).name() << endl;cout << typeid(e).name() << endl;cout << typeid(f).name() << endl;//auto k; 无法通过编译,使用auto定义变量时必须对其进行初始化return 0;
}

使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto 的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编 译期会将auto替换为变量实际的类型。

2 auto 的使用细则

(1) 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 << *a << endl;cout << *b << endl;cout << c << endl;return 0;
}

(2) 在同一行定义多个变量

当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译 器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量

void TestAuto()
{auto a = 1, b = 2;auto c = 3, d = 4.0;  // 该行代码会编译失败,因为c和d的初始化表达式类型不同
}

3 auto不能推导的场景

(1) auto不能作为函数的参数

// 此处代码编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
void Test(auto a)
{}

(2) auto不能直接用来声明数组

void Test()
{int a[] = { 1,2,3 };auto b[] = { 4,5,6 };//此行代码是错误的
}

4 基于范围的for循环

(1)使用

C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范 围内用于迭代的变量,第二部分则表示被迭代的范围。

void TestFor()
{int array[] = { 1, 2, 3, 4, 5 };// 依次取数组中数组赋值给e// 自动判断结束,自动++往后走for (auto& e : array)e *= 2;for (auto e : array)cout << e << " ";
}int main()
{TestFor();
}

与普通循环类似,可以用continue来结束本次循环,也可以用break来跳出整个循环 

(2) 范围for的使用条件

对于数组而言,就是数组中第一个元素和最后一个元素的范围;对于类而言,应该提供 begin和end的方法,begin和end就是for循环迭代的范围。

注意:以下代码就有问题,因为for的范围不确定

void TestFor(int array[])
{for (auto& e : array)cout << e << endl;
}

迭代的对象要实现++和==的操作这个后面说

三 指针空值nullptr(C++11)

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;
}

程序本意是想通过f(NULL)调用指针版本的f(int*)函数,但是由于NULL被定义成0,因此与程序的 初衷相悖。 在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器 默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void *)0。

void f(int)
{cout << "f(int)" << endl;
}
void f(int*)
{cout << "f(int*)" << endl;
}
int main()
{f(0);f(nullptr);f((int*)NULL);return 0;
}

注意:

1. 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入 的。

2. 在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。

3. 为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr。

 

C++入门算是搞完了, 分了上中下, 大家可以整体看, 也可以选择性看, 总之C++入门是进入C++的重要基础.

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

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

相关文章

关于深度学习中Attention的一些简单理解

Attention 机制 Attention应用在了很多最流行的模型中&#xff0c;Transformer、BERT、GPT等等。 Attention就是计算一个加权平均&#xff1b;通过加权平均的权值来自计算每个隐藏层之间的相关度&#xff1b; 示例 Attention 机制 Attention应用在了很多最流行的模型中&am…

C# 海康威视平台API接入 和网页摄像头部署

文章目录 前言相关网址综合安防管理平台网址获取Appkey和Secret/密码和密钥测试个人魔改工具类 海康视频接入获取摄像头Id下载海康Web插件原生Html导入网页设置 JS封装封装代码使用设置成功&#xff01; 前言 最近有个需求是将海康的摄像头视频画面传到我们平台上&#xff0c;…

C# OpenCvSharp Yolov8 Face Landmarks 人脸特征检测

效果 项目 代码 using OpenCvSharp; using OpenCvSharp.Dnn; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;namespace OpenCvSharp_Yolov8_Demo {public partial class frmMain…

FL Studio21.2演示版下载

FL Studio 21.2 带有 stem 分离和 FL Cloud&#xff0c;这是一项专为 FL Studio 打造的具有里程碑意义的新服务。其他新功能包括 FL Studio Fruity Edition 的 Audio Clips&#xff08;音频剪辑&#xff09;和一个新的模拟建模合成器 Kepler。 为庆祝 FL Studio 21.2 的发布&am…

Vue实现首页导航和左侧菜单,介绍mock.js并实现登录注册间的跳转,实现左侧栏折叠效果,优化Main.vue组件,使用mock.js生成随机响应数据

目录 1. mockjs 1.1 mockjs介绍 1.2 mockjs使用步骤 1.2.1 安装mockjs依赖 1.2.2 在项目中引入mockjs 1.2.3 创建目录和文件 1.2.4 为每个组件准备模拟数据 1.2.5 测试 1.2.6 前端调试 1.2.7 mockjs生成随机响应数据 1.2.8 根据不同响应&#xff0c;给出不同提示 2…

二进制搭建 Kubernetes+部署网络组件+部署CornDNS+负载均衡部署+部署Dashboard

二进制搭建 Kubernetes v1.20 k8s集群master01&#xff1a;20.0.0.50 kube-apiserver kube-controller-manager kube-scheduler etcd k8s集群master02&#xff1a;20.0.0.100k8s集群node01&#xff1a;20.0.0.110 kubelet kube-proxy docker etcd k8s集群node02&#xff1a;20.…

如何通过adb控制安卓手机wifi

一、准备工作 1、先用USB数据线 将手机和电脑连接在一起 1&#xff09; 数据线连接手机和电脑&#xff0c;选择“传输文件”的连接方式&#xff1b; 2&#xff09; 在手机上&#xff0c;打开“开发者选项”、“USB调试”&#xff1b; 2、在电脑上安装adb工具&#xff0c;参考…

MySQL(2):环境搭建

1.软件下载 软装去官网下载&#xff08;社区版&#xff09;&#xff1a;https://downloads.mysql.com/archives/installer/&#xff08;历史版本可选&#xff09; 选择下面的&#xff0c;一步到位 2.软件安装 双击 .msi 文件 选完 Custom 自定义后点 next 按 1&#xff0c…

软通动力:打造AI第二增长曲线,图谋新发展

【科技明说 &#xff5c; 重磅专题】 软通动力对于AI的想法还是比较久了&#xff0c;之前在与业内朋友聊到软通动力之时&#xff0c;曾提到软通动力的根基还是在于其多年来的软件服务能力&#xff0c;目前借助AI技术创新的机遇将软件服务能力进一步放大&#xff0c;扩展到更多行…

人工智能基础_机器学习006_有监督机器学习_正规方程的公式推导_最小二乘法_凸函数的判定---人工智能工作笔记0046

我们来看一下公式的推导这部分比较难一些, 首先要记住公式,这个公式,不用自己理解,知道怎么用就行, 比如这个(mA)T 这个转置的关系要知道 然后我们看这个符号就是求X的导数,X导数的转置除以X的导数,就得到单位矩阵, 可以看到下面也是,各种X的导数,然后计算,得到对应的矩阵结…

高阶数据结构学习 —— 图(2)

文章目录 1、BFS1、DFS 1、BFS 广度优先。确定从哪个点开始&#xff0c;然后用队列来完成遍历。拿出一个点就把和这个点相连的其它点放进去&#xff0c;但是这样前面放进过队列的也有可能被再次放入&#xff0c;所以需要做好标记。一个队列&#xff0c;一个标记容器。在邻接矩…

蓝桥杯每日一题2023.10.25

乘积尾零 - 蓝桥云课 (lanqiao.cn) 题目描述 题目分析 由于需要相乘的数很多&#xff0c;所以我们不能直接进行暴力模拟&#xff0c;我们知道10 2 * 5&#xff0c; 所以我们只需要找出这个数2和5的个数&#xff0c;其中2和5个数小的那个则为末尾0出现的个数 #include<bi…

搭建微信小程序环境及项目结构介绍

一、注册 访问微信公众平台&#xff0c;将鼠标的光标置于账号分类中的小程序上&#xff0c; 点击‘查看详情’ 点击“前往注册” 下方也可以点击注册&#xff1a; 小程序注册页面&#xff1a; 步骤a:进入小程序注册页&#xff0c;根据指引填写信息和提交相应的资料&#x…

黔院长 | 一文了解五脏的脏象!

你知道五脏的脏象是怎样的吗&#xff1f;下面一起来了解一下吧。 首先是我们的心&#xff0c;心主血脉&#xff0c;在体合脉&#xff0c;开窍于舌&#xff0c;其华在面。是说心脏是我们生命的根本&#xff0c;心气推动全身的血脉得以正常运行&#xff0c;心发生的生理和病理可…

应用案例|基于三维机器视觉的曲轴自动化上下料应用方案

Part.1 项目背景 此案例服务对象为国内某知名大型汽车零部件制造工厂&#xff0c;该工厂有针对曲轴工件的自动化上下料需求。由于之前来料码放不规范&#xff0c;工件无序散乱摆放&#xff0c;上料节拍要求高&#xff0c;该工厂上下料效率极低。 Part.2 传统曲轴上下料存在的缺…

【python图像处理】模糊图像

模糊前 模糊后 模糊 import os from PIL import Image, ImageFilterfacesPath face # 图片文件夹路径 faces os.listdir(facesPath) for face in faces:facePath os.path.join(facesPath, face)image Image.open(facePath)blurred_image image.filter(ImageFilter.BLU…

GoLong的学习之路(十三)语法之标准库 log(日志包)的使用

上回书说到&#xff0c;flag的问题。这回说到日志。无论是软件开发的调试阶段还是软件上线之后的运行阶段&#xff0c;日志一直都是非常重要的一个环节&#xff0c;我们也应该养成在程序中记录日志的好习惯。 文章目录 log配置logger配置日志前缀配置日志输出位置自定义logger …

AI:39-基于深度学习的车牌识别检测

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌本专栏包含以下学习方向: 机器学习、深度学…

ES6 模块化编程 详解

目录 一、基本介绍 二、基本原理示意图 三、传统CommonJS实现模块化编程 1.介绍 : 2.实例 : 四、ES6新特性实现模块化编程 1.介绍 : 2.实例 : 一、基本介绍 (1) ES6新特性——模块化编程&#xff0c;用于解决传统非模块化开发中出现的"命名冲突", "文件…

英语兔语法笔记(1)动词分类+动词时态

B站英语兔的语法课&#xff0c;强推&#xff01;和学校里面的不同&#xff0c;通俗易懂&#xff0c;看过之后真的醍醐灌顶~ 英语兔语法网课https://www.bilibili.com/video/BV1XY411J7aG?p1&vd_source1d1be06bfa4daa398bc518a66de92cf8 一.动词分类 大致看一下就好&…