一、define宏定义
写代码时,我们常会遇到一个问题:一段繁琐的代码需要多次使用,且这些代码的结构或内容完全相同。
为了更好地编写程序,我们可以使用define宏定义来简化代码。
下面来看一个示例:
#include<iostream>
using namespace std;
int main(){
unsigned long long n;
unsigned long long a,b;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a>>b;
cout<<a+b<<endl;
}
return 0;
}
这段代码中,unsigned long long出现了许多次,我们便可以用宏定义来简化一下。
简化之后:
#include<iostream>
using namespace std;
#define ull unsigned long long
int main(){
ull n;
ull a,b;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a>>b;
cout<<a+b<<endl;
}
return 0;
}
是不是简便了许多?
甚至,我们可以通过define去定义一些常用的其它代码,比如for循环:
#include<iostream>
using namespace std;
#define ull unsigned long long
#define repi{i,a,b} for(int i=(a);i<=(b);i++)
ull n;
ull a[100][100];
int main(){
cin>>n;
repi{i,1,n}{
repi{j,1,n}{
cin>>a[i][j];
}
}
repi{i,1,n}{
repi{j,1,n}{
cout<<a[i][j]<<" ";
}
cout<<'\n';
}
return 0;
}
注:带参宏定义要加括号,如#define ADD{a,b} (a)+(b)
这段代码中使用了repi代替for循环,可以看出简练很多。
总之,define理论上可以定义任何代码,熟练运用后可以使编码速度和代码可读性大大提高。但它只是一种编程技巧,并非必须的。
二、快读快写
来看一道题目:
A+B快速版
时间限制:2秒 内存限制:128M
题目描述
给定 n 对数 a,b ,求出所有的 a+b 。
输入描述
第一行输入 n
接下来 n 行每行有两个整数 a,b
输出描述
输出 n 行, n 对 a+b 的结果
输出样例
2
1 1
2 2
输出样例
2
4
数据范围
1<=n<=5×1e6,1<=a,b<=1e9
看起来很简单对吧?
再仔细看看数据范围,发现n非常大,因此,普通的输入输出会超时。
这就要讲到快读快写了。
先来普及一个基本知识:
C++常见的输入输出所需时间中,cin,cout>关闭同步cin,cout>scanf,printf>getchar,putchar.
在这道题允许的时间范围内,只能用getchar和putchar。
但这种输入输出是用于char类型的,怎么用它输入其他类型呢?
我们可以使用自定义函数,在函数中进行判断与类型转换。
具体代码:
#include<bits/stdc++.h>
using namespace std;
//快读快写
template<typename T>
inline void read(T& x){ //快读
x=0;
char ch=getchar();
long long f=1;
while(!isdigit(ch)){
if(ch=='-'){
f*=-1;
}
ch=getchar();
}
while(isdigit(ch)){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
x*=f;
}
template<typename T,typename... Args>
void read(T& first,Args&... args){
read(first);
read(args...);
}
template<typename T>
inline void write(T arg){ //快写
T x=arg;
if(x<0){
putchar('-');
x=-x;
}
if(x>9){
write(x/10);
}
putchar(x%10+'0');
}
template<typename T,typename... Ts>
void write(T arg,Ts... args){
write(arg);
if(sizeof...(args)!=0){
putchar(' '); //putchar内为输出时的分隔符
write(args...);
}
}
int main(){
return 0;
}
具体用法:read(变量名)输入a,write(变量名)输出。
同时输入输出多个时变量之间用逗号隔开
template的作用是自动判断数量类型,使这个代码可以同时用作多种类型,包括long long和int等。
有了这套完备的快读快写模板,这道题就可以很简单地解决了,我在这里就不写了,大家可以自己试试看。
注意事项:
快读快写很好用,但是不能总是用,因为它会识别空格,有可能会被卡死,平时就没必要用了
如果嫌普通cin,cout太慢,又不想用scanf,printf,可以将cin,cout关闭同步:
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
直接写到主函数内即可,但是要注意,使用这个之后只能使用cin,cout输入输出,用其他方式会报错。
今天先写到这里,讲的不多但比较实用,后续会继续讲一次语法,感兴趣的可以点赞关注我,大家一起进步。谢谢!