前言
在学习C++的过程中,在很多的题解中都发现了利用read来实现快速读入的功能,今天,我们就来学习一下快速读入这个函数,并顺带着学习一下内联函数
内联函数
在学习read函数之前,我们先来学习一下内联函数
引入
我们都知道,函数在分类上可以分为主调函数和被调函数,main函数就是主调函数,是调用其他函数的函数,在C程序中mian函数就是主调函数、
而像bubble_sort这些其他的函数就称为被调函数,他们都被主调函数调用
在程序执行的时候,都是先执行主调函数,再执行被调函数,而当程序在执行被调函数,主调函数是停止的、不执行的,(此处可以借助调试时,按ctrl + fn + F11进入被调函数内部 来进行理解),当执行完被调函数,程序再继续执行刚才主调函数中停止时后面的部分,
我们都知道,函数调用是需要做一些准备的,
首先,程序要在栈中开辟出足够大的空间,先将实参、局部变量、返回地址以及若干寄存器都存储在其中,
然后,才能执行函数体中的代码;
最后,函数体中的代码执行完毕后还要清理现场,也就是释放内存,将之前压入栈中的数据都出栈,才能接着执行函数调用位置以后的代码。
此处可以参考我的另一篇文章函数栈帧的创建和销毁,可能会有助于理解函数调用的过程
经过上面的介绍,相信大家可以理解一件事:
当函数体很庞大时,其准备所需的时间就可以忽略不计,
而当函数体只有一两条语句时,其准备所需的时间就不可忽略,一旦这个简单的函数要调用很多次,那在时间上和空间上都是一种浪费,
此时,人们就想,能不能设计一种函数,当它结束调用时不释放它在内存中开辟的空间,此时,就出现了内联函数
定义
为了消除函数调用的时空开销,也就是更快速
C++ 中提供一种提高效率的方法,即在编译时将函数调用处用函数体替换,
类似于C语言中的宏展开。
这种在函数调用处直接嵌入函数体的函数称为内联函数(Inline Function),又称内嵌函数或者内置函数。
使用
下面,通过一个简单的例子来介绍内敛函数如何使用
例子
使用内联函数创建一个函数,功能是交换两个数
#include<iostream> using namespace std; inline void swap(int* a, int* b) { int tmp = *b; *b = *a; *a = tmp; } int main() { int a = 1; int b = 2; cout << a << endl << b << endl; swap(&a, &b); cout << a << endl << b << endl; return 0; }
使用内联函数,需要在函数定义的开头使用inline关键字
注意
在函数声明处写inline是无意义的,编译器会自动忽略掉他
内联函数的使用情况
因为在函数调用完成后,不会销毁它在内存中开辟的空间
所以,实际上编译后的程序中是存在着多份相同的内容拷贝
所以,当内联函数的函数体很大时,编译后的程序也非常大
所以再次强调,一般只将那些短小的、频繁调用的函数声明为内联函数。
内联函数与宏定义
宏定义的函数不仅存在运算优先级的问题,并且也不可调试
相较于宏定义的直接替换,内联机制既具备宏代码的效率,又增加了安全性,而且可以自由操作的类的数据成员,所以应该尽量使用内联函数来取代宏代码。
read函数
学习完了内联函数,接下来我们来学习快速读入:read函数
基本思路
读取字符
既然是读取数据,并且是一个一个的读取,那么我们肯定会用到getchar来读取字符
设置条件
其次,我们对于要输入的数据肯定是有一定的要求的,不能什么数据都传输进来,
所以我们就要都传入的数据进行判断,看其是否满足我们的条件
代码实现
下面,我们提供两种实现方法
简单版本
inline long long read() { char cc = getchar();//读取第一个字符 long long f = 1;//f用于判断符号正负 long long ans = 0;//ans用于控制数字 while (cc < '0' || cc>'9') { if (cc == '-') { f = -1; } cc = getchar(); } while (cc >= '0' && cc <= '9')//遇到空格,则这个整形数据读取结束 { ans = (ans * 10) + (cc - '0'); cc = getchar(); } return f * ans; }
优化版本
当然,我们也可以通过位运算来优化上面这个解法,毕竟而我们都知道位运算比乘除法的运行速率要快
inline long long read() { char cc = getchar(); long long f = 1; long long ans = 0; while (cc < '0' || cc>'9') { if (cc == '-') { f = -1; } cc = getchar(); } while (cc >= '0' && cc <= '9') { ans = (ans << 1) + (ans << 3) + (cc - '0');//向右移动一位是乘以2 cc = getchar(); } return f * ans; }
练习题
下面,还是给出一道练习题,方便大家理解
题目:A+B problem
题目描述:输入一个正整数n,表示有n个数,接下来再输入n个数。计算它们的和。
样例输入:
20 233 222 2334 123 654 2345 235 2345 321 357 123 45 65 346 76 456 778
-123 -20 -1000
样例输出:
9915
示例代码
#include<cstdio> #include<iostream> using namespace std; inline long long read() { char cc = getchar(); long long f = 1; long long ans = 0; while (cc < '0' || cc>'9') { if (cc == '-') { f = -1; } cc = getchar(); } while (cc >= '0' && cc <= '9') { ans = (ans << 1) + (ans << 3) + (cc - '0'); cc = getchar(); } return f * ans; } int main() { long long ans = 0; int n = read(); int a = 0; for (int i = 0; i < n; i++) { a = read(); ans += a; } cout << ans << endl; return 0; }
结语
好的,关于内联函数和read函数的介绍和学习到这里就结束了,希望对你有帮助,我们下篇文章见~