C语言快速入门——理解字符数组与字符串

字符数组

现在让我们把已经习惯的int型数组转换为char型。一般来讲,char型数组通常是用于'a', 'b', 'c', 'd'这类具有可读性的字符。在《类型与变量》一节中讲过,char类型的数据占用1个字节的存储空间,本质上它是一种小整型类型。这表明char型数组也可用来处理数据,如保存一张图像的像素值,保存接收到来自服务器的回复信息等。随着以后对指针的深入理解,我们会对此有更深的见解。此时,我们只用它来处理可阅读字符。

首先,让我们尝试输出"hello"这个字符串,不同的是,这次是使用数组输出。

为了明确的看到各种输出之间的不同,我以大写串END_STR来标识当前输出的结束。第一个"hello",我们使用字符数组存储5个对应字符,并借助for循环输出。第二个与之类似,但却是6个字符,数组以一个转义字符'\0'结束。如果没有特殊的结束符,看上去会与第一行输出没什么不同。第三个使用我们熟悉的printf()函数输出,使用的格式符是%s,表示以字符串的方式输出。最后一个同样使用%s输出了str1,除了输出hello外,后面还跟有奇怪的字符。你可以尝试多运行几次,这些奇怪字符每次都不一样。

分析后两项输出

最后两个"hello",我们都是使用printf函数加%s格式符输出,为什么最后一个乱码了?最明显的不同之处在于数组的定义。str2的最后一个字符是'\0'值,而str1没有这个值。这说明这个'\0'有特殊意义。

我们知道数组传递给函数时,会转换为对应的指针类型,也就是说str2、str1传递给printf函数时,实际会形成类似printf( char *str )形式。回想一下计算数组平均值的函数,对于传递数组的函数,除了数组变量本身外,通常还需要一个int变量以指明数组元素的个数。而我们把str2,str1传递给printf函数时,并没有给定元素的个数!

但是由于str2具有特殊标记'\0',%s格式符对于该字符数组输出了正确值,但str1却没有这么幸运,它乱码了!这就说明了,'\0'指示了字符串的结束,如同给函数间接传递了元素个数一般。实际情况也确实如此,当printf+%s输出char*类型时,碰到'\0'就认为字符串结束了。

'\0'结束字符串

由运行结果图可以看到,"world"没有被输出,这就表明C的字符串是以'\0'表示 “我的话讲完了”。

那'\0'到底是什么呢?咳咳~~,又到了说说ASCII码表的时候了!'\0'是一个转义字符,它代表的是ASCII码值为0的值,也是ASCII码表中的第一个值,在C语言中用于表示字符串结尾标记。 注意数值0与字符'0'是不同的概念,字符'0'可以理解为是书写上用于交流0值的0。

动手试一下

现在你可以尝试将第一个'\0'变为数值0,你会发现得到同样的输出。再尝试将0变为字符'0',再次观察输出并思考一下。假如你一直跟随我们的教程在学习,还是有点紧张你会用什么样的方式来完成这个试验呢?我们已经学习过数组的基础操作,希望你能使用下标运算符去修改数组中的某个值,而不是把代码拷贝多份......

让生活再简单点

假定你现在在编写一款RPG游戏,主人公有千言万语要向玩家诉说。基于现在所掌握的知识,把每个字符用单引号括起来并放到数组中,那简直就是噩梦!好在你的担心是多余的,你发现的问题,语言的设计者已经解决了,那就是使用char*存储字符串!

与单个字符赋值到数组相比,这种方式真的是轻松多了,而且也具有更好的可读性。这个程序会完整的输出"hello, world!",也不会出现乱码。这就表明,以这种赋值方式保存的字符串,语言自身会在结束加上结束标记。

这就是C风格的字符串,以0结束。

在这种形式下,你可能想要尝试修改一下某个字符,如hw[0]='a',程序可以编译过去,但执行会出错。这是因为"hello, world!"是字面常量,确切的说是常量字符串,是不可修改的。(在古老的编译环境下可能是正确的,如VC++6.0)

详细的说,可以这么理解:想像一下,不管是变量还是常量,总要有能存储这种东西的地方,这地方就是内存,是内存就有地址,对于常量存储区域,具有不可写标记(即只读)。hw仅是一个指针,指针的有效性就是指向一个地址,当为hw赋值后它就指向了这个常量地址,因此编译时是成功的。当使用下标修改时,系统发现你想要修改只读内存,然后被无情打脸。

你可能会抱怨,如果我真的想要修改字符串该怎么办?1:把常量字符串转换为数组。2:使用动态内存分配。作为练习,你可以基于现有的知识,尝试按自己的思路去实现方法1。当然,这些知识在后续的教程中也会一一道来

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180225A106TZ00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券