字符串
首先,先说什么是字符串。简而言之就是双引号引起的一串字符被称为字符串。
它的结束标志是\0,具体什么意思呢,我们后面会具体说到。
上节我们知道,c语言给我们提供了很多数据类型,其中包括整型,浮点型,字符型等等一系列的类型
但是c语言并没有给我们提供字符串类型的变量,那这样我们该如何创建呢?
首先,字符串是由一系列字符组成的,但我们只可以创建字符类型的变量,那么怎么成为很多个字符变量在一起呢?
数组,对数组,数组可以把相同类型的变量存放到一起。只要我们把很多char既字符类型的变量放到一起便可以构成字符串了。
形式如下:
char arr1[]="abcde";
它的意思是把"abcde"这一个字符串存放到arr1数组中。
这样我们就成功创建并初始化了一个字符串。
与此同时,它还有另外一种初始化的方法。
char arr2[]={'a','b','c','d','e'};
那它的意思是不是把"abcde"存放到arr2中呢?
我们接下来输出它们:
char arr1[] = "abcde";
char arr2[] = { 'a','b','c','d','e' };
printf("%s\n", arr1);
printf("%s\n", arr2);
输出结果如下:
很明显,arr1符合我们的才想,但arr2好像出了点问题,这是为什么呢?
大家还记得我刚开始说的\0是字符串的结束标志吗,其实问题就出在这里了。
原来,我们创建arr1时我们是以一个字符串形式传进去的,编译器会自动在末尾加上\0
但是arr2是一个字符一个字符的传入,最后并没有结束标志,既然没有了结束标志,那字符串就会一直往后读取,后面的是什么我们也不知道,于是就会出现了“烫烫”这一列的乱码,至于最后为什么停下来了,是因为往后读取的时候随机遇到了\0,所以停下来了。
所以arr2应该怎样改进呢,很简单,就是加上\0,如下:
char arr2[]={'a','b','c','d','e','\0'};
改进之后我们再运行:
结果一样,完美解决!
以上就是字符串的两种常见的创建及初始化的方式。
小拓展:一个汉字占两个字符。
strlen库函数(string库函数)
既然\0是结束标志,那么它算不算是字符串中的一个字符呢?
先来说strlen,strlen是用来计算字符串的长度,注意只能是字符串。
那我们来测试一下吧:
在使用之前,我们得先调用相应的库函数
#include<string.h>
char arr1[] = { 'a','b','c','d','e','\0' };
printf("%d", strlen(arr1));
运行结果如下:
结果是5,然而我们已经有5个字符abcde了,说明\0并没有算入其中
也就是说strlen只能计算字符串中\0之前的长度
当然,我们在这里还可以用这个函数来验证一下上面那个arr2的长度是不是一个随机值。
代码如下:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abcde";
char arr2[] = { 'a','b','c','d','e'};
printf("%d\n", strlen(arr1));
printf("%d\n", strlen(arr2));
return 0;
}
此时我们没有给arr2加\0。
输出结果如下:
怎么样,arr2是不是个随机值,你们可以在各自电脑上尝试一下,第二个数字都不会一样的。
当我们加上\0时
char arr2[] = { 'a','b','c','d','e','\0'};
至此也验证了我们的思想是正确的。
小结:
字符串是被双引号引起来的一系列字符,c语言中没有字符串类型,必须用
字符数组(如:char a[]={‘0’};)来创建和初始化
strlen函数是用来计算字符串的长度的(字符串),计算时,\0不计入其内。
转义字符
顾名思义,就是把一个字符的意思改变了,转变成了别的意思,下面给大家介绍并解释一些常见的转义字符的用法。
/n
/n是换行的意思,即将鼠标光标移到下一行。
有的同学可能注意到前面我输出arr1和arr2是,在%s后面加了个\n,其实这个\n就是一个转义字符,意为换行的意思,所以你会看到arr1和arr2的内容分别在一行。而不是在一列。
\b表示退格符,将鼠标光标向前移动一个字符。
\a电脑发出一声蜂鸣声
\f换页
\t水平制表符,就相当于按一下键盘上的Tab键,占8个空格,每个电脑可能占得格数不一样。
\v垂直制表符
\\防转义(防止\被转义成一个转义字符)
如果不太理解,我们看接下来的例子
比如你要输出
c:\test\test.c
我们写
printf("c:\test\test.c");
我们看输出结果是否符合我们的猜想:
很遗憾,程序并没有达到我们想要的效果,这是为什么呢?仔细一看,原来\t消失了,再一想,\t不是一个转义字符吗,加上上图的那些空格,我们可以确定:
\t被转义了,转成水平制表符了,所以会有空格。
但我们就要输出c:\test\test.c,有什么办法呢?
我们只需要在\t前面再加一个\,意思是不让\t转义成别的意思,所以代码改进如下:
printf("c:\\test\\test.c");
输出结果如下:
这样就达到我们预期的效果啦。
同样其实你可以举一反三的完成下面的问题
比如你就要单纯的输出一个'
你这样写:
printf("%c",''');
我们输出一下:
程序又报错了。
这是怎么一回事呢,其实程序在执行时,第一个'和第二个'会结合在一起,会留下了第三个',此时当然不符合c语言语法了,所以我们为了避免这种情况发生,可以在第二个就是你想输入的那个符号前面加个\,就是转变它原来的意思,不再是原来 ' 的意思,所以他就不会和第一个 ' 再结合了
改进如下:
printf("%c", '\'');
此时我们运行:
成功输出了!达到我们预期的效果啦。
输出单个"也是同样的道理。
下面来到了一个很重要的转义了
\ddd与\xdd
\ddd
ddd表示1~3个八进制数字,如\130
那它具体是什么作用呢?
我们接下来看下面的代码:
printf("%c\n",'\130');
输出结果会是什么呢?
130?130的十进制?
结果如下:
结果是X!???可能会有人说数字怎么会成为了字母,你这程序有问题啊!
其实呢 是代表它的十进制的ASCII码值。
比如我们把130转化为十进制,就是8^0*0+8^1*3+^2*1=88,后面我会专门出一节精讲进制转化之类的问题的
八进制的130转化为十进制是88,可以发现88对应的ASCII码值正好是X,这也就符合了我刚才说的了。
结论:/130的意思是把130这个八进制数字转化成10机制数字后的88,作为ASCII码值代表的字符
/xdd,dd表示两个16进制数字
例如:
printf("c",'\x31');
这会也是同样的道理,先把16进制的31转化成十进制,既1*16^0+3*16^1=49作为ASCII值,所代表的字符是‘1’;下面看输出结果:
结果对了!
最后,我们再来练一道题吧,一定要细心哦!
printf("%d\n",strlen("c:\test\628\test.c"));
上面忘记说了,转义字符算作是一个字符,如\t,\b,\n等等都是占用1个字符,既占一个长度。
结果是多少呢?
18?13?14?
我们看结果吧
其实很大一部分人都是13,因为\t一个字符,\628也是一个字符,加起来应该是13个,为什么是14个呢?
这里我们注意了,\628它真的是3个八进制数字吗,很明显最后一个不是啊,是个8,八进制范围是0~7,所以不属于哪个八进制数字里面的了,既\62才一个字符,8被单独出来又算作是一个字符,所以总共是14个
那有的同学就会说,那好把8改成7,小于8不就行了吗?
我们再来试试:
printf("%d\n", strlen("c:\test\627\test.c"));
诶,你猜猜结果是什么?
14?13?
结果如下:
哈哈,是不是很不可思议啊,明明改成7了为什么反而报错了呢?
我们来看错误原因:
407,emm,我们把八进制的627转化成10进制,发现恰好是407,对字符来说太大?
我们回顾刚才讲的,就是把八进制的数字转化127成10进制然后转化成对应的ascii码值
ASCII值最大值才是127,它都407了肯定不行了
可能会有些已经稍微有点晕的同学说了,那\628为什么运行了,他也超过了127啊,哈哈,8不是不是八进制数字吗,所以转化的是\62,转化成10进制是50在范围之内,当然能运行了。
以上就是这次的所有内容啦,如果有任何疑问或者指导意见,欢迎私聊我或评论区留言哦!