1.strlen
strlen是获取字符串的长度以‘\0’结尾但是不包括
三种实现方法
1.计数器
int my_strlen1(char *str)
{
assert(str);
int count = 0;
while (*str)
{
str++;
count++;
}
return count;
}
2.递归
//递归思想(不使用临时变量)
int my_strlen2(char* str)
{
if (*str == '\0')
{
return 0;
}
else
{
return 1 + my_strlen2(str + 1);
}
}
3.指针
//指针
int my_strlen3(char* str)
{
char* p = str;
while (*str)
{
str++;
}
return str - p;
}
2.strcpy
strcpy将源字符串(src)拷贝到指定空间(dest)
char* my_strcpy(char* dest, const char* src)
{
//把src拷贝到dest的后面
char* ret = dest;
while (*src)
{
*dest = *src;
dest++;
src++;
}
*dest = '\0';
return ret;
}
上面的代码便于理解,下面的代码写起来行数更少
char* my_strcpy(char* dest, const char* src)
{
assert(dest && src);
char* ret = dest;
while (*dest++ = *src++)
{
;
}
return ret;
}
3.strcat
strcat将一段字符串追加到另一段字符串后面
char* my_strcat(char* dest, char* src)
{
char* ret = dest;
while (*dest)
dest++;
while (*src)
{
*dest = *src;
dest++;
src++;
}
*dest = '\0';
return ret;
}
4.memcpy
memcpy和strcpy很像,但是memcpy可以拷贝任意类型,所以函数返回值类型和函数参数这里用的时void*
void* my_memcpy(void* dest, void* src, int sz)
{
void* ret = dest;
while (sz)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
sz--;
}
return ret;
}
5.memmove
memmove和memcpy也是一样的,但是memmove可以处理源内存区域和目标内存区域有重叠的情况。
判断是正向赋值还是反向
void* my_memmove(void* dest, void* src, size_t sz) {
assert(dest && src); // 检查指针有效性
void* ret = dest;
if ((char*)dest > (char*)src)
{
while (sz > 0) {
*((char*)dest + sz-1) = *((char*)src + sz-1); // 避免越界
sz--;
}
}
else {
while (sz > 0) {
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
sz--;
}
}
return ret;
}
memset
将 ptr 所指向的内存块的前 num个字节都设置为指定的值 value。通常用于将一段内存初始化为特定的值
void* my_memset(void* ptr, int value, size_t num)
{
assert(ptr);
void* ret = ptr;
while (num)
{
*(char*)ptr =value;
ptr = (char*)ptr + 1;
num--;
}
return ret;
}