今天我们来学习运行三个小程序,按照下列步骤依次运行程序,想一想为什么结果会这样?如果有疑问,可以在讨论区讨论
(请自己键入程序,不要采用复制粘贴的方式)

第一个程序:在编译环境下,输入如下代码


1
2
3
4
5
6
7
8
9
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
int a;
scanf("%d",&a);
printf("%d",a);
return 0;
}

运行:

  1. 输入5,看看是什么结果,输入其他的整数,看看输出什么。
    • 5->5; 10->10
  2. 输入5.555,看看是什么结果,输入其他的实数,看看输出什么。
    • 5.555->5; 520.1314->520
  3. 将scanf中的%d,改为%3d,输入12345,看看输出什么。
    • 12345->123
  4. 将scanf中的%d,换为%f,再次运行。输入5,看看什么结果,输入5.555,看看又是什么结果。
    • 5->1084227584; 5.555->1085391503
  5. 将scanf中的%f恢复为%d,将printf中的%d换为%f,再次运行。输入5,看看输出什么结果,输入5.555,看看输出结果是什么。
    • 5->0.000000; 5.555->0.000000

第二个程序:在编译环境下,输入如下代码


1
2
3
4
5
6
7
8
9
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
float a;
scanf("%f",&a);
printf("%f",a);
return 0;
}

运行:

  1. 输入5,看看是什么结果,输入其他的整数,看看输出什么。
    • 5.000000
  2. 输入5.555,看看是什么结果,输入其他的实数,看看输出什么。
    • 5.555000
  3. 将scanf中的%f,改为%3f,输入12345.12345,看看输出什么。
    • 123.000000
  4. 将scanf中的%3f,改为%5.2f,看看能否运行?
    • 12345.12345->0.000000
  5. 将scanf中的%5.2f,恢复为%f,将printf中的%f改为%5f,再次运行。输入12345.55555,看看输出什么结果
    • 12345.555664
  6. 将printf中的%f改为%3f,再次运行,输入12345.55555,看看输出结果是什么。
    • 12345.555664
  7. 将printf中的%f改为%6.2f,再次运行,输入12345.55555,看看输出结果是什么。
    • 12345.56

实验总结与启示

  • 核心主题: 展示C中浮点数的输入输出机制,特别是格式说明符的灵活性和陷阱。scanf易因格式不匹配失败,printf可控制宽度/精度但受浮点硬件限制。
  • 常见问题:
    • 浮点精度丢失:float适合简单计算,双精度double更好。
    • 输入验证:总是检查scanf返回值,避免未初始化变量。
    • 格式兼容:scanf的%f不支持精度,适合用在printf中。

第三个程序:在编译环境下,输入如下代码


1
2
3
4
5
6
7
8
9
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
char a;
scanf("%c",&a);
printf("%c",a);
return 0;
}

运行:

  1. 输入A,看看输出什么结果,输入键盘上任意一个键,看看输出什么。
    • A
  2. 将scanf中的%c,改为%d,输入A,看看输出什么。输入1089,看看输出什么。
    • 不输出;A
  3. 将scanf中的%d,换为%c,再次运行。输入1089,看看什么结果
    • 1
  4. 将printf中的%c换为%d,再次运行。输入A,看看输出什么结果,输入1089,看看输出结果是什么。
    • 65;49
  5. 将printf中的%d换为%f,再次运行。输入A,看看输出什么结果。
    • 0.000000

实验总结与启示

  • 核心主题: 展示C中char的I/O机制,特别是格式不匹配时的风险。char可与整数互换(因ASCII),但与int/float混用易出错。所有结果都符合C语言的预期行为(包括UB),因为C允许实现定义的灵活性,但这也使代码易错。
  • 常见问题:
    • 类型不匹配:scanf/printf依赖正确格式,错配导致UB。总是匹配类型(如char用%c)。
    • 未定义行为:如步骤2/5,避免依赖实现特定行为。
    • ASCII转换:char本质是小整数,%d/%c 可互用,但需理解。
  • 为什么符合预期? 所有输出都可由C标准和常见编译器(如GCC/Clang)解释。没有违反规则,只是展示了边缘情况。