inline与nullptr

笔记来喽~~~这是对上篇C++入门(本篇点这里)的补充

(这我就不放图了:大学牲~~~)

1.inline

⽤inline修饰的函数叫做内联函数,编译时C++编译器会在调⽤的地⽅展开内联函数,这样调⽤内联 函数就需要建⽴栈帧了,就可以提⾼效率。
inline对于编译器⽽⾔只是⼀个建议,也就是说,你加了inline编译器也可以选择在调⽤的地⽅不展 开,不同编译器关于inline什么情况展开各不相同,因为C++标准没有规定这个。inline适⽤于频繁 调⽤的短⼩函数,对于递归函数,代码相对多⼀些的函数,加上inline也会被编译器忽略。
C语⾔实现宏函数也会在预处理时替换展开,但是宏函数实现很复杂很容易出错的,且不⽅便调
试,C++设计了inline⽬的就是替代C的宏函数。
vs编译器 debug版本下⾯默认是不展开inline的,这样⽅便调试,debug版本想展开需要设置⼀下 以下两个地⽅。
inline不建议声明和定义分离到两个⽂件,分离会导致链接错误。因为inline被展开,就没有函数地 址,链接时会出现报错。
适合内联:频繁调用的 函数
总之:因为宏的坑多,inline就是为了替代宏
宏的问题:(坑多~)(主要是宏的本质是替换)
#include<iostream>
using namespace std;
// 实现⼀个ADD宏函数的常⻅问题
//#define ADD(int a, int b) return a + b;
//#define ADD(a, b) a + b;
//#define ADD(a, b) (a + b)
// 正确的宏实现
#define ADD(a, b) ((a) + (b))
// 为什么不能加分号?
// 为什么要加外⾯的括号?
// 为什么要加⾥⾯的括号?
int main()
{
	int ret = ADD(1, 2);
	cout << ADD(1, 2) << endl;
	//被宏替换:
	//int ret = ((1)+(2));
	//如果加分号:int ret = ((1)+(2));;
	//外加括号,内加括号都是因为优先级
	//比如:
	int x = 1;
	int y = 2;
	ADD(x & y, x | y);//->(x&y+x|y);
	//y+x的优先级更高,达不到预想的结果
	return 0;
}

内联函数就不用担忧这样的question~(都变成函数了,函数应该不会写错吧)

inline int ADD(int a,int b)
{
	return a + b;
}
int main()
{
	int ret = ADD(1, 2);
	cout << ADD(3, 4) << endl;
	cout << ret << endl;
	return 0;
}

分离到两个文件,链接错误:(示例)

// 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()
{
	// 链接错误:⽆法解析的外部符号 "void __cdecl f(int)" (?f@@YAXH@Z)
	f(10);
	return 0;
}

2.nullptr

NULL实际是⼀个宏,在传统的C头⽂件(stddef.h)中,可以看到如下代码:
(简单看看就行)
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
C++中NULL可能被定义为字⾯常量0,或者C中被定义为⽆类型指针(void*)的常量。不论采取何种 定义,在使⽤空值的指针时,都不可避免的会遇到⼀些⿇烦,本想通过f(NULL)调⽤指针版本的
f(int*)函数,但是由于NULL被定义成0,调⽤了f(int x),因此与程序的初衷相悖。f((void*)NULL);
调⽤会报错。
C++11中引⼊nullptr,nullptr是⼀个特殊的关键字,nullptr是⼀种特殊类型的字⾯量,它可以转换 成任意其他类型的指针类型。使⽤nullptr定义空指针可以避免类型转换的问题,因为nullptr只能被 隐式地转换为指针类型,⽽不能被转换为整数类型。
#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(int x)
	// 本想通过f(NULL)调⽤指针版本的f(int*)函数,但是由于NULL被定义成0,调⽤了f(intx),因此与程序的初衷相悖。
	f(NULL);//f(int x)
	f((int*)NULL);//f(int x)
	// 编译报错:error C2665: “f”: 2 个重载中没有⼀个可以转换所有参数类型
	// f((void*)NULL);
	
	//C++
	void* p1 = NULL;
	int* p2 = (int*)p2;//C++在这里需要隐式类型转换,(比较严格)

	//C
	void* p3 = NULL;
	int* p4 = p3;//C可以过(没那么严格)

	//引入关键字(nullptr)来解决
	f(nullptr);//f(int* ptr)
	int* p = nullptr;//指针专用,在C++,nullptr就是空指针
	int pp = nullptr;//报错
	return 0;
}

相关推荐

  1. inlinenullptr

    2024-07-12 19:10:03       22 阅读
  2. [C++ 基础入门 - inlinenullptr]

    2024-07-12 19:10:03       17 阅读
  3. Kotlin withContext详解suspend和inline

    2024-07-12 19:10:03       42 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-12 19:10:03       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-12 19:10:03       71 阅读
  3. 在Django里面运行非项目文件

    2024-07-12 19:10:03       58 阅读
  4. Python语言-面向对象

    2024-07-12 19:10:03       69 阅读

热门阅读

  1. ActiViz中的跟随者vtkFollower

    2024-07-12 19:10:03       22 阅读
  2. 常见的load_file()读取的敏感信息

    2024-07-12 19:10:03       21 阅读
  3. tomcat的介绍与优化

    2024-07-12 19:10:03       21 阅读
  4. Elasticsearch实战指南:从下载到高级应用全解析

    2024-07-12 19:10:03       21 阅读
  5. python .join用法

    2024-07-12 19:10:03       18 阅读
  6. 力扣995.K连续位的最小翻转次数

    2024-07-12 19:10:03       22 阅读
  7. ubuntu cp 命令 拷贝文件

    2024-07-12 19:10:03       20 阅读
  8. 探索 Scikit-Learn:机器学习的强大工具库

    2024-07-12 19:10:03       19 阅读
  9. C# —— try catch

    2024-07-12 19:10:03       15 阅读
  10. 机器学习 - one-hot编码技术

    2024-07-12 19:10:03       21 阅读
  11. 【人生苦短,我学 Python】(15)迭代器、生成器

    2024-07-12 19:10:03       23 阅读
  12. hot100 | 十、回溯

    2024-07-12 19:10:03       21 阅读
  13. Eureka: Netflix开源的服务发现框架

    2024-07-12 19:10:03       19 阅读
  14. Gradle 介绍

    2024-07-12 19:10:03       15 阅读
  15. tomcat

    2024-07-12 19:10:03       14 阅读