目录
strlen的模拟实现
size_t strlen (const char* str);
strlen该函数是统计字符串的长度的
方法1:计数器count
利用临时变量count来统计字符的个数。
int my_strlen(const char* str)
{
int count = 0;
assert(str);//断言指针的有效性
while (*str++)//当str不为'\0'执行
count++;
return count;
}
方法2:递归(不创建临时变量)
这里没有使用任何临时变量,通过一层一层的递归来实现的。
//abcd
//1+bcd
//1+1+cd
//1+1+1+d
//1+1+1+1
int my_strlen(const char* str)
{
if (*str)
return 1 + my_strlen(str + 1);
return 0;
}
方法3:指针-指针
指针-指针的结果是中间元素的个数,所以我们通过2个指针,一个指向首元素,一个指向'\0',然后高地址减低地址就是结果了
int my_strlen(const char* str)
{
const char* end = str;
while (*end++);
return (int)(--end - str);
}
strcpy的模拟实现
char* strcpy (char* destination, const char* source);
strcpy是字符串拷贝函数,将source拷贝到destination中
模拟实现strcpy时需要注意以下几点:
①目标空间必须足够大
②目标空间必须是可以修改的(不能是常量字符串)
③源字符串必须以'\0'结束的
④它会把源字符串中的'\0'也拷贝到目标空间
char* my_strcpy(char* dest, const char* src)
{
char* ret = dest;
assert(dest && src);//断言指针的有效性
while (*dest++ = *src++);//将*src赋值给*dest后,判断这个值是否为0,然后再src++,dest++
return ret;
}
int main()
{
char str1[20] = "abcdef";
char str2[] = "Hello World";
//将str2拷贝到str1中
//预期效果为 Hello World
char* ret = my_strcpy(str1, str2);
printf("%s\n", ret);
return 0;
}
strcat的模拟实现
char* strcat (char* destination, const char* source);
strcat是字符串的追加函数,将source追加到destination后面
模拟实现strcat需要注意以下几点:
①源字符串和目标字符串都必须是以'\0'结束的
②目标空间必须足够大
③目标空间必须可修改
char* my_strcat(char* dest, const char* src)
{
char* ret = dest;
assert(dest && src);//断言指针的有效性
while (*dest)//找到dest中的'\0'
dest++;
while (*dest++ = *src++);//将src中的内容赋给dest(包括'\0')
return ret;
}
int main()
{
char str1[20] = "Hello";
char str2[] = "World!";
//将字符串str2追加到str1的后面
//预期效果为 HelloWorld!
char* ret = my_strcat(str1, str2);
printf("%s\n", ret);
return 0;
}
strcmp的模拟实现
int strcmp (const char* str1, const char* str2);
strcmp是字符串的比较函数
如果str1 > str2,返回一个大于0的数
如果str1 < str2,返回一个小于0的数
如果str1 = str2,返回0
【实际上,在VS中大于0的数就被固定为1,小于0的数就被固定为-1了】
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 && str2);//断言指针的有效性
while (*str1 == *str2)//*str1和*str2相等进入循环,否则直接return
{
if (!*str1)//如果*str1和*str2都指向了'\0',那么它们就相等了
return 0;
str1++;
str2++;
}
return *str1 - *str2;
}
int main()
{
char str1[] = "abcde";
char str2[] = "abcdf";
//比较str1和str2的大小
int ret = my_strcmp(str1, str2);
printf("%d\n", ret);
return 0;
}
strstr的模拟实现
char* strstr (const char* str1, const char* str2);
strstr是一个找子串的函数,返回值是找到的第一个子串的地址
char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);//断言指针的有效性
char* s1 = (char*)str1;//移动s1和s2指针来进行比较
char* s2 = (char*)str2;
char* cur = s1;//cur指针是记录当前从哪个字符开始比较的
while (*cur)
{
while (*s1 == *s2)
{
s1++;
s2++;
}
if (!*s2)//s2如果访问到了'\0',那么说明已经找到了子串了
return cur;//返回记录这一子串的首地址
cur++;
s1 = cur;
s2 = (char*)str2;//重置s2
}
return NULL;//如果找不到,返回NULL
}
int main()
{
char str1[] = "ABBCDEF";
char str2[] = "BCD";
//从str1中找str2
char* ret = my_strstr(str1, str2);
printf("%s\n", ret);
return 0;
}
memcpy的模拟实现
void* memcpy (void* destination, const void* source, size_t num);
memcpy是内存拷贝函数,可以拷贝任意类型的数据。
模拟实现memcpy需要注意以下几点:
①memcpy与strcpy不同,它遇到'\0'不会停下来
②memcpy是从source的起始位置向后复制num个字节到destination中
void* my_memcpy(void* dest, const void* src, size_t n)
{
void* ret = dest;
assert(dest && src);//断言指针的有效性
while (n--)//记录拷贝了多少个字节
{
*(char*)dest = *(char*)src;//以char为单位,因为char是1个字节
++(char*)dest;
++(char*)src;
}
return ret;
}
int main()
{
int arr1[] = { 1,3,5,7,9};
int arr2[] = { 2,4,6 };
//将arr1中的前12个字节设置为arr2前12个字节的内容
//预期效果为 2 4 6 7 9
my_memcpy(arr1, arr2, 12);
int i = 0;
for (i = 0;i < 5;i++)
printf("%d ", arr1[i]);
return 0;
}
memmove的模拟实现
void* memmove (void* destination, const void* source, size_t num);
memmove和memcpy都是拷贝任意类型的数据的
memmove与memcpy不同的是它可以处理源内存块与目标内存块重叠的情况。
void* memmove(void* dest, const void* src, size_t n)
{
void* ret = dest;
assert(dest && src);//断言指针的有效性
if (dest > src)
{
while (n--)//从后--->前 拷贝
{
*((char*)dest + n) = *((char*)src + n);//从后向前每个字节每个字节的拷贝
}
}
else//dest < src
{
while (n--)//从前--->后 拷贝
{
*(char*)dest = *(char*)src;
++(char*)dest;
++(char*)src;
}
}
return ret;
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
//将从arr开始的前20个字节拷贝到arr+2开始的前20个字节中
memmove(arr + 2, arr, 20);
int i = 0;
for (i = 0;i < 10;i++)
printf("%d ", arr[i]);
return 0;
}