一、序言
C++的cin和cout实在是太慢了,所以一直用的都是scanf和printf进行输入和输出,但是,最近又发现scanf和printf在数据量大的时候还是太慢了,于是只能手写输入输出优化。但scanf和printf的输入输出功能非常强大,所以还是全面学习了一下,这里写点总结。
二、格式化说明符
符号 | 意义 |
%d | 十进制带符号整数 |
%u | 十进制无符号整数 |
%o | 八进制无符号整数 |
%x | 十六进制无符号整数 |
%f | 十进制小数形式浮点数,无域宽时带6位小数 |
%e | 十进制科学计数法形式浮点数 |
%g | 十进制小数形式和科学计数法形式中较短的一个 |
%c | 单个字符 |
%s | 字符数组 |
%p | 指针的地址 |
三、scanf
格式化输入函数,从标准输入设备读取输入的信息,调用格式:( ”< 格式 >”,< 地址 > );
格式:% [标志字符] [域宽] [长度] 格式化说明符( 中括号内为可选项 )
标志字符:
*( 读入后不赋给任何变量,即跳过输入值 )
域宽:
实际位数多于域宽则截取域宽长度,剩余部分仍留在标准输入中等待下次输入;实际位数少于域宽则无效果
长度:
分为 h,l ( 以下因不同编译器可能不同 )
h 表示按短型读入( 短整型,单精度型 )
l 表示按长型读入( 整形 == 长整型,双精度型 == 长双精度型 )
其它:
若不属于上面任何一种情况,则按格式进行对照忽略,即若%d与%d之间出现了“,”,输入将忽略紧夹在两个整数间
的“,”,若整数间含有两个“,”,则在格式中需打两个“,”;不同的是,若为空格,也会进行忽略,但是会忽略掉中间
的所有的空格或空行。当读入的整数、浮点数、字符串时无需在格式中加空格也可以自动忽略空格或空行。
地址:需要读入参量的地址,不是变量本身
一般变量:
变量名前加取地址符号“&”
字符数组:
数组名就表示数组的首地址,无需加取地址符号
指针变量:
指针名就是地址,无需加“*”
四、printf
格式化输出函数,将信息输出到标准输出设备,调用格式:( ”< 格式 >”,< 参量 > )
格式:% [标志字符] [域宽] [精度] [长度] 格式化说明符( 中括号内为可选项 )
标志字符:
-( 结果左对齐,不够域宽时右边填空格 )
+( 不管正负号都输出符号 )
( “空格”,正号显示空格,符号输出符号 )
#( 输出%o时加八进制前缀0,输出%x时加十六进制前缀0x )
域宽:
实际位数多于域宽按实际位数输出( 小数点等也算位数,下同 ),实际位数少于域宽则在域宽内靠右,左边留空
若前有标志字符“-”则反之
表示域宽的数字以0开头,则在实际位数少于域宽时靠右,左边补满前导零
精度:
以“.”开头,后跟十进制整数
对于浮点数,表示小数位数,实际位数更多,则四舍五入,更少则在后添零
对于字符数组,表示长度,若实际长度更多,截取前一部分,更少无效果
长度:
分为h,l( 以下因不同编译器可能不同 )
h表示按短型输出( 短整型,单精度型 )
l表示按长型输出( 整形 == 长整型,双精度型 == 长双精度型 )
其它:
若不属于上面任何一种情况,包括出现未提及的字符,或者是未按照一定顺序,比如“空格”未直接跟在了“%”后面而是
出现在了格式化说明符后,将按照原样输出
参量:需要输出参量的值,不是地址
一般变量:
直接打变量名,前面不加取地址符号
字符数组:
直接打数组名,告诉程序需要输出的开始位置
指针变量:
在指针名前加指向标志“*”
五、优化
在数据量特别大,比如需要输入或者输出1000万个整数的时候,scanf和printf就会变得非常慢,然而getchar和putchar函数很快,所以我们需要用其来优化读入与输出。
读入优化:
// 优化前读入1-10000000:3.176秒
// 优化后读入1-10000000:1.232秒
void scan( )
{
k = num = 0, bit = 1;
while( ( ch[++num] = getchar( ) ) != 32 );
num--;
while( num ) k += ( ch[num--]-48 )*bit, bit *= 10;
}
输出优化:
// 优化前输出1-10000000:4.336秒
// 优化后输出1-10000000:1.897秒
void print( int k )
{
num = 0;
while( k > 0 ) ch[++num] = k % 10, k /= 10;
while( num )
putchar( ch[num--]+48 );
putchar( 32 );
}
注意:既然是优化就要尽量优化,少带参才是时间的王道!
备注:若有错误,请留言告知,感激不尽。