C语言scanf()与printf()调用异常问题及原理咨询
关于
scanf()和printf()调用格式错误导致异常的原因解析 1. 标准格式代码输出正常的原因
scanf()的标准调用要求格式控制符必须对应变量的地址(通过&取地址),这样才能将输入值写入变量对应的内存空间;printf()则要求格式控制符与后续输出参数的类型、数量完全匹配。严格遵循规则时,函数能正确完成内存读写与输出流程,因此运行正常。
2. 未给scanf()传地址参数的异常原因
scanf()的后续参数必须是指向对应类型变量的指针,用来接收输入数据。若直接传变量名(而非地址),相当于把变量的当前值当作内存地址传入:
- 输入整数时:
scanf()会尝试把输入值写入这个“错误的地址”,属于非法内存访问,触发未定义行为,操作系统会直接终止程序,因此后续scanf()和printf()均不执行。 - 输入字符时:虽同样是非法内存访问,但部分场景下程序可能未立刻崩溃(仍属于未定义行为的表现),但
scanf()并未正确写入变量,a、b保留初始垃圾值;同时输入字符与格式符(如%d)不匹配,会导致输入缓冲区残留字符,scanf()匹配失败后直接跳过后续调用,第二个scanf()不执行,最终printf()输出垃圾值。
3. 重复编写未传地址代码的异常一致原因
未传地址的本质是违反scanf()的参数规范,每次运行都会触发相同逻辑的未定义行为,在相同运行环境下,异常表现会完全一致(但未定义行为不保证跨环境表现相同)。
4. 既未给scanf()传地址、也未给printf()传输出参数的异常原因
- 输入匹配格式的值时:
scanf()的非法内存访问未触发即时崩溃(未定义行为的随机性表现),而printf()因格式控制符与参数数量不匹配,会从栈中读取随机垃圾数据作为输出值,因此所有函数看似执行,但输出垃圾值。 - 输入不匹配字符时:第一个
scanf()因格式匹配失败+非法内存访问直接触发程序终止,printf()在终止前执行并输出栈中垃圾值,第二个scanf()因程序终止无法执行。
5. 第一个scanf()传地址、第二个未传的异常原因
- 输入匹配值时:第一个
scanf()正确将值写入a的内存,但第二个scanf()传变量名(非地址)导致非法内存访问,b未被正确赋值,保留垃圾值;若非法访问破坏了a的内存空间(未定义行为的表现),则a也会变成垃圾值,最终两者都输出垃圾值。 - 第一个输入匹配值、第二个输入字符时:第一个
scanf()正确写入a,第二个scanf()因输入字符与格式符不匹配直接跳过匹配流程,未触发非法内存访问,a的内存未被破坏,因此输出正确值,b仍为初始垃圾值。
内容的提问来源于stack exchange,提问作者Gyanaranjan Behera
相关产品推荐
相关产品推荐

