当前位置:网站首页>03-1、内联函数、auto关键字、typeid、nullptr
03-1、内联函数、auto关键字、typeid、nullptr
2022-07-17 14:45:00 【列宁格勒的街头】
前言:本文章主要用于个人复习,追求简洁,感谢大家的参考、交流和搬运,后续可能会继续修改和完善。
因为是个人复习,会有部分压缩和省略。
一、内联函数
C语言为了避免小函数建立栈帧,提供了宏函数,会在预处理阶段展开
既然C语言已经解决了,为什么C++还要提供inline函数呢?(宏函数的缺点)
1.宏函数不支持调试
2.宏函数语法复杂,容易出错
3.宏函数没有类型安全的检查
C++推荐频繁调用的小函数,定义成inline,会在调用的地方展开,没有栈帧开销
能不能所有函数都搞成内联?
例如这里有一个sort函数有100行指令 ,有10个地方调用,总计是多少指令?
有110条。
如果搞成内联函数,有多少条?
100*10,有1000条指令。
指令变多意味着什么呢?
指令变多意味着编译出来的可执行程序变大,会使安装软件的人体验变差,执行程序内存消耗变多
结论:频繁调用的小函数,建议定义成inline
内联函数的特性:
1. inline是一种以空间换时间的做法,省去调用函数额开销。所以代码很长或者有循环/递归的函数不适宜使用作为内联函数。
2. inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体太大或有递归等等,编译器优化时会忽略掉内联。
3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。
会发生链接错误的根本原因:内联函数没有地址!!!
二、auto
类型声明称auto,可以根据a的类型自动推导b的类型
(auto*)malloc()这样是不可以的
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()
{
int a = 10;
//int b = a;
auto b = a;//类型声明成auto,可以根据a的类型自动推导b的类型
map<string, string> m;
//map<string, string>::iterator it = m.begin();
//这里可以根据m.begin()自动推导it的类型是map<string, string>::iterator
auto it = m.begin();
return 0;
}
auto有几个地方不能使用:
1.auto不能作为函数的参数
auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
void test(auto a) {}2.auto不能直接用来声明数组
void test() { int a[] = {1,2,3}; auto b[] = {4,5,6}; //那么可以这样吗?在创建数组时,auto b[0] = a[1]; auto a = 4.1,b = 4;//也不可以 }3.auto在实际中最常见的优势用法就是跟以后会讲道德C++11的新式for循环,还有lambda表达式等进行配合使用
auto真正的意义在于支持C++11的新语法范围for,新语法遍历,更简单,是数组都可以,容器也可以

e的名字可以改变


注意,这种情况下不能使用范围for
void test(int arr[])
{
for(auto& e : arr)
{
cout << e << endl;
}
}范围for的使用条件
1. for循环迭代的范围必须是确定的
对于数组而言,就是数组中第一个元素和最后一个元素的范围;对于类而言,应该提供begin和end的方法,begin和end就是for循环迭代的范围。注意:以下代码就有问题,因为for的范围不确定,int array[]表示的不是一个数组,它是一个指针,所以不行
void TestFor(int array[])
{
for(auto& e : array)
cout<< e <<endl;
}2. 迭代
的对象要实现++和==的操作。(关于迭代器这个问题,以后会讲)
三、nullptr和NULL
在C++中我们使用nullptr,因为C++中NULL其实是被define成0的,是这样的一个宏,不是指针
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。
边栏推荐
- XSS. haozi. Me brush questions
- Powercli script performance optimization
- 《MySQL DBA封神打怪之路》专栏学习大纲
- Configure spectrum navigation for Huawei wireless devices
- How can enterprise telecommuting be more efficient?
- 性能优化之@Contended减少伪共享
- mysql show processlist 详解
- LeetCode 558. 四叉树交集
- 搭建OpenStack-M版的Cinder所碰到过的状况
- IP SAN has an independent file system. After the application server accesses the IP SAN through the network sharing protocol, it can read and write the files in the file system
猜你喜欢

要想组建敏捷团队,这些方法不可少

Déléguer un chargeur tel qu'un parent

Un modèle de détection par défaut basé sur le réseau neuronal évolutif rapide dans le contrôle de la qualité des produits - lire les notes

Unity高版本退回低版本报错问题

委派双亲之类加载器

Unity high version returned low version error

Synchronized lock upgrade

synchronized锁升级

ThreadLocal变量使用及原理

Tier defect detection using full revolutionary network
随机推荐
NVIDIA uses AI to design GPU: the latest H100 has been used, which reduces the chip area by 25% compared with traditional EDA
Codeforces - 587e (linear basis + segment tree + difference)
Leetcode 1304. 和为零的 N 个不同整数
要想组建敏捷团队,这些方法不可少
SPI service discovery mechanism
Cmake common commands (V)
A fastandrobust convolutionalneuralnetwork-based defect detection model inproductqualitycontrol-阅读笔记
Unity Dropdown(可编辑,可输入)下拉选择框,带文本联想
A current List of AWESOME Qt and qml
JVM hook hooks function
jconsole线程面板中的阻塞总数和等待总数(转)
梦想CMS 前台搜索SQL注入
Qt--优秀开源项目
委派雙親之類加載器
pjudge#21652-[PR #4]到底有没有九【数位dp】
Huawei machine test: Message decompression
玩转CANN目标检测与识别一站式方案
Introduction to the universal theme system of SAP appgyver
The concept of data guard broker and the configuration process of data guard broker
【多线程】JUC详解 (Callable接口、RenntrantLock、Semaphore、CountDownLatch) 、线程安全集合类面试题