C++入门(part 3)

ops/2024/11/14 23:54:47/

前言

在前文我们讲解了C++的诞生与历史,顺便讲解一些C++的小语法,本文会继续讲解C++的基础语法知识。

1.inline(内联函数)

  1. inline是C++新加入的关键字,用inline修饰的函数叫做内联函数,编译时C++编译器会在调用的地方将函数展开,这样每次调用内联函数就不需要建立新的栈帧,就可以提高效率
#include<iostream>
using namespace std;inline int Add(int& a, int& b)
{int ret = a + b;return ret;
}int Sub(int& a, int& b)
{int ret = a - b;return ret;
}
int main()
{int a = 10;int b = 5;// 可以通过汇编观察程序是否展开// 有call Add语句就是没有展开,没有就是展开了int ret = Add(a, b);cout << ret << endl;int tmp = Sub(a, b);cout << tmp << endl;return 0;
}

只要在有call一个地址就是没有展开。
在这里插入图片描述
我们看到不管是有inline修饰的函数,还是没有inline修饰的函数,他们都有在call一个地址(也就是没有展开函数),那不就和inline会展开函数的定义相悖吗。

其实是因为我使用的是VS编译器,VS编译器在debug版本下默认是不展开inline函数的,这样是为了方便调试,如果我们在VS中想要展开,那么就要设置一下两个地方。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

修改了这些之后,我们就可以看到inline的展开了

在这里插入图片描述

  1. 但是我们想要知道的是,inline对于编译器而言只是一个建议,也就是说,即使你在函数前加了inline,编译器也有可能不展开,不同编译器关于inline在什么情况下展开各不相同,因为C++标准并没有规定,所以inline适合的场景是使用频繁的短小函数,对于递归函数、代码比较多的函数,即使加上了inline,编译器也不会展开。

为什么要这样做呢,因为是防止有些程序员不靠谱,在每个函数前都加上inline,如果都展开,那么这个代码量就太大了。

假设我有一个一百行代码的函数a,并且我在函数前加上了inline,这时,我调用了1万次a,如果编译器在每次调用a的时候就展开,那么这个工程编译处理下来,至少要执行 100 ∗ 10000 100*10000 10010000(一百万)条可执行程序,这样效率就会下降。

如果不展开,那么编译处理下来,就只要执行 10000 + 100 10000+100 10000+100(call一百次)条可执行程序,比起前面的一万行,这时不展开的效率就会高很多。

//该函数在编译时就不会展开了
inline int Add(int& a, int& b)
{int ret = a + b;ret += 1;ret += 1;ret += 1;ret += 1;ret += 1;ret += 1;ret += 1;return ret;
}int main()
{int a = 10;int b = 5;// 可以通过汇编观察程序是否展开// 有call Add语句就是没有展开,没有就是展开了//inline修饰的函数int ret = Add(a, b);//cout << ret << endl;return 0;
}

在这里插入图片描述

  1. C++设计inline的目的是为了替代C的宏函数,虽然C语言的宏函数也会在预处理的时候替换展开,但是宏函数实现很复杂很容易出错,并且不好调试。

  2. inline不建议声明和定义分离到两个文件,分离会导致链接错误;因为inline被展开,就没有了函数地址,那么链接时就会报错。

//Func.h
#pragma once
#include<iostream>
using namespace std;
inline int Add(int& a, int& b);//Func.cpp
#include"Func.h"int Add(int& a, int& b)
{int ret = a + b;return ret;
}//test.cpp
#include"Func.h"
int main()
{int a = 10;int b = 5;int ret = Add(a, b);
}

在这里插入图片描述

2.nullptr

在C语言表述一个函数为空函数是使用NULL,但NULL其实是一个宏函数,在C头文件(stddef.h)中,可以看到如下代码:

#ifndef NULL#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif
#endif

这段代码的意思是,如果是在C语言环境下,那么NULL就会被定义成((void) * 0),如果是在C++环境下,那么就直接将NULL定义为0。无论采取何种定义,在使用空值的指针时,都不可避免的遇到一些问题,例如我想通过f(NULL)来调用指针版的f(int*)函数,但由于NULL被定义成了0,那么就会调用f(int x),这样就会于程序的目的相悖

#include<iostream>
#include<stdlib.h>
using namespace std;
void F(int x)
{cout << "void F(int x)" << endl;
}void F(int* x)
{cout << "void F(int* x)" << endl;
}int main()
{F(0);F(NULL);return 0;
}

在这里插入图片描述
并且我们调用f((void*)NULL)时也会报错,因为C++检查的更严格,C++环境下,void*不会自动转换成对于的类型*,如果要转换,就必须使用强制类型转换(C语言会自动转换)。
在这里插入图片描述

既然NULL在定义上已经不是一个指针了,那么我们就需要一个真正意义上的空指针。

那么C++11就引入了nullptr,nullptr是一个特殊的关键字,是一种特殊类型的字面量,他可以转换成任意类型的指针类型。使用nullptr定义空指针也可以避免类型转换的问题,因为nullptr只能被隐式转换为指针类型,不能被上转换成其他类型。

#include<iostream>
#include<stdlib.h>
using namespace std;
void F(int x)
{cout << "void F(int x)" << endl;
}void F(int* x)
{cout << "void F(int* x)" << endl;
}int main()
{F(0);F(NULL);//F((void*) NULL);F(nullptr);int* a = nullptr;double* b = nullptr;//int x = nullptr;return 0;
}

在这里插入图片描述
在这里插入图片描述

结语

本文进一步讲解了c++基础知识,讲解了关键词inline的使用,如何在VS下看到以及他的目的和角色;讲解了nullptr的诞生原因以及使用。

最后感谢您能阅读完此片文章,如果有任何建议或纠正欢迎在评论区留言,也可以前往我的主页看更多好文哦(点击此处跳转到主页)。
如果您认为这篇文章对您有所收获,点一个小小的赞就是我创作的巨大动力,谢谢!!!


http://www.ppmy.cn/ops/110290.html

相关文章

从JVM角度看对象创建过程和内存布局

文章目录 从JVM角度看对象创建过程和内存布局 1.创建对象的方式2.创建对象的步骤2.1.对象判断2.2.分配内存2.3.处理并发问题2.4.初始化分配到的内存2.5. 设置对象的对象头2.6.执行init方法初始化 3.对象内存布局3.1.对象头3.1.1运行时元数据3.1.2.类型指针 3.2实例数据3.3.对齐…

Vue 中阻止点击事件穿透

在 Vue.js 应用中&#xff0c;处理用户交互是常见的需求&#xff0c;尤其是点击事件。然而&#xff0c;在某些情况下&#xff0c;我们可能需要阻止点击事件穿透到下层元素&#xff0c;这可以优化用户体验并防止不必要的事件处理。本文将探讨在 Vue 中如何有效地阻止点击事件穿透…

hive时间函数

一、随机示例&#xff08;想到哪里写哪里&#xff09; 1.系统时间函数 查询 select current_timestamp --当前格式化时间,current_date --当前格式化日期,unix_timestamp() --当前unix时间戳 结果&#xff1a; 2.时间函数转换 查询 --将时间戳转化为格式化时间 sel…

Java后端程序员简单操作Linux系统命令

Linux系统概述 Linux 内核最初是由芬兰人林纳斯托瓦兹&#xff08;Linus Torvalds&#xff09;在赫尔辛基大学上 学时而编写的一个开源的操作系统。 Linux&#xff08;管理计算机硬件资源&#xff0c;任务调度&#xff09;支持多用户&#xff0c;支持网络&#xff0c;支持多线…

打造专业级PPT:用Python-pptx精准编辑图表属性

哈喽,大家好,我是木头左! 本文将深入探讨如何使用python-pptx库来调整图表类型、颜色和样式,从而提升你的PPT图表的专业度和吸引力。 图表类型的选择与转换 图表类型是影响信息传达的关键要素之一。python-pptx允许用户通过编程方式修改图表类型,以适应不同的数据展示需求…

【鸿蒙】HarmonyOS NEXT星河入门到实战1-开发环境准备

目录 一、达成目标 二、鸿蒙开发环境准备 2.1 开发者工作下载 2.2 解压安装 2.3 运行配置安装node.js和SDK 2.4 开始创建第一个项目 2.5 预览 2.5.1 预览遇到的问题&#xff08;报错&#xff09; 2.5.2 修改内容查看预览 三、备用下载地址&#xff08;如果下载是4.X版…

【数据结构与算法 | 灵神题单 | 删除链表篇】力扣2487, 237

1. 力扣2487&#xff1a;从链表中删除节点 1.1 题目&#xff1a; 给你一个链表的头节点 head 。 移除每个右侧有一个更大数值的节点。 返回修改后链表的头节点 head 。 示例 1&#xff1a; 输入&#xff1a;head [5,2,13,3,8] 输出&#xff1a;[13,8] 解释&#xff1a;需…