Bootstrap

浅谈C语言的字符串以及相关练习的简单讲解


前言

字符串是几乎在所有编程语言中可以实现的非常重要和有用的数据类型,在C语言中字符串更是有着重要地位。接下来将围绕字符串进行简单的介绍,并且会对字符串的一些练习题进行简单的讲解。


一、字符串是什么?

字符串或串(String)是由数字、字母、下划线组成的一串字符。在C语言字符串以"\0"结尾。同时,C语言中没有string类型,在 C 语言中,字符串实际上是使用空字符 \0 结尾的一维字符数组。字符串长度就是数组中\0以前的字符个数。

字符串的表示
可以将每个字符单独存进字符数组中,也可将字符串整个存进字符数组中。

char arr[]={'a','b','c','\0'};
char[3]={"abc"};

字符串的输入输出除了使用scanf和printf外还可以使用gets和 puts两个函数;
在这里插入图片描述

二、字符串的简单练习

1.将字符串逆序

示例:输入abcefg 输出gfecba

大体思路:
观察一下abcdefg和gfecba的位置可以发现:如果将abcdefg的中第一个a和最后一个g交换,第二个b和倒数第二个f交换,第三个c和倒数第三个e交换,依此类推,按位交换即可得到字符串的逆序。字符串个数是奇数时位于中间的字符刚好不用交换,如果个数是偶数,刚好对应交换。
基于上述想法,可以用双指针的方法,一个指针指向第一个字符串,一个字指针指向最后一个字符串,然后交换元素,同时指向开头的字符串往前移动,指向结尾的指针向后移动。当交换完所有对应的元素或者只剩下中间元素时,就不用交换了。

通过上述的想法就可以写出如下代码

代码如下:

#include<stdio.h>
#include<string.h>
void reversa(char* str, int len)
{
	char*left = str;
	char* right = str + len-1;
	while (left < right)

	{
		char temp = *right;
		*right = *left;
		*left = temp;
		left++;
		right--;

	}

}
int main()
{
	char str[1000] ;
	gets(str);
	int len=strlen(str);
	reversa(str, len);
	printf("%s", str);
	return 0;



}

其实利用上述的想法还能处理两个字符串的覆盖问题
类似于多个字符从两端移动,向中间汇聚
在这里插入图片描述
利用先前的想法就可以写出如下代码,换一种写法就不用双指针了。直接利用数组下标索引来访问

#include<string.h>
#include <stdio.h>
int main()
{
    char str1[] = { "hello" };
    char str2[] = { "*****" };
    int left = 0;
    int right = strlen(str1) - 1;
    while (left <= right)
    {
        str2[left] = str1[left];
        str2[right] = str1[right];
        left++;
        right--;
        printf("%s\n", str2);
    }
}

2.倒置单词

题目要求:输入I like you. 输出you. like I

对于这种题目可以先观察输入和输出的联系。之间是如何转化的。
大体思路:如果将每次单词逆序就会得到 I ekil .ouy 如果将字符串整个逆序就会得到you. like I.找到转化方法后就可以这样思考。第一步先将每个单词逆序,空格不用处理保持原来的位置即可因为空格无论怎么变都不影响输出格式,第二步将整个字符串逆序即可。也可以将第一步和第二步互换,结果也是一样的。

于是基于上述思路结合先前写的逆序函数就可以写出如下代码:

代码如下(示例):

#include<stdio.h>
#include<string.h>
void reverse(char* left, char* right)
{
    while (left < right)
    {
        char temp = *left;
        *left = *right;
        *right = temp;
        left++;
        right--;
    }

}
int main()
{
    char str[101] = { "0"};
    gets(str);//输入字符串
    char* start = str;
    while (*start)
    {
        char* end = start;
        //因为需要指向下一个单词,所以end需要进入下一个while
        //所以每个单词的起始位置需要重新赋值给end
        while (*end != ' ' && *end != '\0')
        {
            end++;
        }
        reverse(start, end - 1);
        if (*end != '\0')
            start = end + 1;
        else
            start = end;
    }

    int len = strlen(str);
    reverse(str, str + len - 1);//逆序整个字符串
    printf("%s\n", str);
    return 0;
}

因为空格不用管而且字符串是以\0结尾的,所以空格和\0不能进入while更新end,逻辑词是用或者还是并且可以试着带入想想是否符合要求。

三.总结

1.倒置单词的时候,我将start end同时定义在while循环外部,程序出错了,
因为end更新指向时空格时,需要跳出循环,之后的end需要再次进入第二个while中指向下一个单词结尾处的空格或者\0,如果在循环外部定义end,之后的end再也不会进入第二个while更新了,所以必须再将下个单词的起始位置start赋给end.因此在不想引入第三个变量的前提下,需要将end定义在while循环内。
2.当end每次跳出第二个循环时必须进行判断,end是因为空格跳出来的还是因为\0跳出来的,如果是空格那就end+1,start指向下一个单词的开头,如果不是空格,那就一定是\0,这个时候只用start直接等于end不用加1,因为这说明最后一个单词已经是逆序完了,直接跳出循环即可。
3.记得最后的时候一定要逆序一下整个字符串,同时字符串的输入最好是使用gets函数。
4.以上内容,如有错误欢迎指出,谢谢指教!

;