原文:Exercise 9: Arrays And Strings
上一个练习中,我们学习了如何创建基本的数组,以及数组如何映射为字符串。这个练习中我们会更加全面地展示数组和字符串的相似之处,并且深入了解更多内存布局的知识。
这个练习向你展示了C只是简单地将字符串储存为字符数组,并且在结尾加上'\0'(空字符)。你可能在上个练习中得到了暗示,因为我们手动这样做了。下面我会通过将它与数字数组比较,用另一种方法更清楚地实现它。
'\0'
#include <stdio.h> int main(int argc, char *argv[]) { int numbers[4] = {0}; char name[4] = {'a'}; // first, print them out raw printf("numbers: %d %d %d %d\n", numbers[0], numbers[1], numbers[2], numbers[3]); printf("name each: %c %c %c %c\n", name[0], name[1], name[2], name[3]); printf("name: %s\n", name); // setup the numbers numbers[0] = 1; numbers[1] = 2; numbers[2] = 3; numbers[3] = 4; // setup the name name[0] = 'Z'; name[1] = 'e'; name[2] = 'd'; name[3] = '\0'; // then print them out initialized printf("numbers: %d %d %d %d\n", numbers[0], numbers[1], numbers[2], numbers[3]); printf("name each: %c %c %c %c\n", name[0], name[1], name[2], name[3]); // print the name like a string printf("name: %s\n", name); // another way to use name char *another = "Zed"; printf("another: %s\n", another); printf("another each: %c %c %c %c\n", another[0], another[1], another[2], another[3]); return 0; }
在这段代码中,我们创建了一些数组,并对数组元素赋值。在numbers中我们设置了一些数字,然而在names中我们实际上手动构造了一个字符串。
numbers
names
当你运行这段代码的时候,你应该首先看到所打印的数组的内容初始化为0值,之后打印初始化后的内容:
$ make ex9 cc -Wall -g ex9.c -o ex9 $ ./ex9 numbers: 0 0 0 0 name each: a name: a numbers: 1 2 3 4 name each: Z e d name: Zed another: Zed another each: Z e d $
你会注意到这个程序中有一些很有趣的事情:
'a'
"a"
char name[4] = {'a'}
char *another = "name"
注意我使用了相同的语法和代码风格来和整数数组和字符数组交互,但是printf认为name是个字符串。再次强调,这是因为对C语言来说,字符数组和字符串没有什么不同。
printf
name
最后,当你使用字符串字面值时你应该用char *another = "Literal"语法,它会产生相同的东西,但是更加符合语言习惯,也更省事。
char *another = "Literal"
C中所有bug的大多数来源都是忘了预留出足够的空间,或者忘了在字符串末尾加上一个'\0'。事实上,这些bug是非常普遍并且难以改正的,大部分优秀的C代码都不会使用C风格字符串。下一个练习中我们会学到如何彻底避免C风格字符串。
使这个程序崩溃的的关键就是拿掉字符串结尾的'\0'。下面是实现它的一些途径:
name[3] = 'A'
{'a','a','a','a'}
试着想出一些其它的办法让它崩溃,并且在Valgrind下像往常一样运行这个程序,你可以看到具体发生了什么,以及错误叫什么名字。有时Valgrind并不能发现你犯的错误,则需要移动声明这些变量的地方看看是否能找出错误。这是C的黑魔法的一部分,有时变量的位置会改变bug。
Valgrind
int
another
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8