- #include<cstdio>
- #include<iostream>
- #include<cctype>
- using namespace std;
- int read()
- {
- register int s = 0, f = 1;
- register char ch = getchar();
- while(!isdigit(ch)) {
- if(ch == '-') f = -1;
- ch = getchar();
- }
- while(isdigit(ch)) {
- s = s * 10 + ch - '0';
- ch = getchar();
- }
- return s * f;
- }
- void write(int x)
- {
- if(x < 0) {
- putchar('-');
- x = -x;
- }
- if(x > 9)
- write(x/10);
- putchar(x % 10 - '0');
- return;
- }
- int main()
- {
- int a;
- a = read();
- write(a);
- return 0;
- }
一些问题:
1. 快读快写比标准输入输出流以及C的格式化输入输出要快,主要是由于直接利用了单个字符操作,并且适用范围仅限所定义的返回类型与输出类型,牺牲了标准输入输出的普适性而换取了效率,在算法竞赛中具有广泛的应用空间。
2. 快读、快写函数的实现分别用到了循环和递归,从理论上讲无法完成内联,inline建议不会被编译器采纳;通过在vijos上对某一需要大量输入的题目使用快读进行测试,可以发现read()前加入或不加入inline的效率几乎相同。由此可以判断inline大概率被忽略,或是函数调用和返回的时间微不足道,inline的确没有必要。(不理解的同学可从材料和各大博客了解内联函数的相关知识)
3. 该方法利用了cctype库中的字符判断函数isdigit(),其效率与手写ASCII码判断几乎不相上下,甚至更快,可以说同时实现了简洁与快捷,建议使用。
4. 理论上效率较高的写法是将read中所定义的变量加入寄存器建议(如上代码),但是实测的效率相差并不大。依然有指令被编译器忽略的可能性,因此加不加入就看自己的想法了。
5. read(void)函数也可以写成read(&int)的形式(对地址进行直接赋值操作),效率方面没有太大差别,可以按照个人爱好采用不同风格。
6. 一种更快的fread()式快读可以进一步显著提升读入效率,但写法较为复杂,且需要额外开辟内存,出错率高,在OI中用途有限,有兴趣的同学可以自行学习了解。
太原五中
袁盛琪
2019年3月26日