字符串
C语言中的字符串在很大程度上与指针交织在一起。要有效地使用C字符串,您必须熟悉前面文章中介绍的指针概念。但是,一旦您习惯了它们,您通常可以非常有效地执行字符串18新利最新登入操作。
C语言中的字符串只是一个字符数组。下面的行声明了一个数组,它可以容纳最多99个字符的字符串。
广告
char str [100];
它像你所期望的那样保存字符:str [0]是字符串的第一个字符,str [1]是第二个字符,以此类推。但是为什么100个元素的数组不能容纳100个字符呢?因为C使用了以null结尾的字符串,这意味着任何字符串的结尾都用ASCII值0(空字符)标记,该值在C中也表示为' \ 0.
空终止与许多其他语言处理字符串的方式有很大不同。例如,在Pascal中,每个字符串由一个字符数组组成,长度字节用于记录数组中存储的字符数量。当您要求字符串的长度时,这种结构为Pascal提供了明确的优势。Pascal可以简单地返回长度字节,而C必须计数字符,直到找到' \ 0.这一事实使得C语言在某些情况下比Pascal慢得多,但在其他情况下却更快,正如我们将在下面的例子中看到的那样。
因为C语言本身不提供对字符串的显式支持,所以所有字符串处理函数都在库中实现。字符串I/0操作(get、put等)在
字符串不是C语言特有的,这一事实迫使您创建一些相当迂回的代码。例如,假设你想把一个字符串赋值给另一个字符串;也就是说,您希望将一个字符串的内容复制到另一个字符串。在C语言中,正如我们在上一篇文章中看到的,不能简单地将一个数组分配给另一个数组。你必须一个元素一个元素地复制它。字符串库(
char [100];strcpy(年代,“你好”);
执行完这两行之后,下面的图显示了s的内容:18新利最新登入
上面的图表显示了数组及其字符。18新利最新登入下面的图表显示了字符的等效ASCII码值18新利最新登入,以及C语言如何实际考虑字符串(作为包含整数值的字节数组)。看到18新利最新登入比特和字节是如何工作的有关ASCII码的讨论。
下面的代码展示了如何使用18新利最新登入拷贝字符串在C:
#includeint main() {char s1[100],s2[100];strcpy (s1,“你好”);/*复制“hello”到s1 */ strcpy(s2,s1);/*复制s1到s2 */返回0;}
拷贝字符串在c中初始化字符串时使用比较字符串函数来比较两个字符串。它返回一个表示比较结果的整数。0表示两个字符串相等,负值表示s1小于s2,为正值表示s1大于s2.
#include#include int main() {char s1[100],s2[100];得到(s1);得到(s2);If (strcmp(s1,s2)==0) printf("equal\n");Else if (strcmp(s1,s2)<0) printf("s1小于s2\n");Else printf("s1大于s2\n");返回0;}
字符串库中的其他常用函数包括strlen,它返回字符串的长度,和strcat它连接两个字符串。字符串库包含许多其他函数,您可以通过阅读手册页来详细了解它们。
为了让你开始构建字符串函数,并帮助你理解其他程序员的代码(似乎每个人在程序中都有他或她自己的一组用于特殊目的的字符串函数),我们将看两个例子,strlen而且拷贝字符串.下面是一个严格类似pascal的版本strlen:
Int strlen(char s[]) {Int x;x = 0;While (s[x] != '\0') x=x+1;返回(x);}
大多数C程序员都避免使用这种方法,因为它看起来效率很低。相反,他们通常使用基于指针的方法:
Int strlen(char *s) {Int x=0;While (*s != '\0') {x++;s + +;}返回(x);}
您可以将此代码缩写为:
Int strlen(char *s) {Int x=0;While (*s++) x++;返回(x);}
我想一个真正的C专家可以使这段代码更短。
当我使用gcc在MicroVAX上编译这三段代码时(不使用任何优化),并在120个字符的字符串上运行每段代码20,000次,第一段代码生成的时间为12.3秒,第二段代码生成的时间为12.3秒,第三段代码生成的时间为12.9秒。这是什么意思?对我来说,这意味着您应该以您最容易理解的方式来编写代码。指针通常会生成更快的代码,但是strlen上面的代码表明情况并非总18新利最新登入是如此。
我们可以经历同样的进化拷贝字符串:
Strcpy (char s1[],char s2[]) {int x;为(x = 0;x < = strlen (s2);x + +) s1 [x] = s2 [x];}
注意这里< =是很重要的为循环,因为代码会复制' \ 0.一定要复制' \ 0.如果省略它,稍后会出现重大错误,因为字符串没有结尾,因此长度未知。还要注意,这段代码的效率非常低,因为strlen每次通过为循环。要解决这个问题,你可以使用下面的代码:
Strcpy (char s1[],char s2[]) {int x,len;len = strlen (s2);为(x = 0;x < =兰;x + +) s1 [x] = s2 [x];}
指针的版本与此类似。
strcpy (char * s1、s2 char *){虽然(* s2 ! = ' \ 0) {* s1 = * s2;s1 + +;s2 + +;}}
你可以进一步压缩这段代码:
strcpy (char * s1、s2 char *){虽然(* s2) * s1 + + = * s2 + +;}
如果你愿意,你甚至可以说While (*s1++ = *s2++);.第一个版本拷贝字符串将120个字符的字符串复制10000次需要415秒,第二个版本需要14.5秒,第三个版本需要9.8秒,第四个版本需要10.3秒。如您所见,指针在这里提供了显著的性能提升。
原型是拷贝字符串函数表示它被设计为返回一个指向字符串的指针:
Char *strcpy(Char *s1, Char *s2)
大多数字符串函数返回一个字符串指针作为结果,并且拷贝字符串返回的值s1这就是结果。
使用指针和字符串有时可以明显提高速度,如果你稍微考虑一下,你可以利用这些优势。例如,假设您想从字符串中删除前导空格。您可能倾向于将字符移到空格上方以删除它们。在C语言中,你可以完全避免移动:
#include#include int main() {char s[100],*p;(s);p = s;While (*p==' ') p++;printf (" % s \ n, p);返回0;}
这比移动技术快得多,特别是对于长弦。
在继续学习和阅读其他代码的过程中,您将学到许多其他关于字符串的技巧。练习是关键。