C语言学习笔记 - 41.数据类型 - scanf函数核心知识点复习

本知识点对应谭浩强《C程序设计(第五版)》第3章3.4.4节"用scanf函数输入数据"的综合复习,是C语言用户交互功能的核心基础。scanf与printf是一对功能互补的标准输入输出函数,掌握scanf的正确用法是编写健壮交互程序的前提。


1. scanf函数的核心功能

scanf函数的本质:将用户从键盘输入的字符序列,按照指定格式转换为对应类型的数据,并存入指定变量的内存地址中。

它与printf函数功能完全对应:

  • printf:将变量的内容从内存输出到显示器

  • scanf:将用户输入的数据从键盘存入内存变量


2. scanf的两种基本用法

2.1 用法一:仅包含输入控制符(推荐)

格式字符串中只包含输入控制符,这是最常用、最不易出错的用法。

语法

复制代码
scanf("输入控制符", &变量名);

示例

复制代码
#include <stdio.h>
int main() {
    int i;
    char ch;
    float f;
    
    scanf("%d", &i);    // 输入整数
    scanf("%c", &ch);   // 输入单个字符
    scanf("%f", &f);    // 输入单精度浮点数
    
    return 0;
}

2.2 用法二:包含非输入控制符(不推荐)

格式字符串中同时包含输入控制符和非输入控制符。

核心规则 :非输入控制符必须被用户原样输入,否则会导致输入失败。

示例

复制代码
#include <stdio.h>
int main() {
    int i;
    scanf("m%d", &i); // 非输入控制符'm'必须被原样输入
    printf("i = %d\n", i);
    return 0;
}

输入要求 :用户必须输入m123才能正确赋值,直接输入123会失败。

强烈不推荐的原因

  1. 增加用户输入难度,容易出错

  2. 降低程序健壮性,任何格式偏差都会导致输入失败

  3. 替代方案:使用printf函数输出提示信息,明确告知用户输入格式


3. 输入控制符的核心作用

3.1 为什么必须使用输入控制符?

关键事实 :从键盘输入的所有内容,本质上都是字符,而不是数字。

例如,用户输入123时,操作系统接收到的是三个独立的字符:'1'(ASCII 49)、'2'(ASCII 50)、'3'(ASCII 51)。

输入控制符的作用就是:告诉scanf如何将这些字符转换为对应类型的数据

输入控制符 转换规则
%d 将数字字符序列转换为十进制整数
%c 直接读取单个字符,不进行转换
%f 将数字字符序列转换为单精度浮点数

3.2 常用输入控制符

scanf的输入控制符与printf的输出控制符完全一致:

输入控制符 含义 适用数据类型
%d 输入十进制有符号整数 int
%ld 输入十进制有符号长整数 long int
%c 输入单个字符 char
%f 输入单精度浮点数 float
%lf 输入双精度浮点数 double

3.3 取地址符&的必要性

  • 所有输入参数必须是变量的地址,即变量名前必须加取地址符&

  • scanf需要知道变量的内存地址,才能将转换后的数据存入正确的位置

  • 忘记加&是初学者最常见的严重错误,会导致程序崩溃或产生不可预知的结果


4. scanf的输入解析逻辑

scanf函数按照以下严格规则解析用户输入:

  1. 输入缓冲区中逐个读取字符

  2. 跳过前导空白字符(空格、制表符、回车符)

  3. 读取符合输入控制符要求的字符,直到遇到不符合要求的字符为止

  4. 将读取到的字符序列转换为对应类型的数据

  5. 将转换后的数据存入指定变量

  6. 未读取的字符(包括非法字符)会留在输入缓冲区中

  7. 下一次调用scanf时,会从上次停止的位置继续读取

4.1 示例解析

复制代码
#include <stdio.h>
int main() {
    int i, j;
    
    printf("请输入第一个整数:");
    scanf("%d", &i); // 假设用户输入:89m
    
    printf("请输入第二个整数:");
    scanf("%d", &j); // 这行代码会直接失败
    
    printf("i = %d, j = %d\n", i, j);
    return 0;
}

执行过程

  1. 用户输入89m并按下回车键

  2. 第一个scanf读取字符'8''9',转换为整数89存入变量i

  3. 遇到非法字符'm',停止解析,'m'被留在输入缓冲区中

  4. 第二个scanf从输入缓冲区中读取到'm',无法转换为整数,直接失败

  5. 变量j被赋予随机垃圾值

结论:一个地方的输入错误会导致后续所有scanf语句失败,这是初学者最容易遇到的陷阱之一。


5. 多变量输入的最佳实践

5.1 推荐用法:使用默认空白分隔符

多个输入控制符之间不添加任何非输入控制符,使用默认的空白字符(空格、回车、制表符)作为分隔符。

示例

复制代码
#include <stdio.h>
int main() {
    int i, j;
    
    printf("请输入两个整数,用空格分隔:");
    scanf("%d%d", &i, &j); // 两个%d之间没有任何字符
    
    printf("i = %d, j = %d\n", i, j);
    return 0;
}

合法输入方式

  • 12 34(空格分隔)

  • 12\n34(回车分隔)

  • 12\t34(制表符分隔)

5.2 不推荐用法:使用逗号等非输入控制符

复制代码
scanf("%d,%d", &i, &j); // 不推荐

用户必须严格输入12,34才能正确赋值,输入12 34会导致第二个变量赋值失败。

5.3 绝对禁止:在格式字符串末尾添加\n

复制代码
scanf("%d\n", &i); // 严重错误

会导致程序卡住,用户必须输入任意字符并再次按下回车键才能继续执行。


6. 编程规范与常见问题

  1. 使用scanf前必须加printf提示信息:明确告知用户输入格式和要求

  2. 尽量避免使用非输入控制符:所有格式提示都通过printf输出

  3. 每个变量前必须单独添加取地址符&

  4. 非法输入处理:可以通过循环清除输入缓冲区中的垃圾字符,解决输入错误的连锁反应问题。该功能依赖while循环,将在第5章流程控制中详细讲解。


7. 要点总结

  1. 核心功能:将键盘输入的字符转换为指定格式的数据,存入变量中

  2. 两种用法:仅含输入控制符(推荐)和包含非输入控制符(不推荐)

  3. 控制符作用:必须使用输入控制符,因为键盘输入的本质是字符,需要转换为对应类型的数据

  4. 取地址符 :所有输入参数必须是变量的地址,变量名前必须加&

  5. 解析逻辑:遇到非法字符会停止解析,未读取的字符会留在输入缓冲区中,影响后续输入

  6. 多变量输入:推荐使用默认空白分隔符,不要使用逗号等非输入控制符

  7. 绝对禁止 :不要在scanf格式字符串末尾添加\n

  8. 编程规范:使用scanf前必须用printf输出提示信息,提高程序的用户体验

相关推荐
神仙别闹1 小时前
基于MFC(C++)实现(界面)学委作业管理系统
开发语言·c++·mfc
撩得Android一次心动1 小时前
C语言基础笔记3【个人用】
android·c语言·开发语言·笔记
清平乐的技术专栏1 小时前
【FlinkSQL笔记】(三)Flink SQL 核心重难点(窗口函数、水印)
笔记·sql·flink
存在的五月雨1 小时前
JVM 入门学习笔记(内存模型 / GC / 类加载机制)
jvm·笔记·学习
薇茗1 小时前
【初阶数据结构】 升沉有序的平仄 排序 3
c语言·开发语言·数据结构·算法·排序算法·文件归并排序
什么半岛铁盒1 小时前
LangChain常用组件学习
学习·microsoft·langchain
字节高级特工1 小时前
C++11(一) 革新:右值引用与移动语义
java·开发语言·c++·人工智能·后端
孬甭_1 小时前
双向链表详解
c语言·数据结构·链表
薇茗1 小时前
【初阶数据结构】 升沉有序的平仄 排序 2
c语言·数据结构·算法·排序算法·快排精讲