24 / 07 / 09

「一生一芯」Learn C the hard way - Ex 3

练习 3:格式化输出

#include <stdio.h> int main() { int age = 10; int height = 72; printf("I am %d years old.\n", age); printf("I am %d inches tall.\n", height); return 0; }

附加题 1

找到尽可能多的方法使ex3崩溃。

为了使你的C程序 ex3 崩溃,有几个方法可以考虑,涉及改变或引入错误。以下是几种可能的方式:

  1. 使用未初始化的变量

    int main() { int age; int height; printf("I am %d years old.\n", age); printf("I am %d inches tall.\n", height); return 0; }

    这样做会使用未初始化的变量 ageheight,可能会导致程序输出垃圾值,甚至崩溃。

  2. 除以零

    int main() { int age = 10; int height = 72; int zero = 0; int crash = age / zero; // 除以零 printf("I am %d years old.\n", crash); printf("I am %d inches tall.\n", height); return 0; }
  3. 访问无效内存

    int main() { int age = 10; int height = 72; int *ptr = NULL; *ptr = age; // 访问NULL指针 printf("I am %d years old.\n", age); printf("I am %d inches tall.\n", height); return 0; }

附加题 2

执行man 3 printf来阅读其它可用的'%'格式化占位符。如果你在其它语言中使用过它们,应该看着非常熟悉(它们来源于printf)。

常见的 printf 格式化占位符:

  1. %d: 以十进制形式输出一个整数。

  2. %i: 以十进制形式输出一个整数(与 %d 类似)。

  3. %u: 以十进制形式输出一个无符号整数。

  4. %o: 以八进制形式输出一个无符号整数。

  5. %x: 以小写十六进制形式输出一个无符号整数。

  6. %X: 以大写十六进制形式输出一个无符号整数。

  7. %f: 以小数点形式输出一个浮点数。

  8. %e: 以科学计数法(小写e)形式输出一个浮点数。

  9. %E: 以科学计数法(大写E)形式输出一个浮点数。

  10. %g: 自动选择使用 %f%e,以更紧凑的形式输出浮点数。

  11. %G: 自动选择使用 %f%E,以更紧凑的形式输出浮点数。

  12. %c: 输出一个字符。

  13. %s: 输出一个字符串。

  14. %p: 输出一个指针的值。

  15. %n: 将到目前为止输出的字符数存储到对应的参数中。

  16. %%: 输出一个 % 字符。

附加题 3

ex3添加到你的Makefileall列表中。到目前为止,可以使用make clean all来构建你所有的练习。

附加题 4

ex3添加到你的Makefileclean列表中。当你需要的时候使用make clean可以删除它。

CFLAGS = -Wall -g #定义编译器标志。-Wall 启用所有常见的警告,-g 生成调试信息。 LDFLAGS = #定义链接器标志。此处为空,但可以用来指定库路径和库文件。 TARGETS = ex1 ex3 #定义要生成的目标可执行文件名称。 SRCS = ex1.c ex3.c #定义源文件。 OBJS = $(SRCS:.c=.o) #将源文件扩展名从 .c 转换为 .o 以得到目标文件。 all: $(TARGETS) #默认目标,生成目标可执行文件。 $(TARGETS): %: %.o #定义如何链接目标文件生成可执行文件。 $(CC) $(LDFLAGS) -o $@ $< %.o: %.c #定义通用规则,编译 .c 文件生成 .o 文件。 $(CC) $(CFLAGS) -c $< -o $@ clean: #定义清理规则,删除目标文件和可执行文件。 $(RM) $(OBJS) $(TARGETS) .PHONY: all clean #声明伪目标,避免与文件名冲突。