24 / 07 / 10

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

练习 7:更多的变量和一些算术

int main(int argc, char *argv[]) { int bugs = 100; double bug_rate = 1.2; printf("You have %d bugs at the imaginary rate of %f.\n", bugs, bug_rate); long universe_of_defects = 1L * 1024L * 1024L * 1024L; printf("The entire universe has %ld bugs.\n", universe_of_defects); double expected_bugs = bugs * bug_rate; printf("You are expected to have %f bugs.\n", expected_bugs); double part_of_universe = expected_bugs / universe_of_defects; printf("That is only a %e portion of the universe.\n", part_of_universe); // this makes no sense, just a demo of something weird char nul_byte = '\0'; int care_percentage = bugs * nul_byte; printf("Which means you should care %d%%.\n", care_percentage); return 0; }

附加题 1

把为universe_of_defects赋值的数改为不同的大小,观察编译器的警告。

ex7.c: In function ‘main’: ex7.c:10:78: warning: integer overflow in expression of type ‘long int’ results in ‘0’ [-Woverflow] 10 | = 1024L * 1024L * 1024L * 1024L * 1024L * 1024L * 1024L * 1024L * 1024L; | ^ cc -o ex7 ex7.o

在 C/C++ 中,long 的大小和范围依赖于编译器和操作系统。通常情况下:

  • 在 32 位系统中:long 通常是 32 位,范围为 -2,147,483,648 到 2,147,483,647。

  • 在 64 位系统中:long 通常是 64 位,范围为 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807。

附加题 2

这些巨大的数字实际上打印成了什么?

The entire universe has 0 bugs.

打印成了 0,BTW,使用 Valgrind 并没有错误提示。

附加题 3

long改为unsigned long,并试着找到对它来说太大的数字。

ex7.c: In function ‘main’: ex7.c:10:41: warning: integer constant is so large that it is unsigned 10 | unsigned long universe_of_defects = 18446744073709551615; | ^~~~~~~~~~~~~~~~~~~~ cc -o ex7 ex7.o

在 C/C++ 中,unsigned long 的大小和范围也依赖于编译器和操作系统。通常情况下:

  • 在 32 位系统中:unsigned long 通常是 32 位,范围为 0 到 4,294,967,295。

  • 在 64 位系统中:unsigned long 通常是 64 位,范围为 0 到 18,446,744,073,709,551,615。

哎呀,去掉符号位自然就是两倍啦。

附加题 4

上网搜索unsigned做了什么。

诶呀,表明了是无符号数,可以多一位用来储存数的大小啦。

附加题 5

试着自己解释(在下个练习之前)为什么char可以和int相乘。

char 类型被存储为整型,编译器可以自动处理隐式转换。