C语言数组之字符串

本文深入解析字符串的基本概念,包括定义、初始化、存储方式及注意事项。通过实例讲解如何处理字符串输入、输出,解决常见问题,如回车符干扰和字符转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近各大工作室都发布了一些与字符串有关的题目,同学们在写有关字符串的题目时候会感到吃力,或是无从下手,没有思路,或是一些基本的知识不明白。这里我就讲解下与字符串有关的基本知识

字符串,它是由多个字符组成的序列。可以想象成葡萄架上垂挂着的一串葡萄,每一粒葡萄都相当于是字符;字符串也是如此,它在存储上类似字符数组,且其单个元素都是可以提取的,这点像每一粒葡萄都可以单独取下来;

对于字符串,我们需要了解以下几点:
1:字符串的定义与如何初始化。
2:字符在数组里面如何存放的。
3:字符串的注意事项。
4: 结合到题目该如何写

我就这三点展开来说明,首先对于第一点:
1:字符串的定义与如何初始化。
上一篇博客讲了有关数组的基础知识,里面也介绍了点关于字符数组的定义与初始化:

char Str1[50]; //定义一个长度为50的字符数组
char Str2[20] = "Hydrogen"; //定义一个字符数组,并且赋初始值 Hydrogen
//char Str2[20] = {"Hydrogen"}; 和上面等价

这里需要注意两点
1:C语言中字符串都会有一个结束标志,即 ‘\0’ ,这个字符在ACSII码表中为第一个,其值为0。空字符,这是字符串中作为结束的判断标记。
当输出函数列入 puts(); printf(); 在输出数据的时候,遇到 ‘\0’ 就会结束输出。
而这个空字符 ,因为是字符,所以也会占据一个字节的空间,这就导致我们在定义数组长度的时候要考虑这个空字符。以下举例说明:

char Str[8] = "Hydrogen"; // 错误
char Str[9] = "Hydrogen"; //正确
//只考虑字母只有8个,但是由于空字符的存在,所以这里必须是9个长度

2:在你定义了一个字符数组并且为其赋值后,其后没有填上字符的元素,编译器会自动帮你加上 \0.
在这里插入图片描述
如图所示,那些未填充字符的数组元素全部都是 空 的。

str[0]str[1]str[2]str[3]str[4]str5]str[6]str[7]str[8]str[9]
Hydrogen\0\0\0

这里拓展一点关于printf()函数输出顺序的知识:有同学可能注意到了,我的 整形变量i
一开始是从0开始的,而这里输出的确是从1开始的,这是为啥呢? 原因是在printf();函数中,数据输出是从右往左的
所以在这里首先执行的是 i++, 自增1后在输出i,也就是从1开始了。

2:字符在数组里面如何存放的。
结合上面那张图片,可以注意到一个数组元素存放着一个字符,也就是说,字符在数组里面存放是一个一个存放的;字符包是表示数据和信息的字母、数字或其他符号。
A,B,C,a,b,c是字符,1, 2, 3 也是字符 , . / ? ! = - * & ( ) 同样也是字符
空格也是一个字符,也可以存放进数组里面
这里直观的演示下一个字符串的输出和每一个字符对应的ACSII码的程序:
在这里插入图片描述
可以注意到,一个空格对应的ACSII码是 32.
还可以注意到,当我用%d输出一个字符的时候,得到的结果是它的ASCII码。

3:字符串的注意事项。

① 输入字符串有多种方式,上一篇博客中讲到了那几点。这里再强调一下,字符串若是有空格的输入,那么不能选择scanf()函数来进行。
② 要小心回车的存在,这个可能会使一段逻辑语法都没错的代码无法运行出正确的结果。下面用一个例子来说明:
我想分别输入两个字符H 和 2, 并且输入一次回车一次:
结果确实
在这里插入图片描述
观察运行结果可以知道,c2的值对应的ASCII码的值是10,这个换行符在ASCII码表中对应的字符是一模一样的。
也就是说,在我输入数据的时候,H 回车 就结束了,c2获取的值是回车的值,而这个回车是我们原本就不需要的,这时候咋办呢?就可以借助 fflush(stdin);
在这里插入图片描述
如何解释这种奇怪的结果呢? 结合第一篇博客所讲的内容,缓冲区和scanf()函数读取数据的知识就可以解释了,输入数据回车后,回车遗留在了缓冲区内,等待下一个scanf()函数调用,即把回车这个ASCII码赋给了c2。 所以这里只需要清空下缓冲区即可。
另一个可以解决这种问题的方法是在第一个scanf()函数后面加一个getchar(); 该函数也会从缓冲区读取一个字符,这里将回车给读取掉了。
输入数据的时候:

缓冲区:H\n
调用一次scanf函数读取

scanf首先读走了H,此时缓冲区:

缓冲区:\nNULL
调用一次scanf函数读取

下一次调用scanf();函数的时候,\n 就给了c2。

若加了fflush(stdin);后,在输入H回车 完毕后,
缓冲区就空掉了:

缓冲区:NULLNULL
调用一次scanf函数读取

在这里插入图片描述


4: 结合到题目该如何写
例一:
输入两串字符串:10 20 要求输出它们相加的结果 30
如果直接让他们对应的个位十位相加得出结果会是怎样的呢?
答案肯定是不正确的,代码和结果如下:

这里为什么是1086呢?
这是因为,直接让字符相加,他们的结果是对应字符的ASCII码进行相加,

字符012
ASCII484950

所以(49+50) * 10 + 96 = 1086
知道了计算法则是对应元素的ASCII码相加后,那就好办了:
我们只需要让该字符减去某一个数字,让它相加的时候就是以该数字本身相加即可。
观察上面的表格,不二之选就是减去’0’啦,注意这里是减去字符0,或者减去0本身对应的ASCII码。二者一样。

字符-480-481-482-48
ASCII012

这样更改后:

就可以运行出我们想要的结果了。
例2:
给定一个字符串,判断其是否为回文字符串
从最简单的一串回文串进行分析:ABCCBA
假如我们人眼进行判断,要么从外向内一一比较:AABBCC
要么从内向外CCBBAA。
只要是有一个不符合的,则就不是回文串。那思路就很明显了:
从字符串的两侧进行一一比较,若找到一对不相等的字符,则输出否。
全部比较完毕后,还没有找到不相等的,则就是回文的。
并且比较的次数是字符串长度的一半。
在这里插入图片描述
其他测试结果:在这里插入图片描述


其他需要用到字符串的题目,也是如此,先分析题目,在结合与字符串有关的知识进行解答,合理的运用循环,判断等语法知识就可以了。
最后说一点,字符串里面重要的一个字符是结束符(空字符),它决定了字符串在哪里结束,有些时候我们需要自己设置结束符,或者在某些题目里面,比如两个字符元素的两两交换,就有可能会改变空字符的位置,从而导致一些无法预知的bug出现。
若遇到这种情况,我们大可用printf() + 循环结构,来输出此时数组内部元素的情况,以此来更好的找出bug,解决bug。
(如有错误欢迎指出)

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C01acat

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值