大家晚上好呀!哦不,这篇文章写好应该是凌晨了,所以,大家凌晨好呀!!!
这几天早八到晚十都在打寒假工,回家做完家务洗澡基本11点。啦啦啦,终于有时间做自己热爱的事情咯。
分享之前和大家分享一下一位非常喜欢的小说家海明威的句子:
生活总是让我们遍体鳞伤,但到后来,那些受伤的地方一定会变成我们最强壮的地方。
——海明威
今天想要和大家分享的知识点是C语言里面的字符串。一提起字符串,大家脑海里浮现出来形如“helloworld”,“Goodbye”等等之类的,没错这是字符串,但是一说起字符串,你的脑海里浮现的东西如果很少,那么下面这篇关于字符串全方位无死角的讲解一定能够让你大开眼界!相信你会有很大的收获!加油!!!
一.字符串的定义及特点:
1.字符串的定义:
串(string)也叫做字符串,它是由数字、字母、下划线组成的一串字符。如:"abcd", "hello world"等等。
代码表示:
char str_1[]={'h','e','l','l','o'}; //第一种表示形式
char str_2[]="hello"; //第二种表示形式
//以上两种大体是一样的,声明的方式是等价的,但是如果细分的话,还略有差别.
//建议使用第二种,因为第二种的写法比较方便.
2.字符串的特点:
(1).字符串是一个只读型字符型数组。ps:只读的意思就是你只能够浏览它,确认不能修改它。
(2).字符串是一种特殊类型,而且这个数组是只读的,不能够通过指针更改字符串内部数据。
(3).字符串后面默认都是以'\0'作为结束符号。
先讲解一下字符串常量以及字符数组,为下文做铺垫:
01字符串常量:虽然C 语言没有字符串类型,但是 C语言是有字符串这个概念的,也就是字符串常量:它是以 NULL 字节结尾的,并且由 0 个或多个字符组成的序列。字符串常量是不可被修改的,一般用一对双引号(" ")括起的一串字符来表示字符串常量,如:
"Hello world"、"!string/"、"123abc\n"、 ""
字符串常量可以为空,如 "" 就是一个空的字符串常量,但是即使为空,还是存在一个终止符 NULL 的。(在 C 语言中,常用转义字符 \0 来表示 NULL)
02字符数组:顾名思义,他是一个数组,数组里面存放的元素是字符,所以叫做字符数组。
在 C 语言中,除了字符串常量外,其他所有字符串都必须存储于字符数组或动态分配的内存中。定义一个字符数组和定义一个普通数组大同小异,不同的是字符数组中存放的是字符数据而已。
直接上代码帮助理解:
char str_1[]={'h','e','l','l','o'}; //第一种表示形式
char str_2[]="hello"; //第二种表示形式
#include<stdio.h>
int main()
{
char str_1[] = { 'h','e','l','l','o'}; //第一种表示形式
char str_2[] = "hello"; //第二种表示形式
char str_3[] = { 'h','e','l','l','o','\0' }; //在第一种方式后面加上一个'\0'
printf("sizeof(str_1)=%d\n", sizeof(str_1)); //计算str_1的大小
printf("strlen(str_1)=%d\n", strlen(str_1)); //计算str_1的长度
printf("sizeof(str_2)=%d\n", sizeof(str_2)); //计算str_2的大小
printf("strlen(str_2)=%d\n", strlen(str_2)); //计算str_2的长度
printf("strlen(str_3)=%d\n", strlen(str_3)); //计算str_3的长度
return 0;
}
用sizeof,strlen分别计算数组的大小和长度,运行结果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/a6b8dd0fab7290180d810491508c6bea.png)
上文说到这两种实现方式略有差别,差别如下:
(1).关于数组的大小(sizeof):第一种实现方式的算数组大小的时候末尾是不会加\0的,数组大小就是后面字符数。第二种的数组里面的元素是用双引号连接起来的,是一个字符串,然而字符串末尾是默认有'\0'的,这样一来,第二种的数组大小就为6,第一种数组大小就为5.
(2).关于数组的长度(strlen):在一个字符数组中,计算数组的长度时,当系统扫描到一个字符串末尾的'\0'时(只计算'\0'前面的字符的长度),就会停止计算。先来讲一下第二种方式,当识别到字符串末尾的'\0'时,就停止识别,"hello"长度为5,故输出5。 第一种方式,为什么会输出37呢?是这样的,字符和字符串是不同的,字符只有一个,并且是单引号括起来的,字符串是双引号括起来的,一个字符数组的最后并没有'\0'这个东西,这是和字符串不同的一个点,因为这个字符数组[]里面的长度没定义,所以计算它的长度是不唯一的,因为你不知道这个数组什么时候会遇到'\0',上面显示37,也就是说这个'\0'实在第38个位置搜索到的,这样系统就结束了,显示37。但是如果给一个字符数组末尾加一个'\0'那么长度就变为5了。
二.字符串与其它知识混合:
1.字符串常量与指针:
字符串常量与指针关系密切,因为字符串常量的值,实际上表示的是存储这些字符的内存空间的地址,更准确地说是字符串常量中第 1 个字符的地址,而不是这些字符本身。因此,在 C 语言中是不能直接进行字符串赋值的(因为没有字符串类型)。在 C 语言中,常通过声明一个指向 char 类型的指针并将其初始化为一个字符串常量的方式来访问一个字符串。
char *pstr = "Hello World!";
// 上面的语句也可以拆分成下面两句
char *pstr;
pstr = "Hello World!"; // 这句话看起来像是字符串复制,其实不是,只是涉及到指针操作
上述语句声明了一个指向 char 类型的指针,并用字符串常量中第 1 个字符的地址对该指针进行初始化。可以通过字符指针 pstr 来访问字符串常量,下面这段代码,使用字符指针遍历了字符串常量中的每一个字符
#include <stdio.h>
int main()
{
char *pstr = "Hello World!";
printf("%s\n",pstr);
while(*pstr != '\0')
{
printf("%c ",*pstr++);
}
printf("\n");
return 0;
}
输出结果如下:
Hello World!
H e l l o W o r l d !
2. 字符串常量与字符数组的区别:
(1)字符串常量内容和长度在初始化时就已经固定了,不可更改;且可以通过一个指向字符串常量第一个元素的指针来访问该字符串常量;
(2)字符数组是一个用于存放字符的数组,字符数组的值是可以更改的。
三.对字符串的各种操作:
1.获取字符串:
字符串的长度就是这个字符串所包含字符的个数,但是这个长度是不包含 NUL 字符的。C 语言中使用库函数 strlen 来计算字符串长度:
size_t strlen(char const *string); //这是strlen函数的原型
需要注意的是 strlen 的返回值类型:size_t 类型,这是一个无符号整数类型,size_t的打印格式也不是%d,而是%zu。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char str_1[] = "Hello World!";
printf("strlen(str_1)=%zu\n",strlen(str_1));
return 0;
}
//运行结果如下:
// strlen(str_1)=12
//注意:空格也算一个字符,要把空格给数进去
//注意:size_t的打印格式也不是%d,需要%zu
2.复制字符串:
C 语言中使用库函数 strcpy 来进行字符串复制操作:
char *strcpy(char *dst , char const *src);//这是strcpy函数的原型
函数 strcpy 接收两个字符串参数,并将参数 src 字符串复制到 dst 参数。使用 strcpy 函数时需要注意的是,必须保证目标字符数组 dst 的长度足够存放源字符数组 src 的内容。如果 src 比 dst 长,则 src 剩余部分的字符仍会被复制,而且它们会覆盖 dst 后面的内存空间的值,如果这除内存空间原本就存放有值,则会导致原本的数据丢失,这样会造成很严重的后果。为了解决这个问题, C 语言中提供了一种更为安全的方式来进行字符串复制操作——strncpy 函数:
char *strncpy(char *dst , char const *src , size_t len); //这是strncpy函数的原型
strncpy 函数有三个参数,与 strcpy 函数一样,它也是将 src 字符串中的字符复制到目标数组 dst 中去,但是 strncpy 函数提供的第三个参数 len 规定了可以向 dst 中写入的字符的个数:
01如果 strlen(src) > len,则只有 len 个字符被复制到 dst 中去,此时 dst 将不会以 NULL 字节结尾(也就是说,strncpy 调用的结果可能不是一个字符串);
02如果 strlen(src) < len,则 src 中的字符全被复制到 dst 中去,dst 中剩余的部分用 NULL填充。
3.连接字符串:
C 语言中使用库函数 strcat 来连接两个字符串:
char *strcat(char *dst,char const *src) //这是strcat函数的原型
函数 strcat 将参数 src 字符串连接到参数 dst 字符串的后面。与 strcpy 函数一个同样的问题是,必须保证 dst 的剩余空间足够存放下 src 整个字符串。C 语言中提供了 strncat 函数来解决这个问题:
char *strncat(char *dst , char const *src , size_t len); //这是strncat函数的原型
strncat 函数从 src 中最多复制 len 个字符到目标数组 dst 后面,并且,strncat 总是在结果字符串后面添加一个 NUL 字节,而且不会像 strncpy 函数那样对 dst 剩余的空间用 NULL进行填充。
4.字符串的比较:
C 语言中使用库函数 strcmp 来进行字符串比较。strcmp 函数会对被比较的两个字符串进行逐字符地比较,直到发现不匹配为止:最先不匹配的字符中较小的那个字符所对应的字符串即被认为小于另一个字符串;如果两者所有字符都匹配,则认为这两个字符串相等;
int strcmp(char const *s1 , char sonst *s2);//这是strcmp函数的原型
该函数的返回值如下:
1)s1 小于 s2,返回一个负值;
2)s1 等于 s2,返回 0;
3)s1 大于 s2,返回一个正值。
char *strncmp(char const *s1 , char const *s2 , size_t len);
//这是strncmp函数的原型
可以使用 strncmp 函数限定比较的字符的个数,返回值与 strcmp 一样,但是只针对前 len 个字符进行比较。
5.字符串的查找:
(1) 查找一个字符
可以使用 strchr 函数或 strrchr 函数来在一个字符串中查找一个特定的字符:
char *strchr(char const *str,int ch); // int ch 是字符的ASCII码值
char *strrchr(char const *str,int ch);
函数 strchr 在字符串 str 中查找字符 ch 第一次出现的位置,并返回一个指向该位置的指针;如果没有找到相应的字符,则返回一个 NULL 指针。函数 strrchr 在字符串中查找字符 ch 最后一次出现的位置,并返回指向该位置的指针。
(2) 查找任意几个字符:
可以使用 strpbrk 函数来查找任何一组字符第一次在字符串中出现的位置:
char *strpbrk(char const *str , char const *group);
这个函数返回一个指向字符串 str 中第一个匹配 group 中任何一个字符的字符位置,如果没有匹配到,则返回一个 NULL 指针。
(3) 查找一个子串:
可以使用 strstr 函数来在一个字符串中查找一个子串:
char *strstr(char const *str1 , char const *str2);
这个函数在 str1 中查找整个字符串 str2 第一次出现的起始位置,并返回一个指向该位置的指针;如果 str2 并没有完整的出现在 str1 中,则函数将返回一个 NULL 指针;如果 str2 是一个空字符串,则返回str1.
23:00——2:00
通过这一篇文章,相信你对字符串这个知识点收获一定巨大。现在凌晨2点,晚安!
2023.01.10
From:努力进大厂的新青年