24 / 07 / 10

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

练习 8:大小和数组

#include <stdio.h> int main(int argc, char *argv[]) { int areas[] = {10, 12, 13, 14, 20}; char name[] = "Zed"; char full_name[] = { 'Z', 'e', 'd', ' ', 'A', '.', ' ', 'S', 'h', 'a', 'w', '\0' }; // WARNING: On some systems you may have to change the // %ld in this code to a %u since it will use unsigned ints printf("The size of an int: %ld\n", sizeof(int)); printf("The size of areas (int[]): %ld\n", sizeof(areas)); printf("The number of ints in areas: %ld\n", sizeof(areas) / sizeof(int)); printf("The first area is %d, the 2nd %d.\n", areas[0], areas[1]); printf("The size of a char: %ld\n", sizeof(char)); printf("The size of name (char[]): %ld\n", sizeof(name)); printf("The number of chars: %ld\n", sizeof(name) / sizeof(char)); printf("The size of full_name (char[]): %ld\n", sizeof(full_name)); printf("The number of chars: %ld\n", sizeof(full_name) / sizeof(char)); printf("name=\"%s\" and full_name=\"%s\"\n", name, full_name); return 0; }

full_name最后的'\0'去掉,并重新运行它,在valgrind下再运行一遍。现在将full_name的定义从main函数中移到它的上面,尝试在Valgrind下运行它来看看是否能得到一些新的错误。有些情况下,你会足够幸运,不会得到任何错误。

去掉 '\0':无报错;移动至 main 上:无报错。

areas[0]改为areas[10]并打印,来看看Valgrind会输出什么。

The first area is 76098960, the 2nd 12. Valgrind 无报错。

尝试上述操作的不同变式,也对namefull_name执行一遍。

同上。

附加题 1

尝试使用areas[0] = 100;以及相似的操作对areas的元素赋值。

可以正常赋值。

附加题 2

尝试对namefull_name的元素赋值。

make ex8 cc -Wall -g -c ex8.c -o ex8.o ex8.c: In function ‘main’: ex8.c:16:14: error: assignment to expression with array type 16 | name = "A"; | ^ make: *** [Makefile:13: ex8.o] Error 1

尝试使用 strcpy 函数,需补充string.h并避免越界。

ex8.c: In function ‘main’: ex8.c:16:9: warning: implicit declaration of function ‘strcpy’ [-Wimplicit-function-declaration] 16 | strcpy(name, "Qidi"); | ^~~~~~ ex8.c:2:1: note: include ‘<string.h>’ or provide a declaration of ‘strcpy’ 1 | #include <stdio.h> +++ |+#include <string.h> 2 | ex8.c:16:9: warning: incompatible implicit declaration of built-in function ‘strcpy’ [-Wbuiltin-declaration-mismatch] 16 | strcpy(name, "Qidi"); | ^~~~~~ ex8.c:16:9: note: include ‘<string.h>’ or provide a declaration of ‘strcpy’ ex8.c:16:9: warning: ‘__builtin_memcpy’ writing 5 bytes into a region of size 4 overflows the destination [-Wstringop-overflow=] 16 | strcpy(name, "Qidi"); | ^~~~~~~~~~~~~~~~~~~~ ex8.c:12:10: note: destination object ‘name’ of size 4 12 | char name[] = "Zed"; | ^~~~ cc -o ex8 ex8.o

附加题 3

尝试将areas的一个元素赋值为name中的字符。

areas[0] = name[0]The first area is 90, the 2nd 12. 以 ASCII 码赋值。

附加题 4

上网搜索在不同的CPU上整数所占的不同大小。

  • x86 架构:通常采用 ILP32 数据模型,即 int、long 和指针都是 32 位。

  • x86-64 或 AMD64 架构:通常采用 LP64 数据模型,即 int 是 32 位,而 long 和指针是 64 位。