字符串须知
关于字符串常量
假设您编写并运行下面两段代码:
printf("%s\n",s);
Fragment 2
char s[100];strcpy(s,"hello");printf("%s\n",s);
虽然两个代码段的输出相同,但是其运行过程却有很大不同。在代码段2中,您不能写s="hello";。要明白这种区别,您需要了解一下C中的字符串常量表。
编译程序时,编译器会生成目标代码文件,它包含了机器代码和一个由在程序中声明的所有字符串常量组成的表格。代码段1中的s="hello";这条语句使s指向字符串常量表中hello的地址。因为此字符串位于字符串常量表中,严格来说属于可执行代码的一部分,所以不能被修改。您只能用指针指向它,然后以只读方式使用。
在代码段2中,字符串hello也在常量表里面,所以您可以将其复制给名为s的字符数组。因为s不是一个普通的指针,所以在代码段2中不能用s="hello";。它甚至不能通过编译。
关于在字符串中使用malloc
假设您写了下面的程序:
int main()
char *s;
s=(char *) malloc (100);
s="hello";free(s);return 0;
它可以成功编译,但当运行到free这一行的时候会发生段错误。malloc语句分配了一个100字节大小的内存块并使s指向它,而现在问题就出在s="hello";这行上。虽然语法是正确的,但执行了s="hello";以后,s指向了字符串常量表的内容,分配的内存块就被丢失了。因为是字符串常量表,所以s现在指向的字符串是不可修改的。free函数会失败,因为它无法释放可执行区的内存块。
下面是正确的写法:
int main()
char *s;s=(char *) malloc (100);strcpy(s,"hello");free(s);return 0;
动手一试
编写一个读入一个字符串的程序。此字符串的开头是一个名字,后接一个空格,最后是一个姓氏。编写一个函数清除字符串开头和结尾的空格。再编写一个函数返回姓氏。
编写一个函数将字符串转换成大写字母。
再编写一个函数将字符串的第一个单词取出并返回剩下的部分。
C常见错误
很容易因粗心忘记字符串结尾的字符\0,这将导致难以发现的程序错误。复制字符串时请确定复制了\0。创建新的字符串时请确定包含了\0。如果要复制字符串,请确认目标字符串可以容纳源字符串,包括\0。最后,您若要把一个字符指针指向某些字符,请确定它们以\0结尾。