C++入门(part 3)

news2024/11/14 15:00:51

前言

在前文我们讲解了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.coloradmin.cn/o/2131971.html

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

相关文章

数据中台 | 数据资源管理平台介绍

01 产品概述 数据资源的盘查、集成、存储、组织、共享等全方位管理能力&#xff0c;无论对于企业的数字化转型&#xff0c;还是对企业数据资产的开发、运营、交易及入表&#xff0c;都具有极为关键的作用。今天&#xff0c;小兵就来为大家介绍我们自研数据智能平台中的核心产品…

废品回收小程序搭建,回收市场的机遇

随着经济的快速发展&#xff0c;居民生活水平普遍提高&#xff0c;产生的各类废品也在不断增加&#xff0c;为废品回收市场提供了发展基础。当下&#xff0c;在大众环保意识增加下&#xff0c;废品回收行业也将成为一个具有广阔发展前景的朝阳行业&#xff01; 目前&#xff0…

C++vector类 (带你一篇文章搞定C++中的vector类)

感谢大佬的光临各位&#xff0c;希望和大家一起进步&#xff0c;望得到你的三连&#xff0c;互三支持&#xff0c;一起进步 数据结构习题_LaNzikinh篮子的博客-CSDN博客 初阶数据结构_LaNzikinh篮子的博客-CSDN博客 收入专栏&#xff1a;C_LaNzikinh篮子的博客-CSDN博客 其他专…

代码随想录27期|Python|Day54|​单调栈|​42. 接雨水|84. 柱状图中最大的矩形

42. 接雨水 根据常识可以归纳出&#xff0c;对于每一列所能够存住的水的高度 Height min(LeftMax, RightMax) - height 也就是&#xff0c;当前列的存水高度 左侧和右侧柱子的最大高度的较小值&#xff0c;减去当前列的柱子高度&#xff0c;所得到的差值。 可以验证第4列&…

spring常用注解(10)@Order

一、 1、作用 加Order()注解&#xff0c;在注解中加入数字&#xff0c;数字越小&#xff0c;优先级越高&#xff0c;最先执行。 2、使用方法 &#xff08;1&#xff09;自定义顺序 Component Order(1) public class XxxFilter extends OncePerRequestFilter{}Component Or…

什么品牌的宠物空气净化器性价比最高?352/希喂/霍尼韦尔/有哈/IAM实测对比

我开着一家猫咪咖啡馆&#xff0c;我们店貌美小猫可没少给我带来回头客~先给大家看看我的招财猫们 开了三年了&#xff0c;也是前不久店里才开始有点盈利&#xff0c;开始那段时间没少收到投诉&#xff0c;差点就干不下去了。店里养着的猫多&#xff0c;平时鱼油、冻干也没稍微…

foc入门

FOC(Field Oriented Control)磁场定向控制 foc,磁场定向控制&#xff0c;通过控制无刷电机三相电流&#xff0c;来实现对无刷电机的角度扭矩的控制。 首先先要理解无刷电机的原理&#xff0c;我们以三槽两极内转子电机进行讲解&#xff0c; 相较于有刷电机&#xff0c;无刷电…

乱弹篇(47)渔友絮语

中秋节连着国庆节长假很快就要来临&#xff0c;这对于久未远行旅游的人来说&#xff0c;真是拉满的幸福日子&#xff0c;因此本“人民体验官”特意推广人民日报官方微博文化产品《收藏&#xff01;中秋假期博物馆看展攻略》。 截图&#xff1a;来源“人民体验官”推广平台 人民…

Linux编译内核选项说明

内核功能选择 编译内核时出现的提示信息是在描述内核配置界面中的导航和操作方式。具体解释如下&#xff1a; Arrow keys navigate the menu: 使用箭头键可以在菜单中上下左右移动。 <Enter> selects submenus ---> (or empty submenus ----): 按下回车键可以选择一个…

【白话树】之 树的基本知识、存储结构和二叉树转换

快速导航 一、树的基础概念1. 树的定义&#xff1a;2. 树的特点:3. 树的常用术语&#xff1a;4. 树的简单分类&#xff1a; 二、树的存储结构1.顺序存储1) 双亲表示法2) 孩子表示法3) 双亲孩子表示法 2.链式存储1) 孩子链表表示法2) 孩子兄弟表示法 三、树、森林和二叉树的转换…

根据NVeloDocx Word模板引擎生成Word(五)

前面几篇基本上介绍完了NVeloDocx的基础用法&#xff0c;绝大部分的需求其实都是这些基础的东西&#xff0c;本篇将介绍2个不常用但是实际的业务场景&#xff1a; 1、图片列表输出&#xff1b; 比如在E6开发平台生成的客户端中&#xff0c;图片列表往往是这样显示的&#xff…

【数据结构】第八节:链式二叉树

个人主页&#xff1a; NiKo 数据结构专栏&#xff1a; 数据结构与算法 源码获取&#xff1a;Gitee——数据结构 一、二叉树的链式结构 typedef int BTDataType; typedef struct BinaryTreeNode {BTDataType data;struct BinaryTreeNode* left; // 左子树根节点struct BinaryT…

2024年沈阳都市圈电竞大赛 暨TGA腾讯电竞运动会辽宁省选拔赛盛大开赛

去年&#xff0c;由沈阳市体育局主办的“2023年沈阳都市圈首届电竞大赛暨TGA浑南之夏辽宁省英雄联盟选拔赛”成功举办。通过搭建赛事平台&#xff0c;营造了沈阳都市圈电竞氛围&#xff0c;促进了电子竞技全业态发展。 今年&#xff0c;“2024年沈阳都市圈电竞大赛暨TGA腾讯电…

Day24_0.1基础学习MATLAB学习小技巧总结(24)——图形对象属性值的设置和查询

利用空闲时间把碎片化的MATLAB知识重新系统的学习一遍&#xff0c;为了在这个过程中加深印象&#xff0c;也为了能够有所足迹&#xff0c;我会把自己的学习总结发在专栏中&#xff0c;以便学习交流。 参考书目&#xff1a;《MATLAB基础教程 (第三版) (薛山)》 之前的章节都是…

vue3项目实现全局国际化

本文主要梳理vue3项目实现全项目格式化&#xff0c;例如在我前面文章使用若依创建vue3的项目中&#xff0c;地址&#xff1a;若依搭建vue3项目在导航栏中切换&#xff0c;页面中所有的组件的默认语言随之切换&#xff0c;使用的组件库依旧是element-plus&#xff0c;搭配vue-i1…

LeetCode --- 414周赛

题目列表 3280. 将日期转换为二进制表示 3281. 范围内整数的最大得分 3282. 到达数组末尾的最大得分 3283. 吃掉所有兵需要的最多移动次数 一、将日期转换成二进制表示 题目本质就是将数字转成二进制字符串&#xff0c;可以类比将十进制数字的每一位拆开拼成字符串&#x…

【Redis】redis5种数据类型(list)

目录 基本介绍 命令 LPUSH LPUSHX RPUSH RPUSHX LRANGE LPOP RPOP LINDEX LINSERT LLEN LREM LTRIM LSET 阻塞版本的命令 BLPOP 内部编码 基本介绍 list相当于c的双端队列deque 区分获取和删除的区别 lindex能获取到元素的值lrem也能返回被删除元素的值 命…

一条SQL实现GPT大模型【完全看不懂】

用一条SQL实现GPT大模型&#xff0c;简直让人不可思议&#xff0c;但是俄罗斯一位名叫Quassnoi的SQL牛人做到了&#xff0c;Quassnoi每年只写一条SQL&#xff0c;但是每条SQL都非常复杂&#xff1a; 2021年&#xff0c;用SQL绘制新冠病毒的3D图片 2022年&#xff0c;用SQL模拟…

为何初创数字影像企业纷纷选择入驻孵化基地?

在当今数字化时代&#xff0c;数字影像行业正蓬勃发展&#xff0c;越来越多的初创数字影像企业如雨后春笋般涌现。而这些充满活力与创新的初创企业&#xff0c;为何纷纷选择入驻数字影像企业孵化基地呢&#xff1f; 首先&#xff0c;数字影像企业孵化基地为初创数字影像企业提供…

再次进阶 舞台王者 第八季完美童模全球赛形象大使【邱玳莹】赛场秀场超燃合集!

7月20-23日&#xff0c;2024第八季完美童模全球总决赛在青岛圆满落幕。在盛大的颁奖典礼上&#xff0c;一位才能出众的少女——邱玳莹&#xff0c;迎来了她舞台生涯的璀璨时刻。 形象大使——邱玳莹&#xff0c;以璀璨童星之姿&#xff0c;优雅地踏上完美童模盛宴的绚丽舞台&am…