c/c++ scanf printf 用法与优化

时间:2022-09-05 22:18:27

一、序言

        

        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 );
}

        注意:既然是优化就要尽量优化,少带参才是时间的王道! 

        备注:若有错误,请留言告知,感激不尽。