快读快写是啥?看这篇就够了

目录

快读快写

首先,快读快写代码是什么?

其次,为什么快,与谁比?

最后,什么时候都适用吗?

小tips


快读快写

首先,快读快写代码是什么?

以下是模板,解释以注释的形式给出了

如果你对getchar不熟悉,可以先看下面的小tips。

typedef long long ll;  
inline ll read(){    //内联函数
	ll n=0;  
	int f=1;
	char c=getchar();  //获取字符赋值给c
	while(c<'0' || c>'9'){    //一直不断的判断,直到读到数字,如果读到符号,f=-1,记录一下
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0' && c<='9'){  //读数字,最后用户或者我们输入完之后会有回车,回车也读,以此出循环
		n=(n<<3)+(n<<1)+(c^48);//移位运算符,在下面细讲
		c=getchar();
	}
	return n*f;//返回
}

左移运算符

假设int n=1;

二进制表示就是00000000  00000000  00000000  00000001    =1

左移3位

就是                  00000000  00000000  00000000  00001000    =8

再左移3位

就是                  00000000  00000000  00000000  01000000     =64

而从1开始左移一位就是

00000000  00000000  00000000  00000001=1

00000000  00000000  00000000  00000010=2  一位

00000000  00000000  00000000  00000100=4  两位

看出来了吗,一个相当于乘8,一个相当于乘2,加起来就是乘10。

哎呦呵,原来你就是乘个10啊,写这么复杂干什么,哎嘿,这么做肯定有道理

充满的你应该知道了,没错,就是快。

那么这个(c^48)这样写,是不是写成(c - '0')啊

没错,就是可以这么做。

我们知道,字符 '1' 到 '9' 的ASCII码值分别是 49 到 57。

^表示按位异或操作符。

48的二进制表示是0011 0000

而57的二进制表示0011 1001

异或就是相同为0不同为1

自己推一推就知道啦——

哈哈,快之前,我们再说说快写

 模板

inline void write(ll x){
	if(x<0){
		putchar('-');
		x=-x;
	}
	if(x>9) write(x/10);
	putchar((x%10)^48);
	return;
}

先把负号打出来,通过递归致使到个位数,然后输出

这个(x%10)^48就等价于x%10+'0',一般用后者即可

那我们就很好理解了x%10得到的数一定是个位数

再异或48,相当于在48的基础上加这个个位数,因为putchar要输出字符嘛——

其次,为什么快,与谁比?

肯定与要样子的scanf和printf比或者cincout相比要快很多

我认为啊,首先读入字符打印字符嘛,肯定快,不向数字。其次,我的目的很明确,就做这些。

具体原因如下

  1. 减少函数调用:在快读和快写技巧中,通常会减少函数调用的次数。函数调用涉及到压栈、出栈等操作,会引入额外的开销。通过减少函数调用次数,可以降低开销,提高程序的执行效率。

  2. 减少格式转换:在快读和快写技巧中,尽可能减少了不必要的格式转换。例如,直接使用 %d%lld 等格式化符号读取整数,而不需要额外的类型转换。避免不必要的格式转换可以节省时间,从而提高程序的速度。

  3. 缓冲区优化:快读和快写技巧通常会对输入输出的缓冲区进行优化。例如,使用 fgets 函数可以一次性读取一行数据,避免多次读取造成的开销。

  4. 底层优化:在一些情况下,快读和快写技巧可能会涉及到底层的输入输出操作,绕过了标准库函数的一些封装,从而减少了不必要的中间环节,提高了数据的读写速度。

最后,什么时候都适用吗?

数据量大时,非常好用,虽然我还没用过,不过快了——哈哈哈

数据量小时,不建议用,没必要,当然可能会有不必要的麻烦

整数多,非常好;空格多,难搞;有浮点数,不搞。

网上还有其他类型的模板,用想用的就好,没太多区别。

只是有些更快一点,但都很快了,嘶,快~

OK,结束,祝您常AC~

小tips

如果对getchar不熟悉,可以看看这篇文章

http://t.csdn.cn/dVEml

下面是getchar的简单过程

在Linux中,getchar() 函数涉及以下主要步骤:

    标准输入流的文件描述符获取:
    在Linux中,所有的输入输出设备都被抽象为文件,包括标准输入、标准输出和标准错误输出。标准输入的文件描述符是 0。当程序调用 getchar() 函数时,它实际上是从文件描述符为 0 的文件(标准输入流)中读取一个字符。

    等待输入:
    当调用 getchar() 函数时,程序会进入一个阻塞状态,直到用户输入一个字符并按下回车键。这是因为 getchar() 函数会等待用户输入完成后才会继续执行程序。

    字符读取:
    一旦用户输入完成,操作系统会将输入的字符存储在输入缓冲区中。getchar() 函数通过系统调用读取输入缓冲区中的字符。

    缓冲区管理:
    输入缓冲区是一个临时存储区域,操作系统将用户输入的字符存储在其中,直到应用程序读取它们。getchar() 函数实际上是从输入缓冲区中读取一个字符并将其从缓冲区中移除。

    字符转换与返回:
    读取到的字符被转换成对应的整数(ASCII码值),然后作为 getchar() 函数的返回值返回给调用它的程序。如果读取失败或遇到文件结束符(EOF),则返回特殊值 EOF。

整个过程中,C语言标准库中的 getchar() 函数充当了一个高级接口的角色,隐藏了底层系统调用的复杂性,使得程序员可以方便地从标准输入流中获取字符,而无需直接与底层的文件描述符和缓冲区交互。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

每天写bug的屑闲鱼

请我杯饮料吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值