跳转至

知识点 02 · 格式化输入输出

本页最后更新于 ,内容可能过时

scanf/printf 的格式串必须与参数类型匹配,这是本课程年年考的点。

1 · double%f:格式串类型不匹配

如下程序,scanf 输入:1<B>.234<CR>(其中 <B> 表示空格,<CR> 表示回车),输出( )。

#include<stdio.h>

int main() {
    double x;
    scanf("%f", &x);
    printf("%.2f", x);
    return 0;
}
  • A. 1.234
  • B. 1.23
  • C. 1.00
  • D. 以上答案均不是
答案

D

解析

陷阱在 %fscanf%f 要求的是 float*,而 &xdouble*——两者类型不匹配。

scanf 会按 float(4 字节)去写这 8 字节的 double,读进来的数据是错的,所以输出既不是 1.23 也不是 1.234,只能是"以上答案均不是"。

正确写法是 scanf("%lf", &x)printf%f%lf 都行,因为可变参数会做默认实参提升)。

scanf 里 double 必须写 %lf


2 · 同一个陷阱换个数

有如下程序,scanf 输入:1234<B>.5678<CR> 后(其中 <B> 表示空格,<CR> 表示回车),printf 输出( )。

#include<stdio.h>

int main() {
    double x;
    scanf("%f", &x);
    printf("%.2f", x);
    return 0;
}
  • A. 1234.5678
  • B. 1234.56
  • C. 1234.00
  • D. 以上答案均不是
答案

D

解析

同一个陷阱、同一段程序,只是输入的数字换了——可见这个考点年年考。

scanf("%f", &x) 里的 %ffloat*&x 却是 double*,类型不匹配导致读入的数据本身就是错的,跟输入的是 1 .234 还是 1234 .5678 无关,四个具体数值选项(1234.5678 / 1234.56 / 1234.00)一个都不对。

改成 scanf("%lf", &x) 才会输出 1234.56


3 · 四个输入输出语句谁不会出错

请指出以下能够正确运行的输入输出语句。

A)

int a, *b;
scanf("%d", b);

B)

char d[2]={'c', 'h'};
printf("%s\n", d);

C)

float a = 5.0;
printf("%d\n", &a);

D)

float c;
scanf("%f", c);
答案

C

解析

先把三个错项排掉——A:b 定义了但从未初始化,直接 scanf("%d", b) 就是往一个野指针写数据(*b 处应补 &a,正确写法是 scanf("%d", &a));

B:char d[2] 存不下 "abc" 那类字符串所需的结束符 '\0'%s 找不到终止符会一直往后续内存读下去(应补上 '\0');

D:scanf("%f", c) 漏了取地址符 &c 是变量值不是指针,直接崩。

C 是唯一"不会立刻出错"的:&afloat*%d 会把它当整数打印,即打印地址。

严格说

严格说,用 %d 去打印一个指针属于实现定义行为(64 位机器上 int 4 字节、指针 8 字节,理论上可能截断),所以 C 并不是"标准意义上完全正确"。

但本题问的是"能够正确运行",A/B/D 是当场崩溃或未定义行为,只有 C 能跑通——这是本题的命题取向,考试选 C 即可。


4 · 能正确输出内容的代码片段

下列代码片段可以正确输出内容的是?

  • A. printf("%d", 'A'-'a');
  • B. scanf("%d", NULL);
  • C. char str[3]="abc"; printf("%s",str);
  • D. printf("%f", "123.45");
答案

A

解析

A 正确:字符常量参与算术运算时按 int 用,'A'-'a' = 65 - 97 = -32,用 %d 输出完全合法。

B 把 NULL 当作 int* 传给 scanf,等于往地址 0 写数据,运行时崩溃。

C 是最经典的陷阱:char str[3] 只有 3 字节,装不下 "abc" 加结束符 '\0' 共 4 字节,字符串没有终止符,printf("%s") 会越界一直读到内存里的随机 \0 为止——能"编译过",但输出内容不可预期。

D 用 %f 去打一个 char*"123.45" 是字符串字面量的地址),格式与参数类型不匹配,属未定义行为。