今天我来讲一讲我对库函数<string.h>中大多函数的理解与使用。
目录
一.字符串函数
字符串函数(String processing function)也叫字符串处理函数,指的是编程语言中专门用来进行对字符串处理的函数,如C,pascal,Visual以及LotusScript中进行字符串拷贝,计算长度,字符查找等的函数。
字符串都具有的一个性质:字符串会将 '\0' 作为结束标志。
以下字符串均是<string.h>库中的函数,使用时要引头文件!!!
二.strlen函数
1.strlen的定义
strlen函数用来计算字符串的长度。
strlen函数有两个重要参数,其一是返回类型,其二是它的参数。
size_t类型可以理解为:unsigned int(无符号整型)。什么是无符号?大家可以简单的认为它的值是一个不分正负,永远大于等于0的数,若是输入负数,程序执行时会通过原反补码的计算最终将其转换为正数。
char*string作为函数的参数,是一个字符型指针,对于字符串来说,字符串本身是一个常量,一旦创建不可自己进行“修改”(重新的赋值操作),所以函数对字符串接收时,指针也得进行const修饰,以防指针被修改,大大增强代码安全性。
字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包 含 '\0' )。
参数指向的字符串必须要以 '\0' 结束。
2.strlen函数的计算方式
int main() {
char arr[] = "abcdefg";
int len=strlen(arr);
printf("%d\n", len);
return 0;
}
3.练习题
int main(){
if(strlen("abc")-strlen("abcdef)>0)
printf("abc>abcdef\n");
else
printf("abc<abcdef\n");
return 0;
}
通过代码可知,”abc"的长度为3,“abcdef"的长度为6,3-6=-3<0,所以应该输出语句:abc<abcdef。————(err)
之前说过,strlen的返回值是size_t 无符号整型,所以就算是负数代入无符号整型中也会直接转换为非负数数,无符号数——无符号数永远大于等于0。所以程序进入else并输出语句:abc>abcdef
3.自己模拟实现对库函数strlen
#include<assert.h>
int my_strlen(const char* str) {
assert(str != NULL);
int count = 0;
while (*str != '\0') {
count++;
str++;
}
return count;
}
模拟实现的库函数就是采用一个临时变量去统计指针向后的每一步,一个字符占一字节,一个char型指针每次也只会访问到1个字节,所以当指针遇到'\0'字符停止,随着也会停止统计,最后函数会返回统计此数。
assert是用来判断指针接收的安全性,若是指针接收到空指针NULL,就会提示警告!
其中对于strlen的模拟实现还有两种方法,一种为递归,一种为指针相减法。
//方法2.递归法
int my_strlen(const char* str) {
assert(str != NULL);
if (*str == '\0') {
return 0;
}
else {
return 1 + my_strlen(str + 1);
}
}
//方法3. 指针减指针法
int my_strlen(const char* str) {
char* ret = str;
while (*str != '\0') {
str++;
}
return str - ret;
}
对于这两种方法不再做过多解释。
二.strcpy函数
1. 用来拷贝字符串的函数
此函数有三个重要参数,返回值类型:char型指针;参数1:目的地字符型指针;参数2:源头字符型指针 。
该函数的基本原理就是将一个字符串(源头)的内容拷贝到另一个字符串(目的地)中,拷贝的意思就是新的内容会覆盖掉旧的内容。
char* strDestination:目的地指针,被拷贝的字符串
const char* strSource:源头指针,拷贝的字符串
使用strcpy需要注意的事项:
- 源字符串必须以 '\0' 结束。
- 会将源字符串中的 '\0' 拷贝到目标空间。
- 目标空间必须足够大,以确保能存放源字符串。
- 目标空间必须可变。
2.strcpy的使用
int main() {
char arr1[30] = "abcdef";//目的地字符串必须足够大,才能放下源头字符串的所有内容
char arr2[] = "hello!";
strcpy(arr1, arr2);
printf("arr1:%s\n", arr1);
return 0;
}
3.模拟实现strcpy
char* my_strcpy(char* dest, const char* src) {
assert(dest != NULL);
assert(src != NULL);
char* tmp = dest;
while (*dest++ = *src++) {
;
}
return tmp;
}
int main() {
char arr1[30] = "abcdef";
char arr2[] = "hello!";
my_strcpy(arr1, arr2);
printf("arr1:%s\n", arr1);
return 0;
}
模拟该函数实现的步骤:1. 通过assert判断两指针接收的安全性,且源头字符串是要进行拷贝的,绝对不可修改,需要const修饰。
2.需要一个字符型指针指向目的地字符串的开始地址,这是为了最后返回目的地起始地址而做准备!
3.因为字符串中字符众多,需要用到while循环,通过将源头的首字符解引用传给目的地的首字符解引用,两指针逐步往后遍历,最终src指针指向自身字符串的'\0'字符时,将其解引用==0,传给dest指针,所以*dest==0,条件为假,跳出循环,拷贝完成!最终返回目的地起始地址。
三.strcat函数
字符串追加函数
strcat函数基本原理与strcpy有着异曲同工之妙,也是将源头字符串的内容传给目的地,只不过这次传递不会覆盖目的地字符串原有信息,而是在原有信息后添加内容。
使用strcat函数的注意事项:
- 源字符串必须以 '\0' 结束。
- 目标空间必须有足够的大,能容纳下源字符串的内容。
- 目标空间必须可修改。
2.strcat函数使用
#include<string.h>
#include<stdio.h>
int main() {
char a1[50] = "Welcome to my ";
strcat(a1, "world!");
printf("%s\n", a1);
return 0;
}
3.模拟实现strcat函数
char* my_strcat(char* dest, const char* src) {
assert(dest && src);
char* ret = dest;
while (*dest != '\0') {
dest++;
}
while (*dest++ = *src++) {
;
}
return ret;
}
int main() {
char a1[50] = "Welcome to my ";
//strcat(a1, "world!");
//printf("%s\n", a1);//Welcome to my world!
my_strcat(a1, "home!\n");
printf("%s\n", a1);
return 0;
}
模拟实现的步骤:
1.开始还是先通过assert函数对两个指针进行断言 ,判断其安全有效性;源头字符串是要进行拷贝的,绝对不可修改,需要const修饰;且创建字符指针指向目的地起始地址。
2.先让目的地指针指向该字符串的最后位置'\0',这样不会覆盖掉自身原本的信息。之后的步骤与模拟实现strcpy函数的步骤相同,都是源头字符串对目的地字符串进行逐步字符的传递。
3.最终返回最开始指向的目的地地址。
四.strcmp函数
1.strcmp是用来对两个字符串进行比较和判断的函数
这次strcmp函数的参数虽然还是两个,但不再是源头与目的地了,而且返回类型变为int型数据。 而且两个参数不分先后顺序,只是普通字符指针。
strcmp函数判断的基本原理就是对字符串相同位置上两字符的判断,若判断相等则跳转到下一位置进行两字符的判断。
判断标准规定:
- 第一个字符串大于第二个字符串,则返回大于0的数字
- 第一个字符串等于第二个字符串,则返回0
- 第一个字符串小于第二个字符串,则返回小于0的数字
2.strcmp函数的使用
#include<string.h>
#include<stdio.h>
int main() {
char arr1[] = "abcdefs";
char arr2[] = "abcdefdefsad";
int ret=strcmp(arr1, arr2);
printf("%d\n", ret);
if (ret > 0) {
printf("arr1>arr2\n");
}
else if (ret == 0) {
printf("arr1==arr2\n");
}
else {
printf("arr1<arr2\n");
}
对arr1与arr2进行比较,两指针会从arr1与arr2的起始位置开始进行比较,通过代码可以发现,第一二三四五六位置上的字符完全相等,所以就直接跳过了;等到两指针各自指向第七个位置时,arr1的指针指向字符 's',arr2指针指向字符 'd' ,通过标准判断,第一个字符串大于第二个字符串!
注意:1.两字符串的指针是通过比较双方的ASCII码值大小进行判断,字符'd'与字符's'的ASCII码值分别为100和115,115-100=15>0,所以ret>0,字符串1大于字符串2
2.千万不要认为strcmp比较的是两字符串长度之间的差值!!!
3.strcmp 模拟实现
//模拟实现strcmp函数
int my_strcmp(const char* str, const char* ptr) {
assert(str && ptr);
while (*str == *ptr) {
if (*str == '\0') {
return 0;
}
str++;
ptr++;
}
if (*str > *ptr)
return 1;
else
return -1;
}
int main() {
char arr1[] = "abcdefs";
char arr2[] = "abcdefdefsad";
//int ret=strcmp(arr1, arr2);
int ret = my_strcmp(arr1, arr2);
printf("%d\n", ret);
if (ret > 0) {
printf("arr1>arr2\n");
}
else if (ret == 0) {
printf("arr1==arr2\n");
}
else {
printf("arr1<arr2\n");
}
模拟实现strcmp 步骤:
1.开始仍是先断言函数形参两指针的安全有效性。
2.其次开始在循环中比较两指针,通过标准规定,分为三种情况,若两指针全都遍历完各自字符串且是最终遇到'\0'字符才跳出循环,说明两字符串相等,return 0;
若途中遇到两指针相应位置上的不同字符,则开始比较两者的ASCII码值,ASCII码值大的则返回1,小的则返回-1。
好了,以上就是对字符串常用函数的介绍,大家觉得有用的话点个一键三连吧,谢谢!