Simule a realização de funções de manipulação de strings
Para obter detalhes sobre funções de manipulação de string, consulte o blog anterior
03-C funções de caracteres avançados e funções de string
Github endereço de download do código-fonte:
https://github.com/Kyrie-leon/C_Practice/tree/main/day7
1. Simule a realização do strcat
//1.模拟实现strcat
char * my_strcat(char *destination, const char * source)
{
//首先定义一个指针指向destination起始地址,便于操作完成后返回原始字符串的首地址
char *dest = destination;
//判断两个字符串是否为空
assert(destination != NULL);
assert(source != NULL);
//第一轮循环让destination指向\0
while (*destination)
{
destination++;
}
//第二轮循环将source内容追加给destination
while ((*destination++ = *source++))
{
;
}
//返回dest起始地址
return dest;
}
2. Simule a realização do strcmp
//2.模拟实现strcmp
int my_strcmp(const char *str1, const char *str2)
{
//判断指针合法性
assert(str1 != NULL);
assert(str2 != NULL);
//两个字符串分别从第一个字符进行比较
while ( (*str1++) && (*str2++) )
{
if (*str1 > *str2)
{
return 1;
}
else if (*str1 < *str2)
{
return -1;
}
else
{
continue;
}
}
return 0;
}
3. Simule a realização de strcpy
//3.模拟实现strcpy
char * my_strcpy(char * destination, const char *source)
{
//判断指针合法性
assert(destination!=NULL);
assert(source!=NULL);
//先定义一个指针指向destination便于复制后返回首地址
char *ret = destination;
//将第二个字符串的每个字符依次复制到destination中
while ((*destination++ = *source++))
{
;
}
return ret;
}
4. Simule a realização de strlen
4.1 Modo de contador
//4.1计数器
int my_strlen(const char *str)
{
//定义一个计数器
int count = 0;
//循环扫描字符串直到'/0'
while (*str)
{
//计数器+1,字符串指针+1
count++;
str++;
}
return count;
}
4.2 Não crie um contador de variável temporário (recursivo)
//4.2不创建临时变量计数器,采用递归的方式
int my_strlen2(const char *str)
{
if (*str == '\0')
{
return 0;
}
else
{
return 1 + my_strlen2(str + 1);
}
}
4.3 Caminho Pointer-Pointer
Idéia: O método de ponteiro duplo é usado.
Primeiro, o primeiro ponteiro aponta para o primeiro endereço da string (ou seja, o primeiro endereço da variável de string de parâmetro formal de entrada), o segundo ponteiro é usado para percorrer até o final do string e o valor do segundo ponteiro Subtrair o valor do primeiro ponteiro é o comprimento da string.
Por exemplo: assumindo a string "abcd", o endereço inicial de a é 1, o primeiro ponteiro s aponta para a e o segundo ponteiro aponta atrás de d após o final da travessia. '\ 0', ou seja, s = 1, p = 5, ps = 4, é o comprimento da corda.
Nota: Devido ao uso de ponteiros duplos, a definição de parâmetros formais não pode usar const.
Razão: O parâmetro formal const char * str é um ponteiro constante e, em seguida, uma variável de ponteiro char * p é definida . Neste momento, char * p = str está errado, porque str é um ponteiro constante, se atribuído a p é para fazer com que o tipo de p também se torne um ponteiro constante, essa abordagem está errada, o tipo não combina .
//4.3 双指针
//a.第一个指针指向字符串首地址,第二个指针遍历到字符串结束
//b.第二个指针减去第一个指针即为字符串长度
//注意:由于使用双指针,因此形参不能使用const
int my_strlen3(char *str)
{
//定义指针p用于遍历字符串
char *p = str;
//遍历字符串str
while (*p)
{
p++;
}
return p - str;
}
5. Simule a realização de strstr
A otimização de strstr pode referir-se ao seguinte algoritmo KMP do blog
//5.模拟实现strstr
const char *my_strstr(const char* str, const char* sub_str)
{
//判断指针合法性
assert(str != NULL);
assert(sub_str != NULL);
//双层循环实现字符串子串查找
//外层循环控制str起始位置,一直向后移动直到\0
while (*str)
{
//定义两个指针变量方便返回字符串起始地址
const char *p = str;
const char *q = sub_str;
//内层循环用于判断str字符串是否包含sub_str子串
while ((*p == *q)&&*p&&*q)
{
p++;
q++;
}
//如果sub_str扫描到\0说明在str中找到子串,返回str中的子串首字符的起始地址
if (*q == '\0')
{
return str;
}
str++;
}
return NULL;
}