目录
内存操作函数
- memcpy
- memmove
- memset
- memcmp
memcpy
void* memcpy(void* destination,const void* source, size_t num)
- 复制指定个数字节数据,到目标位置;
- 遇到'\0'并不会停下来;
- 如source和destination有任何的重叠也可使用,但一般使用memmove;
注:模拟实现的函数,无法自己拷贝重叠,会覆盖数据;
#include <stdio.h>
#include <string.h>
int main()
{
int arr1[10] = { 0 };
int arr2[10] = { 0,1,2,3,4,5,6,7,8,9 };
//将arr2数组中,前20个字节数据复制到arr1中
memcpy(arr1, arr2, 5 * 4);
return 0;
}
#include <stdio.h>
#include <string.h>
#include <assert.h>
//模拟实现memcpy
void* my_memcpy(void* dest, const void* src, size_t num)
{
assert(dest);
assert(src);
void* tmp = dest;
while (num--)
{
*((char*)dest)++ = *((char*)src)++;
}
return tmp;
}
int main()
{
char str1[] = "abcdefg";
char str2[] = "qwe";
printf("%s ", (char*)my_memcpy(str1, str2, 3));
return 0;
}
int main()
{
//会出现覆盖错误
char str1[] = "abcdefg";
printf("%s ", (char*)my_memcpy(str1+2, str1, 3));
return 0;
}
//结果:abafg
int main()
{
char str1[] = "abcdefg";
printf("%s ", (char*)memcpy(str1 + 2, str1, 3));
return 0;
}
//结果:abcfg
memmove
void* memmove(void* destination,const void* source, size_t num)
- 复制指定个数字节数据,到目标位置;
- 与memcpy的差别,处理的源内存块和目标内存块是可以重叠的;
- 源空间和目标空间出现重叠,使用memmove函数;
#include <stdio.h>
#include <string.h>
#include <assert.h>
//模拟实现memmove
void* my_memmove(void* dest, const void* src, size_t num)
{
assert(dest);
assert(src);
void* tmp = dest;
//dest<src(dest在前),从前向后拷贝
if (dest < src)
{
while (num--)
{
*((char*)dest)++ = *((char*)src)++;
}
}
//dest>=src(dest在后),从后向前拷贝
else
{
while (num--)
{
*((char*)dest + num) = *((char*)src + num);
}
}
return tmp;
}
int main()
{
char str1[] = "abcdefg";
char str2[] = "qwe";
printf("%s ", (char*)my_memmove(str1+2, str1, 3));
return 0;
}
//结果:abcfg
memcmp
int memcmp(const void* ptr1,const void* ptr2, size_t num)
- 比较从ptr1和ptr2指针开始的每个字节无符号值大小,总共比较num个数;
- <0,ptr1代码块内容小于ptr2代码块内容;
- =0,ptr1代码块内容等于ptr2代码块内容;
- >0,ptr1代码块内容大于ptr2代码块内容;
注:和'\0'无关,注意和strcmp/strncmp区分;
#include <stdio.h>
#include <string.h>
#include <assert.h>
//模拟实现memcmp,参考strncmp
int my_memcmp(const void* p1, const void* p2, size_t num)
{
assert(p1);
assert(p2);
if (!num)
return 0;
while (num--)
{
if (*(char*)p1 != *(char*)p2)
{
//比较字节无符号值大小
//大于返回1,小于返回-1
return (*(unsigned char*)p1 > *(unsigned char*)p2) - (*(unsigned char*)p1 < *(unsigned char*)p2);
}
((char*)p1)++;
((char*)p2)++;
}
return 0;
}
int main()
{
int arr1[] = { 1,222,3,4 };
int arr2[] = { 1,333 };
printf("%d ", memcmp(arr1, arr2, 2*4)); //以每个字节值进行比较,num不要越界
printf("%d ", my_memcmp(arr1, arr2, 2 * 4));
return 0;
}
//结果:1 1
memset
void* memset(void* destination,int c, size_t num)
- 设置num字节,每个字节值为c;
- 将目标地址内num个内存,值设置为c,返回目标空间地址;
- c为待设置的内存字节值,num指定字节个数;
int main()
{
char str1[] = "abcdefg";
printf("%s ", (char*)memset(str1, 'q', 3)); //以每个字节进行设置的
return 0;
}
//结果:qqqdefg
#include <stdio.h>
#include <string.h>
#include <assert.h>
//模拟实现memset
void* my_memset(void* dest, int c, size_t num)
{
assert(dest);
void* tmp = dest;
while (num--)
{
*(char*)dest = c;
(char*)dest += 1;
}
return tmp;
}
int main()
{
char str[] = "abcdefg";
printf("%s ", (char*)my_memset(str, 'q', 3));
return 0;
}
//结果:qqqdefg