C语言学习【printf函数和scanf函数】
printf()函数和scanf()函数可以让用户与程序交流,是输入/输出函数
printf()函数
请求printf()函数打印数据的指令要与待打印数据的类型相匹配。例如,打印整数时使用%d,打印字符时使用%c。这些符号被称为转换说明(conversion specification),它们指定了如何把数据转换成可显示的形式
如下图所属我i欸转换说明及其打印的输出结果
 
 
/* 使用转换说明 */
#include "stdio.h"
#define PI 3.1415926
int main(void)
{
    int number = 7;
    float pies = 12.75;
    int cost = 7800;
    printf("The %d contestants ate %f berry pies.\n", number, pies);
    printf("The value of pi is %f.\n", PI);
    printf("Farewell! thou art too dear for my possessing, \n");
    printf("%c%d\n", '$', 2 * cost);
}
程序运行结果
The 7 contestants ate 12.750000 berry pies. 
The value of pi is 3.141593.
Farewell! thou art too dear for my possessing, 
$15600
printf()函数格式为
printf(格式字符串, 待打印项 1, 待打印项 2,...);
printf()输出百分号:使用两个%即可
/* printf 输出 % */
#include "stdio.h"
int main(void)
{
    int radio = 12;
    printf("%d%%", radio);
}
程序运行结果
12%
printf()的转换说明修饰符
下图所示为printf()的修饰符
 
 
printf()中的标记
 
 
使用修饰符和标记的示例程序(字段宽度打印输出整数时的效果)
/* 字段宽度 */
#include "stdio.h"
#define PAGES 959
int main(void)
{
    printf("*%d*\n", PAGES);
    printf("*%2d*\n", PAGES);
    printf("*%10d*\n", PAGES);
    printf("*%-10d*\n", PAGES);
}
程序运行结果
*959*
*959*
*       959*
*959       *
第一个转换说明%d不带任何修饰符,其对应输出结果与带整数字段宽度的转换说明的输出结果相同;
 第二个转换说明是%2d,其对应的输出结果应该该是2字段度。因为待打印的整数有3位数字,所以字段宽度自动扩大以符合整数的长度;
 第3个转换说明是%10d,其对应的输出结果有10个空格宽度,实际上在两个星号之间有7个空格和3位数字,并且数字位于字段的右侧;
 最后一个转换说明是%-10d,其对应的输出结果同样是10个空格宽度,-标记说明打印的数字位于字段的左侧.
浮点型格式效果
/* 一些浮点型修饰符的组合 */
/* 一些浮点型修饰符的组合 */
#include "stdio.h"
int main(void)
{
    const double RENT = 3852.99;     /* const 常量 */
    printf("*%f*\n", RENT);                  /* 字段宽度和小数点文书均为系统默认 小数点后打印6位数字 */
    printf("*%e*\n", RENT);                  /* %e 编译器在小数点左侧打印一个数字 小数点右侧打印6个数字 */
    printf("*%4.2f*\n", RENT);               /* */
    printf("*%3.1f*\n", RENT);
    printf("*%10.3f*\n", RENT);
    printf("*%10.3E*\n", RENT);
    printf("*%+4.2f*\n", RENT);              /* +代数标记 */
    printf("*%010.2f*\n", RENT);             /* 补齐方式 */
}
程序运行结果
*3852.990000*  
*3.852990e+003*
*3852.99*
*3853.0*
*  3852.990*
*3.853E+003*
*+3852.99*
*0003852.99*
其他组合
/* 演示一些格式标记 */
#include "stdio.h"
int main(void)
{
    printf("%x %X %#x\n", 31, 31, 31);
    printf("**%d**% d**% d**\n", 42, 42, -42);
    printf("**%5d**%5.3d**%05d**%05.3d**\n", 6, 6, 6, 6);
}
程序运行结果
1f 1F 0x1f
**42** 42**-42**
**    6**  006**00006**  006**
第1行输出中,1f是十六进制数,等于十进制数31,第1行 printf()语句中,根据%x打印出1f,%F打印出1F,%#x打印出0x1f;
 第 2 行输出演示了如何在转换说明中用空格在输出的正值前面生成前导空格,负值前面不产生前导空格。这样的输出结果比较美观,因为打印出来的正值和负值在相同字段宽度下的有效数字位数相同;
 第 3 行输出演示了如何在整型格式中使用精度(%5.3d)生成足够的前导 0 以满足最小位数的要求(本例是 3)。然而,使用 0 标记会使得编译器用前导 0 填充满整个字段宽度。最后,如果 0 标记和精度一起出现,0 标记会被忽略。
字符串格式的示例
/* 字符串格式 */
#include "stdio.h"
#define BLURB "Authentic imitation!"
int main(void)
{
    printf("[%2s]\n", BLURB);
    printf("[%24s]\n", BLURB);
    printf("[%24.5s]\n", BLURB);
    printf("[%-24.5s]\n", BLURB);
}
程序运行结果
[Authentic imitation!]    
[    Authentic imitation!]
[                   Authe]
[Authe                   ]
-标记使得文本左对齐输出.
转换(conversion)说明的意义
76在计算机内部的存储格式为二进制数0100 1100, %d转换说明将其转换成字符7和6,并显示为76;%x转换说明把相同的值0100 1100转化成十六进制计数法4c,%c转换说明把0100 1100转换成字符L
转换说明应该与待答应值得类型相匹配
以下是一些不匹配的整型转换示例
/* 一些不匹配的整型转换 */
#include "stdio.h"
#define PAGES 336
#define WORDS 65618
int main(void)
{
    short num = PAGES;
    short mnum = -PAGES;
    printf("num as short and unsigned short: %hd %hu\n", num, num);
    printf("-num as short and unsigned short: %hd %hu\n", mnum, mnum);
    printf("num as int and char: %d %c\n", num, num);
    printf("WORDS as int, short, and char: %d %hd %c\n", WORDS, WORDS, WORDS);
}
程序运行结果
num as short and unsigned short: 336 336
-num as short and unsigned short: -336 65200
num as int and char: 336 P
WORDS as int, short, and char: 65618 82 R
%u表示无符号;
 short int的大小是2字节;系统采用二进制补码来表示有符号整数;数字0~32767代表它们本身,而32768~65535则表示负数,其中65535表示-1,依此类推.
当 printf()使用%c 打印 336 时,它只会查看储存 336 的 2 字节中的后 1 字节
 用%hd 转换说明打印时,printf()只使用最后 2 个字节
混淆整型和浮点型
/* 不匹配的浮点型转换 */
#include "stdio.h"
int main(void)
{
    float n1 = 3.0;
    double n2 = 3.0;
    long n3 = 2000000000;
    long n4 = 1234567890;
    printf("%.1e %.1e %.1e %.1e\n", n1, n2, n3, n4);
    printf("%ld %ld\n", n3, n4);
    printf("%ld %ld %ld %ld\n", n1, n2, n3, n4);
}
程序运行结果
3.0e+000 3.0e+000 9.9e-315 6.1e-315
2000000000 1234567890
0 0 2000000000 1234567890
第1 行输出显示,%e转换说明没有把整数转换成浮点数;
 float 类型的值作为 printf()参数时会被转换成 double 类型。
 在本系统中,float 是 4 字节,但是为了 printf()能正确地显示该值,n1 被扩成 8 字节
参数传递
栈(stack)
printf("%ld %ld %ld %ld\n", n1, n2, n3, n4);
n1 被储存在栈中,占 8 字节(float 类型被转换成 double 类型)。同样,n2 也在栈中占 8 字节,而 n3 和 n4 在栈中分别占 4 字节;
 %ld 转换说明表明 printf()应该读取 4 字节
printf()函数的返回值
printf()函数也有一个返回值,它返回打印字符的个数。如果有输出错误,printf()则返回一个负值
/* printf()的返回值 */
#include "stdio.h"
int main(void)
{
    int bph2o = 212;
    int rv;
    rv  =printf("%d F is water's boiling point.\n", bph2o);
    printf("The printf() function printed %d characrters.\n", rv);
    return 0;
}
程序运行结果
212 F is water's boiling point.
The printf() function printed 32 characrters.
在字符串中,可以使用\n 来表示换行字符,但是不能通
 过按下 Enter(或 Return)键产生实际的换行符。
打印较长字符串的方法
/* 打印较长字符串 */
#include "stdio.h"
int main(void)
{
    printf("Here's one way to print a ");
    printf("long string.\n");
    printf("Here's another way to print a \
    long string.\n");
    printf("Here's the newest way to print a "
        "long string.\n");        /* ANSI C */
    return 0;
}
程序运行结果
Here's one way to print a long string.        
Here's another way to print a     long string.
Here's the newest way to print a long string. 
示例二
/* 打印较长字符串 */
#include "stdio.h"
int main(void)
{
    printf("Hello, young lovers, wherever you are.\n");
    printf("Hello, young"    " lovers" ", wherever you are.\n");
    printf("Hello, young lovers" 
        ", wherever you are.");
}
程序运行结果
Hello, young lovers, wherever you are.
Hello, young lovers, wherever you are.
Hello, young lovers, wherever you are.


















