[C++]内联函数和nullptr

news2024/11/14 14:19:19

 
> 🍃 本系列为初阶C++的内容,如果感兴趣,欢迎订阅🚩
> 🎊个人主页:[小编的个人主页])小编的个人主页
>  🎀   🎉欢迎大家点赞👍收藏⭐文章
> ✌️ 🤞 🤟 🤘 🤙 👈 👉 👆 🖕 👇 ☝️ 👍


目录

🐼inline

 🐼nullptr


🐼inline

  • 🌟在C语言阶段,我们学习了宏,并学习了宏函数的用法。比如写一个加法的宏函数:#define Add(x,y) ((x)+(y))由于C语言宏函数的容易出错,不一小心就会使逻辑错误,比如:为什么不能加分号?为什么要加外层括号?为什么要加内层括号?而且宏函数还不能调试(都是在编译期间已经完成替换)。如果在这里发生逻辑错误,我们很难发现。所以C++设计了inline目的就是替代C的宏函数。
  • 所以在C++中,引入了内联函数(inline)用inline修饰的函数叫做内联函数,在编译区间,编译器会将内联函数展开,这样就不需要建立函数栈帧,提高了效率
  • 需要注意vs编译器debug版本下面默认是不展开inline的,目的是方便调试,debug版本想展开需要设置⼀下以下两个地方。

 第一步:

   

第二步:

  

我们可以从汇编层看内联函数是否展开 

对于这段内联函数:

#define  _CRT_SECURE_NO_WARNINGS
#include <malloc.h>
#include<iostream>
using namespace std;
inline int Add(int x, int y)
{
	int ret = x + y;
	ret += 1;
	
	return ret;
}
#include"F.h"
int main()
{
	// 可以通过汇编观察程序是否展开 
	// 有call Add语句就是没有展开,没有就是展开了 
	int ret = Add(1, 2);


	cout << Add(1, 2) * 5 << endl;
	return 0;
}

没设置之前:

  

我们发现,内联函数发生了调用,没有展开,说明vs默认是不展开的。

通过刚刚两步设置修改后:

  

✨经过修改,我们发现,在vs中,编译器默认不展开inline函数,而我们修改后,inline函数在编译期间直接展开。 

  •  🌟inline对于编译器而言只是⼀个建议,也就是说,你加了inline编译器也可以选择在调用的地方不展开,不同编译器关于inline什么情况展开各不相同,因为C++标准没有规定这个。inline适用于频繁调用的短小函数,对于递归函数,代码相对多⼀些的函数,加上inline也会被编译器忽略。具体最后inline函数是否展开取决于编译器
  • inline不建议声明和定义分离到两个文件,分离会导致链接错误。因为inline被展开,就没有函数地址,链接时会出现报错。 对于编译器而言,编译器回去找函数的地址,但是内联函数如果展开,在链接期间:在符号表中是默认不存在的,所以编译器找不到内联函数的首地址,发生了链接错误。

如: 

//test.cpp

#include"F.h"

int main()
{
	// 可以通过汇编观察程序是否展开 
	// 有call Add语句就是没有展开,没有就是展开了 
	int ret = Add(1, 2);


	cout << Add(1, 2) * 5 << endl;
	f(1);//call(0x)
	//f();
	return 0;
}

#pragma once
// F.h
#include <iostream>
using namespace std;
inline void f(int i);

//F.cpp
#define  _CRT_SECURE_NO_WARNINGS
// F.cpp
#include "F.h"
inline void f(int i)
{
	cout << i << endl;
}

会发生链接错误,编译器报错: "void __cdecl f(int)" (?f@@YAXH@Z),函数 main 中引用了该符号.这正是因为内联函数的声明和定义分开,导致的。

 🐼nullptr

🌟在C语言中,NULL本质上是宏。

但是C++中NULL可能被定义为字面常量0,或者C中被定义为无类型指针(void*)的常量。不论采取何种定义,在使用空值的指针时,都不可避免的会遇到一些麻烦,本想通过f(NULL)调用指针版本的 f(int*)函数,但是由于NULL被定义成0,调用了f(intx),因此与程序的初衷相悖。f((void*)NULL); 调用会报错。

如:


#include<iostream>
using namespace std;
void f(int x)
{
	cout << "f(int x)" << endl;
}
void f(int* ptr)
{
	cout << "f(int* ptr)" << endl;
}
int main()
{
	f(0);
	// 本想通过f(NULL)调⽤指针版本的f(int*)函数,但是由于NULL被定义成0,调⽤了f(int x),因此与程序的初衷相悖。
	f(NULL);
	f((int*)NULL);
	// 编译报错:error C2665: “f”: 2 个重载中没有⼀个可以转换所有参数类型 
	// f((void*)NULL);

	f(nullptr);
	return 0;
}

运行结果:

f(int x)
f(int x)
f(int* ptr)
f(int* ptr)

C++11中引入nullptr,nullptr是⼀个特殊的关键字,nullptr是⼀种特殊类型的字面量,它可以转换成任意其他类型的指针类型。使用nullptr定义空指针可以避免类型转换的问题,因为nullptr只能被隐式地转换为指针类型,而不能被转换为整数类型

 感谢你看到这里,如果觉得本篇文章对你有帮助,点个赞👍 吧,你的点赞就是我更新的最大动力⛅️🌈 ☀️

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

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

相关文章

微软OmniParser:一切皆文档,OCR驱动智能操作

前沿科技速递&#x1f680; 微软推出的OmniParser是一种创新的框架&#xff0c;旨在将手机和电脑屏幕视为文档&#xff0c;通过OCR技术与多模态大模型实现对用户界面的深度理解和操作。OmniParser能够高效识别和提取界面中的文本信息、位置和语义&#xff0c;助力自动化操作。 …

使用 Web Search 插件扩展 GitHub Copilot 问答

GitHub Copilot 是一个由 GitHub 和 OpenAI 合作开发的人工智能代码提示工具。它可以根据上下文提示代码&#xff0c;还可以回答各种技术相关的问题。但是 Copilot 本身不能回答非技术类型的问题。为了扩展 Copilot 的功能&#xff0c;微软发布了一个名为 Web Search 的插件&am…

Rust语言在系统编程中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 Rust语言在系统编程中的应用 Rust语言在系统编程中的应用 Rust语言在系统编程中的应用 引言 Rust 概述 定义与原理 发展历程 Ru…

vue+vite前端项目ci过程中遇到的问题

将项目进行ci流水线构建时&#xff0c;遇到了npm run build 构建完成后命令行不会终止的问题&#xff0c;导致了无法进行下一个步骤。如下图&#xff1a; 排查了好久找到事vite.config.js的配置出了问题&#xff0c;如图所示&#xff0c;将build下的watch改为false即可解决问…

Python 获取PDF的各种页面信息(页数、页面尺寸、旋转角度、页面方向等)

目录 安装所需库 Python获取PDF页数 Python获取PDF页面尺寸 Python获取PDF页面旋转角度 Python获取PDF页面方向 Python获取PDF页面标签 Python获取PDF页面边框信息 了解PDF页面信息对于有效处理、编辑和管理PDF文件至关重要。PDF文件通常包含多个页面&#xff0c;每个页…

企业级RAG(检索增强生成)系统构建研究

— 摘要 检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;RAG&#xff09;技术已经成为企业在知识管理、信息检索和智能问答等应用中的重要手段。本文将从RAG系统的现状、方法论、实践案例、成本分析、实施挑战及应对策略等方面&#xff0c;探讨企业如何…

前端学习八股资料CSS(二)

更多详情&#xff1a;爱米的前端小笔记&#xff0c;更多前端内容&#xff0c;等你来看&#xff01;这些都是利用下班时间整理的&#xff0c;整理不易&#xff0c;大家多多&#x1f44d;&#x1f49b;➕&#x1f914;哦&#xff01;你们的支持才是我不断更新的动力&#xff01;找…

SAP 创建物料主数据报错:估价范围3010还没有生产式的物料帐簿

通过接口创建物料主数据&#xff08;模拟MM01&#xff09;&#xff0c;报错如图&#xff1a; 处理方案1&#xff1a;&#xff08;我的不行&#xff0c;提示已经是生产的&#xff09; 将评估范围的物料分类账设置为生产 事务码: CKMSTART - 物料分类帐的生产开始 处理方案2&a…

扫雷游戏代码分享(c基础)

hi , I am 36. 代码来之不易&#x1f44d;&#x1f44d;&#x1f44d; 创建两个.c 一个.h 1&#xff1a;test.c #include"game.h"void game() {//创建数组char mine[ROWS][COLS] { 0 };char show[ROWS][COLS] { 0 };char temp[ROWS][COLS] { 0 };//初始化数…

leetcode 148. 排序链表 中等

给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [4,2,1,3] 输出&#xff1a;[1,2,3,4] 示例 2&#xff1a; 输入&#xff1a;head [-1,5,3,4,0] 输出&#xff1a;[-1,0,3,4,5]示例 3&#xff1a; …

Elasticsearch中什么是倒排索引?

倒排索引&#xff08;Inverted Index&#xff09;是一种索引数据结构&#xff0c;它在信息检索系统中被广泛使用&#xff0c;特别是在全文搜索引擎中。倒排索引允许系统快速检索包含给定单词的文档列表。它是文档内容&#xff08;如文本&#xff09;与其存储位置之间的映射&…

excel-VLOOKUP函数使用/XVLOOKUP使用

多个窗口同时编辑表格&#xff0c;方便对照操作 使用开始-视图-新建窗口 将战区信息表的三列数据匹配到成交数据表上 可以使用VLOOKUP函数 有4个参数&#xff08;必须要查找的值&#xff0c; 要查找的区域&#xff0c;要返回区域的第几列数据&#xff0c;一个可选参数查找匹…

netcore 静态文件目录浏览

环境&#xff1a;Net6 string dirPath "C:\\Users\\15298\\Pictures"; var fileProvider new PhysicalFileProvider(dirPath); app.UseStaticFiles(new StaticFileOptions {FileProvider fileProvider,RequestPath new PathString(("/files")) }); // …

1Panel修改PostgreSQL时区

需求 1Panel安装的PostgreSQL默认是UTC时区&#xff0c;需要将它修改为上海时间 步骤 进入PostgreSQL的安装目录 /opt/1panel/apps/postgresql/postgresql/data打开postgresql.conf文件 修改&#xff1a; log_timezone Asia/Shanghai timezone Asia/Shanghai保存后重启…

函数式接口和stream

函数式接口&#xff08;Functional Interface&#xff09;是Java 8引入的一个新特性&#xff0c;它只有一个抽象方法的接口。这意味着你可以将一个函数式接口作为参数传递给方法&#xff0c;或者将其实现为一个lambda表达式。函数式接口的主要目的是允许你以声明性方式处理操作…

Oracle 高水位线和低-高水位线(High Water Mark Low High Water Mark)

在Oracle的逻辑存储结构中&#xff08;表空间-段-区-块&#xff09;&#xff0c;数据是存在数据段中的&#xff0c;通常一个表就是一个数据段&#xff0c;而段最终又由许多数据块组成。当数据存入数据块时&#xff0c;需要对块进行格式化&#xff0c;高水位线&#xff08;High …

科技资讯|Matter 1.4 标准正式发布,低功耗蓝牙助力其发展

连接标准联盟&#xff08;CSA&#xff09;宣布推出最新的 Matter 1.4 版本&#xff0c;引入了一系列新的设备类型和功能增强&#xff0c;有望提高包括 HomeKit 在内的智能家居生态系统之间的互操作性。 设备供应商和平台能够依靠增强的多管理员功能改善多生态系统下的用户体验&…

python练习-Django web入门

python -m pip install --user requests使用API调用请求数据 处理API响应 import requestsclass Requests:def request(self):url "https://www.toutiao.com/stream/widget/local_weather/data/?city北京"headers {"Accept": "application/json;…

元器件封装

元器件封装类型 为什么越来越多用贴片元件&#xff0c;而不是插件元件 为什么越来越多用贴片元件&#xff0c;而不是插件元件 1.体积小、质量小、容易保存和运输&#xff1b; 2.容易焊接和拆卸。抗震效果好。 贴片元件不用过孔&#xff0c;用锡少。直插元件最麻烦的就是拆卸&a…

[SaaS] 数禾科技 AIGC生成营销素材

https://zhuanlan.zhihu.com/p/923637935https://zhuanlan.zhihu.com/p/923637935