基本的字符函数和内存函数
- 求子符串长度函数 strlen
- 两个字符串操作函数
- 字符串长度不受限制 strcpy strcat strcmp
- 字符串长度受限制 strncpy strncat strncmp
- 字符串查找函数 strstr strchr
- 内存操作函数 memcpy memmove memcmp
函数介绍和模拟实现
strlen
求一个字符串的长度,对字符串进行遍历,遇到'\0'就停止,以当前记录的字符串的长度为为返回值,返回一个int型数据。
模拟实现
int my_strlen(const char* str)
{
int count = 0;
while (*str)
{
count++;
str++;
}
return count;
}
const-->的意思是:该变量不可以被修改 ,防止在操作中改变原字符串的数据。
strcpy
把源字符串赋值到目标字符串中,前提是,目标字符串应该有足够大的空间来存放赋值的源字符串,防止出现数据溢出。
模拟实现
char* my_strcpy(char* str1, const char*str2)
{
char* src = str1;
while (*str2)
{
*str1 = *str2;
str1++;
str2++;
}
*str1 = '\0';
return src;
}
这种方法模拟的时候,不会把字符串结束的标志->'\0'赋值进去,所以还需要在下面再加一个对'\0'的赋值,因为while循环是先判断再执行,所以才需要最后再来一个赋值操作,可以用do while循环或者改进一下while 进行优化。
while ((*str1++ = *str2++));
do
{
*str1 = *str2;
str1++;
} while (*(++str2));
strcat
这是一只很神奇的猫,它可以把两个字符串连接起来,使源字符串的连接从目标字符串'\0'的位置开始,把目标字符串的'\0'位置覆盖掉,从而完成连接。
模拟实现
char* my_strcat(char* str1, const char* str2)
{
char* src = str1;
while (*src)
{
src++;
}
while ((*src++ = *str2++));
return str1;
}
strcmp
比较两个字符串的大小,但是这个比较的不同之处在于,他是以ascll码的形式来比较大小的,从两个字符串各自的第一个字符开始.
如果第一个字符串首字符的ascll码大于第二个字符串首字符的ascll码,则停止比较,返回1,表示第一个字符串大于第二个字符串;
如果小于,则返回-1,表示第一个字符串小于第二个字符串;如果等于,则比较各自下一个字符的大小,倘若两字符串同时到'\0'位置,则返回0,表示两字符串相等。
模拟实现
int my_strcmp(const char* str1, const char* str2)
{
while (*str1&&*str2)
{
if (*str1 > *str2)
{
return 1;
}
else if (*str1 < *str2)
{
return -1;
}
else
{
str1++;
str2++;
}
}
return 0;
}
strncpy
从源字符串中拷贝num个字符到目标空间(目标空间要足够大),如果源字符串的长度小于num,则拷贝完字符串之后,在目标字符串后面加0,知道num个为止。
函数实现
char* my_strncpy(char* a, const char* b,const size_t size)
{
size_t i = 0;
for (i = 0; i < size; i++)
{
a[i] = b[i];
}
return a;
}
strncat
把源字符串中前num个字符从目标字符串'\0位置开始拷贝到目标字符串后面。
函数实现
char* my_strncat(char* str1, const char* str2, const size_t num)
{
char* src = str1;
while (*str1)
{
str1++;
}
for (size_t i = 0; i < num; i++)
{
*(str1 + i) = *(str2 + i);
}
return src;
}
strncmp
从源字符串和目标字符串的首字符开始,最大比较num个字符,来判断两字符串的大小。
函数实现
int my_strncmp(const char* str1, const char* str2, const size_t num)
{
size_t i = 0;
for (i = 0; i < num; i++)
{
if (*(str1 + i) > *(str2 + i))
{
return 1;
}
else if (*(str1 + i) < *(str2 + i))
{
return -1;
}
}
return 0;
}
strstr
找到源字符串在目标字符串中第一次出现的位置,并返回这个位置,如果没有找到,则返回NULL。
模拟实现
char* my_strstr(const char* str1, const char* str2)
{
const char* src = str1;
const char* sub = str2;
const char* stact = str1;
while (*src)
{
if (*src == *sub)
{
src++;
sub++;
}
else
{
sub = str2;
src = ++stact;
}
if (*sub == '\0')
{
return stact;
}
}
return NULL;
}
strchr
找到源字符在目标字符串中第一次出现的位置,并返回这个位置,如果没有找到,则返回NULL。
模拟实现
char* my_strchr(const char* str1, const char str2)
{
const char* src = str1;
const char sub = str2;
while (*src != sub)
{
src++;
}
return src;//如果没有找到源字符,此时src指向'\0'-->NULL
}
memcpy
从源字符串的首字符开始,拷贝num个字符到目标字符串的后面,和strcpy的区别在于,memcpy在遇到'\0'不会停止,但是他的拷贝遇到源字符串和目标字符串有重叠的地方时,拷贝可能就会出问题,会使结果无意义。
模拟实现
void* my_memcpy(void* str1, const void* str2, int size)
{
int i = 0;
void* src = str1;
while (size--)
{
*(char*)str1 = *(char*)str2 ;
(char*)str1++;
(char*)str2++;
}
return src;
}
memmove
作用等同于memmcat,不同之处在于解决了内存覆盖的问题。
模拟实现
void* my_memmove(void* str1, const void* str2, int size)
{
void* src = str1;
if ((str1<=str2)||((char*)str1 >= ((char*)str2+size)))
{
int i = 0;
for (i = 0; i < size; i++)
{
*((char*)str1 + i) = *((char*)str2 + i);
}
}
else
{
while (size--)
{
*((char*)str1 + size) = *((char*)str2 + size);
}
}
return src;
}
memcmp
和strncmp作用相同,比较从两个字符串的首字符开始的num个字符。
函数实现
int my_memcmp(const char* str1, const char* str2, const size_t num)
{
size_t i = 0;
for (i = 0; i < num; i++)
{
if (*(str1 + i) > *(str2 + i))
{
return 1;
}
else if (*(str1 + i) < *(str2 + i))
{
return -1;
}
}
return 0;
}