fread 秀我一脸

前言

卡常必备小技巧,妹妹除外。

读入

在萌芽时期,我们使用的朴实无华的读入是 scanf

后来有人用了更简便的 cin 但是他不关同步。

虽然关了同步的 cin 还是挺快的,但是不能和 scanf 之类的混用,容易引起问题。

所以我们就直接手写读入函数!

前置知识:getchar巨快!

于是我们可以写出这样一份快读:

LL Read()
{
	LL x = 0,f = 1; char c = getchar();
	while(c > '9' || c < '0'){if(c == '-') f = -1;c = getchar();}
	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
	return x * f;
}

其中的 x*10 有人喜欢写成 (x<<3)+(x<<1) ,但本人亲测其实没多大区别,甚至 long long 类型和 int 类型的速度也没多大区别,所以这就是我最常用的读入。

但是有些时候,这还不够快,我们还需要优化!

fread!

char buf[1<<21];
char getChar(){
	static char *S = buf, *T = S;
	if(S == T) S = buf, T = S + fread(S,1,1<<21,stdin);
	return *(S ++);
}

大概思路是它一次性把读入文件全部都读进来了,然后一个一个送出去,用上这个函数,再把上文的 Read 函数中的 getchar() 换成 getChar() 就好了。

运行速度可以甩 getchar() 版本十条街,缺点是只能用文件输入输出

输出

我喜欢这么写:

#define TT template<typename T>
TT void Put1(T x)
{
	if(x > 9) Put1(x/10);
	putchar(x%10^48);
}
TT void Put(T x,char c = -1)
{
	if(x < 0) putchar('-'),x = -x;
	Put1(x); if(c >= 0) putchar(c);
}

这个版本的快输可以自动识别输出类型,还可以在后面加个字符,比如这样:

Put(x);
Put(x,' ');
Put(x,'
');

但是与fread相应的,我们还有fwrite!

不会,等fread都不够用了再来填坑。

原文地址:https://www.cnblogs.com/PPLPPL/p/15376095.html