代码位置:test-c-2024: 对C语言习题代码的练习 (gitee.com)
一、前言:
如果对这些函数不太了解可看我上一篇博客,上一篇博客我们介绍了这些函数的功能及性质这次我们的目的是自我实现这些函数。
常见的字符串和内存函数有:
1、求字符串长度:
1.1-strlen
2、长度不受限制的字符串函数:
1.2-strcpy
1.3-strcat
1.4-strcmp
3、长度受限制的字符串函数:
1.5-strncpy
1.6-strncat
1.7-strncmp
4、字符串查找:
1.8-strstr
1.9-strtok
5、错误信息报告:
1.10-strerror
6、内存操作函数:
1.11-memcpy
1.12-memmove
1.13-memset
1.14-memcmp
二、函数的自我实现:
1.1-my_strlen:
size_t my_strlen ( const char * str );
功能:
该函数的功能是得到一个字符串的长度。
代码:
//strlen 是求字符串长度的,求出的长度是不可能为负数的
//所以返回类型设置为size_t 也是合情合理的
size_t my_strlen(const char* str)
{
assert(str);
size_t size=0;
while (*str)
{
size++;
str++;
}
return size;
}
效果:
1.2-my_strcpy:
char* my_strcpy(char * str1, const char * str2 );
功能:
该函数为字符串拷贝函数,功能是将字符串str2中元素拷贝到字符串str1中。
代码:
char* my_strcpy(char* str1, const char* str2)
{
assert(str1);
assert(str2);
char* head = str1;
while (*str2)
{
*str1 = *str2;
str1++;
str2++;
}
*str1 = *str2; //将'\0'赋值给str1
return head;
}
效果:
1.3-my_strcat:
char * my_strcat ( char * str1, const char * str2 );
功能:
该函数实现的功能是将str2的内容追加到str1后。
代码:
char* my_strcat(char* str1, const char* str2)
{
assert(str1);
assert(str2);
char* head = str1;
while (*str1)
{
str1++;
}
while (*str2)
{
*str1 = *str2;
str1++;
str2++;
}
return head;
}
效果:
1.4-my_strcmp:
int my_strcmp ( const char * str1, const char * str2 );
功能:
用于比较字符串的大小,这里比较的是字符串第一个字符的ASCLL码值的大小,若相同则比较下一个字符。
标准规定:
第一个字符串大于第二个字符串,则返回大于 0 的数字
第一个字符串等于第二个字符串,则返回 0
第一个字符串小于第二个字符串,则返回小于 0 的数字
代码:
int my_strcmp(const char* str1, const char* str2)
{
assert(str1);
assert(str2);
while (*str1 || *str2)
{
if (*str1 > *str2)
{
return 1;
}
if (*str1 < *str2)
{
return -1;
}
str1++;
str2++;
}
return 0;
}
效果:
1.5-my_strncpy:
char * my_strncpy ( char * str1, const char * str2, size_t num );
功能:
将str2中num个元素个数拷贝到str1上。如果字符串str2的长度小于num,则拷贝完字符串str2之后,在目标的后边追加 0 ,直到 num 个。
代码:
char* my_strncpy(char* str1, const char* str2, size_t num)
{
assert(str1);
assert(str2);
char* head = str1;
while (num--)
{
*str1++ = *str2++;
if (*str2 == '\0')
break;
}
//判断字符串str2的长度是否小于num
if (num == -1)
{
return head;
}
//若字符串str2的长度小于num,则拷贝完字符串str2之后。
//在目标的后边追加 0 ,直到 num 个。
while (num--)
{
*str1++ = '\0';
}
return head;
}
效果:
1.6-my_strncat :
char * my_strncat ( char * str1, const char * str2, size_t num );
功能:
将字符串str2中的num个元素追加到str1后。
代码:
char* my_strncat(char* str1, const char* str2, size_t num)
{
assert(str1);
assert(str2);
char* head = str1;
while (*str1)
{
str1++;
}
while (num--)
{
*str1++ = *str2++;
}
return head;
}
效果:
1.7-my_strncmp:
int my_strncmp ( const char * str1, const char * str2, size_t num );
功能:
比较str1和str2中num个字符的大小,这里比较的是字符串第一个字符的ASCLL码值的大小,若相同则比较下一个字符。
代码:
int my_strncmp(const char* str1, const char* str2, size_t num)
{
assert(str1);
assert(str2);
while ((*str1 || *str2) && num--)
{
if (*str1 > *str2)
{
return 1;
}
if (*str1 < *str2)
{
return -1;
}
str1++;
str2++;
}
return 0;
}
效果:
1.8-my_strstr :
char * my_strstr ( const char *str1, const char * str2);
功能:
strstr() 函数搜索字符串str2在字符串str1中的第一次出现的位置。找到所搜索的字符串,则该函数返回第一次匹配的字符串的地址,如果未找到所搜索的字符串,则返回NULL。
代码:
char* my_strstr(const char* str1, const char* str2)
{
assert(str1);
assert(str2);
char* cur = str1;
char* head = str2;
while (*str1)
{
//判断首字符是否相等
if (*cur==*str2)
{
//遍历一遍str2若到结束时与字符串cur存在不相等时
//则需将str2重新归回字符串str2首位置便于下一次判断
while (*str2)
{
if (*str2 == *cur)
{
str2++;
cur++;
}
else
{
str2 = head;
break;
}
}
//若遍历str2一遍后str2没有归回字符串str2首位置
//则说明此时的str1的位置为字符串str2在字符串str1中的第一次出现的位置
if (str2 != head)
{
return str1;
}
}
//本次循环没有出现str2时cur指向str1下一个位置str1+1.
cur = ++str1;
}
return NULL;
}
效果:
1.11-my_memcpy:
void * my_memcpy ( void * str1, const void * str2, size_t num );
功能:
函数memcpy从str2的位置开始向后复制num个字节的数据到str1的内存位置。
代码:
void* my_memcpy(void* str1, const void* str2, size_t num)
{
assert(str1);
assert(str2);
void* head = str1;
while (num--)
{
*(char*)str1 = *(char*)str2;
str1 = (char*)str1 + 1;
str2 = (char*)str2 + 1;
}
return head;
}
效果:
注:这里整型为4个字节num为13时拷贝到str1的数为1,2,3,4因为我这里是小端存储,此时4存在的是整型4个字节中的第一个字节
1.12-my_memmove:
void * my_memmove ( void * str1, const void * str2, size_t num );
功能:
函数memmove从str2的位置开始向后复制num个字节的数据到str1的内存位置。
代码:
void* my_memmove(void* str1, const void* str2, size_t num)
{
assert(str1);
assert(str2);
void* ret = str1;
if (str1 < str2)
{
//前-->后
while (num--)
{
*(char*)str1 = *(char*)str2;
str1 = (char*)str1 + 1;
str2 = (char*)str2 + 1;
}
}
else
{
//后->前
while (num--)
{
*((char*)str1 + num) = *((char*)str2 + num);
}
}
return ret;
}
效果:
1.14-my_memcmp:
int my_memcmp ( const void * str1, const void * str2, size_t num );
功能:
比较从str1和str2指针开始的num个字节
代码:
int my_memcmp(const void* str1, const void* str2, size_t num)
{
assert(str1);
assert(str2);
char* cur1 = (char*)str1;
char* cur2 = (char*)str2;
while (num--)
{
if (*cur1 > *cur2)
{
return 1;
}
if (*cur1 < *cur2)
{
return -1;
}
str1 = (char*)str1 + 1;
str2 = (char*)str2 + 1;
cur1 = (char*)str1;
cur2 = (char*)str2;
return 0;
}
}
效果:
三、结语:
上述内容,即是我个人对常见字符串+内存函数的个人见解以及自我实现。若有大佬发现哪里有问题可以私信或评论指教一下我这个小萌新。非常感谢各位友友们的点赞,关注,收藏与支持,我会更加努力的学习编程语言,还望各位多多关照,让我们一起进步吧!