目录
实际上,c语言本身并没有任何字符串类型,字符串通常放在常量字符串中或者字符串数组中,一个不可修改,一个可修改。
对于字符串函数,有些常见的函数,之前也见过,下面会写一些这些函数的自定义。
一、strlen
字符串以'\0'作为结束标志,strlen函数返回的是在字符串中'\0'前面出现的字符个数(不包含'\0')。
参数指向的字符串必须要以'\0'结束。
注意函数的返回值为size_t,是无符号的。
模拟实现。
size_t strlen (const char* str)
这是函数自己的定义,现在要自定义函数
#include <stdio.h>
#include <assert.h>
int my_strlen(const char* str)
{
int count = 0;
assert(str != NULL);
while (*str != '\0')
{
count++;
str++;
}
return count;
}
int main()
{
if (my_strlen("abc") - my_strlen("abcdef") > 0)
{
printf("hehe\n");
}
else
{
printf("haha\n");
}
return 0;
}
现在把这个函数返回类型定为int,那么main函数体内进行比较时,小的减大的,结果是负数,会打印相应的字符串。而如果按照标准定义去做,size_t,其实就是无符号整数类型,那么就会一直大于0。但是这并不说明标准定义有问题,因为一个大小肯定会大于0,所以为了会定义成无符号整型。这是计数器的方法,还有递归算法。
if (*str != '\0')
1 + my_strlen(str + 1);
else
return 0;
二、strcpy
源字符串必须以'\0'结束。
会将源字符串中的'\0'拷贝到目标空间
目标空间必须足够大,以确保能存放源字符串
目标空间必须可变
模拟实现。
char* strcpy(char* destination, const char* source)
两个字符拷贝,会把\0带过去。模拟实现做到这个是重点。
char* my_strcpy(char* dest, const char* src)
{
assert(dest != NULL);
assert(src != NULL);
char* ret = dest;
//拷贝src指向的字符串到dest指向的空间,包含\0
while (*dest++ = *src++)
{
;
}
//返回目的地的空间的起始地址
return ret;
}
int main()
{
char arr1[] = "abcdefghi";
char arr2[] = "bit";
int sz = sizeof(arr2) / sizeof(arr2[0]);
my_strcpy(arr1, arr2);
return 0;
}
不能写一个指针指向的字符串,因为那样就变成了常量字符串。
三、strcat
源字符串必须以'\0'结束。
目标空间必须足够大,以容纳下源字符串的内容
目标空间必须可变
字符串不能给自己追加
char* strcat(char* strDestination, const char* strSource)
append a string
int main()
{
char arr1[20] = "hello";
char arr2[] = "world";
strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
追加时,arr2要从arr1的\0处开始追加,所以除了源字符串,目的地字符串也得有\0,比如想从e开始追加,那么he\llo,就会开始逐个替换掉,直到\0传过去,整个过程结束。
char* my_strcat(char* dest, const char* src)
{
assert(src != NULL);
assert(dest);
char* ret = dest;
while (*dest != '\0')
{
dest++;
}
while (*dest++ = *src++)
{
;
}
return ret;
}
int main()
{
char arr1[15] = "hello";
char arr2[] = "world";
my_strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
当arr1读取到\0时,这时候就相当于strcpy这个函数功能,所以后面直接加上。
结束。