前言:
字符串在C语言中比较特别,没有单另的字符串类型,想要初始化字符串必须用字符变量的数组初始化,但是在C语言标准库函数中提供了大量能对字符串进行修改的函数,比如说可以实现字符串的的拷贝,字符串的追加,字符串的替换等等。
接下来就一起来学习这些功能,并且能够模拟实现以下这些函数的功能。
strlen函数
介绍并且使用:
简单了来说就是可以得到字符串的长度的函数,注意事项:
1、字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包 含 '\0' )。
2、参数指向的字符串必须要以 '\0' 结束。
3、注意函数的返回值为size_t,是无符号的( 易错 )。
#include<stdio.h>
#include<stdlib.h>
int main()
{
char arr[] = { "abcdefg" };
printf("%u\n", strlen(arr));//因为strlen返回值是一个无符号整型,我们可以用%u打印
return 0;
}
很容易计算出结果是7,也就是这个字符串中有7个字符。
模拟实现strlen函数
我们可以自己编写自己的strlen函数,只需要返回一个整型,然后即可,接下来用三种方式模拟实现strlen函数。
方法一:while循环
代码如下:
int my_strlen(char *arr)
{
int num = 0;
while (1)
{
if (*arr == '\0')
{
break;
}
arr++;
num++;
}
return num;
}
int main()
{
char arr[] = { "abcdefg" };
printf("%d\n",my_strlen(arr));
return 0;
}
方法二:递归
int my_strlen(char* arr)
{
if (*arr == '\0')
{
return 0;
}
else
{
return 1 + my_strlen(arr + 1);
}
}
int main()
{
char arr[] = { "abcdefg" };
printf("%d\n",my_strlen(arr));
return 0;
}
方式三:指针
//指针-指针的方式
int my_strlen(char *s)
{
char *p = s;
while(*p != ‘\0’ )
p++;
return p-s;
}
int main()
{
char arr[] = { "abcdefg" };
printf("%d\n",my_strlen(arr));
return 0;
}
strcpy函数
介绍并使用:
可以进行字符串的拷贝。从源头拷贝到目的地。
注意事项:
1、源字符串必须以 '\0' 结束。
2、会将源字符串中的 '\0' 拷贝到目标空间。
3、目标空间必须足够大,以确保能存放源字符串。
4、目标空间必须可变。
int main()
{
char arr1[] = {"abcde"};
char arr2[20] = {0};
strcpy(arr2,arr1);
printf("%s\n", arr2);
return 0;
}
模拟实现strcpy函数
这里需要强调几点:
1、由于是将一个数组的字符串传到另一个字符串中,所以这两个字符串里面应该都有位置,也就是传过去的地址不能是空值(NULL)
所以用assret断言一下,如果是空值,电脑会进行报错。
2、因为传进去的时候,也要将'\0'传进去所以当判断是'\0'的时候应该要跳出循环,在跳出之前最后将'\0'传进去。
根据注意事项,即可对strcpy函数进行模拟,返回类型为char*。代码如下:
#include<assert.h>
char* my_strcpy(char* arr2, const char* arr1)
{
assert(arr1 !=NULL);
assert(arr2 != NULL);
char* arr = arr2;
while (1)
{
if (*arr1 == '\0')
{
*arr2 = *arr1;
break;
}
*arr2 = *arr1;
arr1++;
arr2++;
}
return arr;
}
int main()
{
char arr1[] = {"abcde"};
char arr2[20] = {0};
my_strcpy(arr2, arr1);
printf("%s\n",arr2 );
return 0;
}
当然这里可以对代码进行升级,升级如下:
#include<assert.h>
char* my_strcpy(char* arr2, const char* arr1)
{
assert(arr1 !=NULL);
assert(arr2 != NULL);
char* arr = arr2;
while (*arr2++ = *arr1++)
{
;
}
*arr2 = *arr1;
return arr;
}
int main()
{
char arr1[] = {"abcde"};
char arr2[20] = {0};
my_strcpy(arr2, arr1);
printf("%s\n",arr2 );
return 0;
}
strcat函数
介绍并使用:
该函数可以对字符串进行追加(连接)
例如:
int main()
{
char arr1[20] = {"abcd"};
char arr2[] = {"efgh"};
strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
效果如下:
注意事项:
1、源字符串必须以 '\0' 结束。
2、目标空间必须有足够的大,能容纳下源字符串的内容。
3、目标空间必须可修改。
模拟实现strcat函数
这里首先根据正常逻辑分析并my_strcat
char* my_strcat(char*arr1,const char* arr2)
{
assert(arr1 != NULL);
assert(arr2 != NULL);
char* arr = arr1;
while (1)
{
if (*arr1 == '\0')
{
while (1)
{
*arr1 = *arr2;
arr1++;
arr2++;
if (*arr2 == 0)
{
*arr1 = *arr2;
break;
}
}
break;
}
arr1++;
}
return arr;
}
int main()
{
char arr1[20] = { "abcd" };
char arr2[] = {"efgh"};
//my_strcat(arr1, arr2);
printf("%s\n", my_strcat(arr1, arr2));
return 0;
}
可以进行一次改进:(减少if语句)
char* my_strcat(char*arr1,const char* arr2)
{
assert(arr1 != NULL);
assert(arr2 != NULL);
char* arr = arr1;
while (*arr1)
{
arr1++;
}
while (1)
{
*arr1 = *arr2;
if (*arr2 == 0)
{
*arr1 = *arr2;
break;
}
arr1++;
arr2++;
}
return arr;
}
int main()
{
char arr1[20] = { "abcd" };
char arr2[] = {"efgh"};
//my_strcat(arr1, arr2);
printf("%s\n", my_strcat(arr1, arr2));
return 0;
}
可以进行第三次改进:
char* my_strcat(char* arr1, const char* arr2)
{
assert(arr1 != NULL);
assert(arr2 != NULL);
char* arr = arr1;
while (*arr1)
{
arr1++;
}
while (*arr1++ = *arr2++)//先赋值后++
{
;
}
return arr;
}
int main()
{
char arr1[20] = { "abcd" };
char arr2[] = { "efgh" };
//my_strcat(arr1, arr2);
printf("%s\n", my_strcat(arr1, arr2));
return 0;
}
strcmp函数
介绍并使用:
这个函数可以实现比较两个字符串:
比较的是两个字符串的ASCALL码值,从第一个字符开始比较,返回值是这样的:
当 str1大于str2的时候,返回>0的数
当str1小于str2的时候,返回<0的数
当str1等于str2的时候,返回 = 0的数
使用代码如下:
int main()
{
char arr1[] = {"abcdf"};
char arr2[] = {"abct"};
if (strcmp(arr1, arr2) == 0)
{
printf("=");
}
else if(strcmp(arr1, arr2)>0)
{
printf(">");
}
else
{
printf("<");
}
return 0;
}
模拟实现strcmp函数
初步模拟:
int my_strcmp(const char* arr1, const char* arr2)
{
assert(arr1 != NULL);
assert(arr2 != NULL);
while (1)
{
if (*arr1 > *arr2)
{
return 1;
}
else if(*arr2 > *arr1)
{
return -1;
}
else if (*arr2 == '\0' && *arr1 == '\0')
{
return 0;
}
arr1++;
arr2++;
}
}
int main()
{
char arr1[] = {"abcdef"};
char arr2[] = {"abcdfk"};
int c = 0;
c = my_strcmp(arr1,arr2);
if (c > 0)
{
printf(">");
}
else if (c < 0)
{
printf("<");
}
else
printf("=");
return 0;
}
二次修改:
可以自己分析一下,while函数。
int my_strcmp(const char* src, const char* dst)
{
int ret = 0;
assert(src != NULL);
assert(dst != NULL);
while (!(ret = *(unsigned char*)src - *(unsigned char*)dst) && *dst)
{
src++;
dst++;
}
if (ret < 0)
ret = -1;
else if (ret > 0)
ret = 1;
return ret;
}
int main()
{
char arr1[] = {"abcdef"};
char arr2[] = {"abcdefo"};
int c = 0;
c = my_strcmp(arr1,arr2);
if (c > 0)
{
printf(">");
}
else if (c < 0)
{
printf("<");
}
else
printf("=");
return 0;
}