解析:
这道题考查的是 C 语言中 `scanf` 函数的格式控制符及其使用规则。我们需要根据变量 `a`(float 型)和 `b`(unsigned 型,即无符号整型)的类型,来判断哪个输入语句是合法的。
**详细解析如下:**
1. **分析变量类型与对应的格式符:**
* `a` 是 `float` 型:在 `scanf` 中,浮点数通常使用 `%f`、`%e`、`%g` 等格式符。**注意**:`scanf` 的格式符中**不能指定精度**(如 `.2`),只能指定宽度(如 `%6f` 是合法的,但 `%6.2f` 是非法的)。
* `b` 是 `unsigned` 型(即 `unsigned int`):在 `scanf` 中,无符号整数可以使用 `%u`(十进制无符号)、`%o`(八进制无符号)、`%x` 或 `%X`(十六进制无符号)等格式符。虽然 `%d` 用于有符号整数,但在某些编译器实现中,如果输入值在范围内,用 `%d` 读取到 unsigned 变量可能不会报错,但从标准规范来看,匹配类型最好使用 `%u` 或 `%o`、`%x`。然而,更关键的判断依据往往在于其他选项是否有明显的语法错误。
2. **逐项分析:**
* **A. `scanf("%6.2f%d", &a, &b);`**
* `%6.2f`:**错误**。`scanf` 函数不支持在格式符中指定精度(小数点后的位数)。精度指定(如 `.2`)仅适用于 `printf` 输出函数。在 `scanf` 中使用 `%6.2f` 会导致未定义行为或解析失败。
* 因此,A 选项非法。
* **B. `scanf("%f%n", &a, &b);`**
* `%n`:这是一个特殊的格式符,它不读取任何输入,而是将**到目前为止成功读取的字符数**存储到对应的参数中。
* 问题在于:`%n` 对应的参数应该是一个 `int *` 指针。虽然 `unsigned int` 和 `int` 在某些系统上大小相同,但语义上 `%n` 是用来获取计数的,而不是用来读取一个普通的无符号整数变量的值。此外,题目意图显然是让 `b` 接收一个输入的数值,而不是接收“已读字符计数”。更重要的是,如果 `b` 被当作 `%n` 的目标,它就不会从输入流中读取代表 `b` 值的数据,这不符合常规的“输入变量 b”的逻辑。虽然语法上可能编译通过(取决于指针类型兼容性警告),但这通常不被视为对变量 `b` 进行正常数据输入的“合法”或“正确”方式。相比之下,C 选项更符合常规输入逻辑。
* *注:在某些严格的标准检查下,类型不匹配(unsigned int* vs int*)也可能被视为问题。*
* **C. `scanf("%f%3o", &a, &b);`**
* `%f`:正确,用于读取 `float` 型变量 `a`。
* `%3o`:正确。`%o` 是用于读取**八进制无符号整数**的格式符,完全匹配 `unsigned` 型变量 `b`。`3` 表示最大域宽为 3,即最多读取 3 个字符,这是 `scanf` 允许的用法(指定宽度)。
* 因此,C 选项在语法和语义上都是完全合法的。
* **D. `scanf("%f%f", &a, &b);`**
* 第一个 `%f` 对应 `&a`(float),正确。
* 第二个 `%f` 对应 `&b`(unsigned int),**错误**。`%f` 期望的是一个指向 `float` 或 `double` 的指针。将一个 `unsigned int` 变量的地址传给 `%f` 会导致类型不匹配,`scanf` 会尝试将输入的浮点数二进制表示写入整型变量的内存空间,这将导致数据错误和未定义行为。
* 因此,D 选项非法。
**结论:**
只有 **C** 选项中的格式符与变量类型正确匹配,且语法符合 `scanf` 的规范(没有非法的精度指定,格式符类型正确)。
**正确答案:C**