目录
前言:
C语言的相关知识点的笔记均在下面的专栏链接中,欢迎订阅!
10-1字符数组与字符串
1、字符数组就是一个数组,数组的每一个元素都是一个字符
首先利用字符数组,回顾以前学过的数组的相关知识点
2、字符串就是一种特殊的字符数组,这种字符数组的最后一个元素是'\0',结束符
上面这种字符串的定义与初始化的方式是最本质的
占位符%s的含义就是,从第0个元素开始读取字符数组,直至遇到结束符'\0'
一般我们常用的字符串的定义方法是下面这种
用双引号把要输出的字符串括起来,
注意编译器遇到这种字符串的定义方法会自动转换成上面的第一种方法,也就是最后一个字符为结束符'\0'的字符数组的形式
wd后面的中括号内表示后面字符串内容的长度 可以不写,但是如果要写,就要考虑最后一个字符是'\0',也就是连上world这五个字符,一共有6个字符 那么中括号内的数字必须大于等于6
3、修改字符串的内容
如果我想把字符串中的world的字符'o'修改成字符'0'怎么办?如下
4、利用指针定义字符串
与利用字符数组定义字符串(也就是上面1,2,3点所用的方法)不同
利用指针定义字符串会把字符串放在内存的只读常量区,也就是无法对所定义的字符串进行修改
具体格式如下:
你会发现确实利用指针定义的字符串,字符串的内容无法修改,我们想把上面hhh指针的第1个元素修改成了字符'0'
结果我们运行后,发现编译器运行了半天什么也没有输出出来,并且下面的返回值非0,可见这种操作是错误的
那么利用指针定义字符串,把字符串放在内存里的只读常量区有什么作用呢?
就是当再用指针定义一个字符串时,它就会去只读常量区去找,看看是否曾经出现过类似的字符串,如果有就不用重新创建了,用原来的那个字符串就行,即进行复用 如何证明这件事呢?
先定义一个与hhh指针定义的字符串一样的字符串
然后打印hhh和hhh1的地址
我们发现是一个地址 那么其实hhh1定义的字符串并没有存在内存里,而是直接调用hhh定义过的字符串了
10-2字符串输入
下面是一般的字符串输入的方法:
为什么scanf后面括号内的str前面没有取地址符?
因为str是一个数组名,数组名本身的含义就是数组首元素的地址,既然str本身就是一个地址,自然不需要前面加取地址符了
那么我们如果用指针定义一个字符串 可以进行正确的输入输出吗
显然不行,因为利用指针定义的字符串是存储在只读常量区的 一开始我们初始化指针str=NULL,即空指针,但是人为从键盘上输入本质上就是对内存中的数据进行存储和修改,显然这样在只读常量区是不被允许的,因此会报错
下面我们回顾并且解决一下 字符串输入时,输入空格不显示空格后面的内容的问题
你看利用scanf进行字符串的输入时,如果人为输入空格,空格后面的字符串内容不显示
原因是scanf在输入字符串时,是以空格和换行符作为结束标志的,所以当你输入空格后,默认结束,后面的输入内容就不读取了
那我就想要输入有带空格的字符串怎么办?
我们之前在第四章已经讲过,现在回顾一下
法1:用fgets函数(推荐,更安全)
法2 用gets_s函数
10-3字符串输出
本节介绍三种字符串的输出方法
法1:利用printf 占位符是%s\n
法2:利用puts函数 传的参数是字符串名(即字符数组名 也就是字符数组的首元素的地址)
法3:利用指针对字符数组进行遍历
此法更加具有普适性,因为我可以利用while循环对字符串进行任何操作,包括大小写转化呀之类的,不只是仅仅局限于简单的打印输出
下面我们用几节的时间讲解一下字符串中常用的函数
10-4-1strlen 函数
strlen用于获取字符串长度 传的参数是字符串的名字
具体格式如下
注意!strlen 函数返回的是 size_t 类型,而 size_t 是一个无符号整数类型,通常用于表示数组的大小或字符串的长度。当你将 size_t 类型的值赋给 int 类型的变量时,可能会导致数据丢失,特别是在 size_t 的值大于 int 类型的最大值时。
因此需要在strlen函数的前面加上(int),强制转换strlen的返回值数据类型,然后再赋值给a,b,c
上图是利用for循环,参照a的值设置遍历的次数 也就是为了证明使用a真的获取了字符串str1的长度
经过遍历输出验证,strlen函数可以获取字符串的长度
10-4-2strcat 函数
strcat 是字符串拼接函数 str=string 字符串的意思 cat=concat 拼接连接
具体的格式如下:注意包含头文件string.h 并且记得strcat的两个参数传进去后,是把后面那一个拼接到前面那一个的后面
str1没有被修改 而str2的后面被拼接上了整个字符串str1的内容
我们如果把str1拼接到str3后面,发现不行,因为str3是指针定义的在只读常量区的字符串,无法被修改
你看代码返回值非0,说明报错了
拼接要注意字符串的中括号内的长度 不能超过这个长度
10-4-3strcpy 函数
strcpy函数用于字符串的拷贝
str=string 字符串的意思 cpy=copy 拷贝的意思
上面是正常拷贝的情况 也就是strcpy的参数1的长度大于等于参数2字符串长度 并且str3的内容还比str2的内容多
把str3的内容拷贝给str2,你会发现str2的内容和str3的内容完全相同了
下面是异常拷贝的情况
所以使用strcopy时注意,传参时:第一个字符串的长度必须要大于等于第二个字符串的长度,这样才能够保证第二个字符串拷贝过去的内容能够被第一个字符串存起来,而避免存不下的情况
下面我们来介绍一种比较奇怪的拷贝,本质上和正常拷贝是一样的,只是利用这个特殊情况介绍一下拷贝的原理
实际做题过程中不用管这两种拷贝的区别
在满足 传参时:第一个字符串的长度大于等于第二个字符串的长度的前提下
第二个字符串的内容少于第一个字符串 那么此时会发什么
你会发现str1是123
str2也变成了123
str2原来是abcdef
这中间到底发生了什么 我们通过遍历新的str2字符串来看看情况
1,2,3和'\0'都从str1拷贝过来到str2这边了,原先str2前面的abcd分别被1,2,3和'\0'替换,后面的e,f虽然没被替换,但是前面有'\0'结束符,表示整个字符串已经结束,'\0'后面的内容显示不出来,因为\0后面的内容属于字符串
长度之外的内存,本身就不允许访问,也就没办法读取了
字符串拷贝的原理就是把第二个参数所代表的字符串所有内容(包括'\0')逐个赋值给第一个参数所代表的字符串
然后再打印输出时,新的这个经过拷贝重新得到的字符串的结束符'\0'后面的内容不显示
10-4-4strcmp函数
strcmp是字符串比较函数
str=string字符串的意思 cmp=compare 比较的意思
语法就是把需要比较的两个字符串传进strcmp函数里面去
如果两个字符串的内容完全相等 则函数strcmp的返回值为0
如果两个字符串的内容不完全相同怎么比较,返回值又是什么?
比较函数的原理是把两个字符串的每一个字符进行比较,如果相等就继续比较下一个字符
如果两个字符串完全相同,那么它们的每一个元素都是相等的,最后strcmp函数返回值为0
但是在比较的过程中只要两个元素遇到不相等的情况,就比较这两个元素的ASCLL码值
比如前面比较了3个元素,第一个字符串和第一个字符串的元素都相等,然后第4个元素不同了
如果第一个字符串(也就是传的第一个参数)的第4个元素的ASCLL码值小于第二个字符串的的第4个元素的ASCLL码值,那么strcmp函数结束调用,直接返回-1
如果第一个字符串(也就是传的第一个参数)的第4个元素的ASCLL码值大于第二个字符串的的第4个元素的ASCLL码值,那么strcmp函数结束调用,直接返回1
也就是说只有被比较的两个字符串的元素相同时,才会进行下一个元素的比较,但是只要遇到不相同,那么立马比较ASCLL码值,返回1或-1
像本题str1和str3首元素就不相同了,那么比较1和a的ASCLL码值,1是49 a是97 那么strcmp直接返回-1,不进行后面的元素的比较
这个函数的用处就是对字符串进行排序,之后进行补充