输出和输入
第 2 课里,%f 总是显示 6 位小数,价格 4.5 显示成 4.500000,没人这样写价格。这一课先学怎么让输出整齐好看,再学怎么让程序读入用户输入的数。
1#include <stdio.h>2 3int main(void) {4 double price = 3.5;5 printf("%f\n", price);6 printf("%.2f\n", price);7 return 0;8}
3.500000 3.50
小数位
在 % 和 f 中间写 .2,就只显示两位小数;.1 是一位,.0 是不要小数。多出来的位数会四舍五入:
1#include <stdio.h>2 3int main(void) {4 double temp = 36.678;5 printf("%.2f\n", temp);6 printf("%.1f\n", temp);7 printf("%.0f\n", temp);8 printf("%f\n", temp);9 return 0;10}
36.68 36.7 37 36.678000
这只改变显示出来的样子。变量 temp 里的值还是 36.678,最后一行就能看出来。
宽度和对齐
在 % 后面写一个数,是宽度:这个值至少占这么多个字符,不够的话在前面补空格,数就靠右对齐了。方括号是为了看清空格:
1#include <stdio.h>2 3int main(void) {4 printf("[%5d]\n", 42);5 printf("[%5d]\n", 1234);6 printf("[%5d]\n", 123456);7 return 0;8}
[ 42] [ 1234] [123456]
123456 有 6 位,比宽度还长,就照原样全部显示,一位也不会少。宽度前面加一个减号,又会怎样?
这段程序显示什么?
1#include <stdio.h>2 3int main(void) {4 printf("[%-5d]\n", 42);5 return 0;6}
- 的意思是左对齐:数先写,不够的空格补在后面。它不会让 42 变成负数。
宽度和小数位可以一起用。%8.2f 是至少 8 个字符、两位小数。一列数字这样对齐,小数点就上下对齐了:
1#include <stdio.h>2 3int main(void) {4 printf("%-4d%8.2f\n", 1, 3.5);5 printf("%-4d%8.2f\n", 2, 12.25);6 printf("%-4d%8.2f\n", 3, 108.0);7 return 0;8}
1 3.50 2 12.25 3 108.00
| 写法 | 意思 | 显示成 |
|---|---|---|
[%d] 配 42 | 照原样 | [42] |
[%5d] 配 42 | 至少 5 个字符,靠右 | [ 42] |
[%-5d] 配 42 | 至少 5 个字符,靠左 | [42 ] |
[%.2f] 配 3.14159 | 两位小数 | [3.14] |
[%8.2f] 配 3.14159 | 至少 8 个字符,两位小数 | [ 3.14] |
显示 % 本身
% 在 printf 里是格式符的开头。要显示一个真正的百分号,就写两个:%%。
1#include <stdio.h>2 3int main(void) {4 int done = 75;5 double rate = 2.5;6 printf("完成了 %d%%\n", done);7 printf("年利率:%.1f%%\n", rate);8 return 0;9}
完成了 75% 年利率:2.5%
用 scanf 读一个数
printf 往外显示,scanf 往里读:它等用户输入,再把读到的值放进变量。点运行,输入一个数试试;页面上显示的是有人输入 25 时的样子(输入的内容本身不显示)。
1#include <stdio.h>2 3int main(void) {4 int age;5 printf("你多大了?\n");6 scanf("%d", &age);7 printf("你今年 %d 岁\n", age);8 return 0;9}
你多大了? 你今年 25 岁
scanf("%d", &age) 里的 %d 说要读一个整数,&age 说读到的数放进 age。注意变量名前面的 &:scanf 要知道变量在内存里的哪个位置,才能往里放。为什么是这样,第 15 课再讲;现在只要记住:scanf 里的变量前面写 &,printf 里不写。
小技巧: 忘了写 & 是用 scanf 时最常见的错。编译器一般会给一条警告,警告也要看。
一次读几个值
和 printf 一样,一个 scanf 可以有好几个格式符,后面的变量按顺序对上:
1#include <stdio.h>2 3int main(void) {4 int width;5 int height;6 printf("输入宽和高:\n");7 scanf("%d %d", &width, &height);8 printf("宽 %d,高 %d\n", width, height);9 return 0;10}
输入宽和高: 宽 3,高 4
用户可以输入 3 4 再回车,也可以 3 回车、4 回车:%d 会跳过前面的空格和换行,去找下一个数。
读小数用 %lf
读 double 时,scanf 要写 %lf(l 是 long 的第一个字母),不是 %f。显示的时候 printf 照样用 %f:
1#include <stdio.h>2 3int main(void) {4 double price;5 printf("价格是多少?\n");6 scanf("%lf", &price);7 printf("价格:%.2f\n", price);8 return 0;9}
价格是多少? 价格:19.90
| 类型 | printf 显示 | scanf 读入 |
|---|---|---|
int | %d | %d |
double | %f | %lf |
scanf 的返回值
用户什么都可能输入。scanf 做完以后会给出一个数:成功读到了几个值。把它存进变量看看,假设用户输入的是 abc:
1#include <stdio.h>2 3int main(void) {4 int count = 0;5 int n = scanf("%d", &count);6 printf("读到了 %d 个数\n", n);7 printf("count 还是 %d\n", count);8 return 0;9}
读到了 0 个数 count 还是 0
abc 不是整数,所以一个也没读到,n 是 0,count 也没被改。现在知道有这么回事就行;学了 if(第 5 课)以后,就能用它检查用户是不是真的输入了数字。
练一练
写好代码,点检查。提示随便看,实在想不出来再看答案。
两位小数
✓让程序显示 价格:3.50。
价格:3.50
1#include <stdio.h>2 3int main(void) {4 double price = 3.5;5 printf("价格:%f\n", price);6 return 0;7}
对齐
✓让三个分数都占 5 个字符、靠右对齐,显示成下面这样。
95
8
1001#include <stdio.h>2 3int main(void) {4 int a = 95;5 int b = 8;6 int c = 100;7 printf("%d\n", a);8 printf("%d\n", b);9 printf("%d\n", c);10 return 0;11}
折扣
✓用一个 printf 和这两个变量,显示 折扣 10%,实付 45.50。
折扣 10%,实付 45.50
1#include <stdio.h>2 3int main(void) {4 int discount = 10;5 double total = 45.5;6 7 return 0;8}
这一课学会了
%.2f显示两位小数,会四舍五入;变量里的值不变。%5d至少占 5 个字符、靠右;%-5d靠左;%8.2f宽度和小数位一起用。- 要显示
%,写%%。 scanf("%d", &x)读一个整数放进x;变量前面要写&,为什么第 15 课再讲。- 一个
scanf可以读好几个值;读double用%lf。 scanf返回成功读到的值的个数。