Memcmp
为什么有了strcpy还要有memcpy
因为strcpy是用来拷贝字符和字符串的,strcpy是按字节拷贝的,一个字节一个字节去拷贝,strcpy是不能用来拷贝其他类型的,所以应运而生了memcpy
memcpy函数原型
void *memcpy( void *dest, const void *src, size_t count );
count为要拷贝的字节数,单位是字节
使用memcpy
#include<stdio.h>
#include<string.h>
int main()
{
int arr1[10] = { 0 };
int arr2[3] = { 1,2,3 };
memcpy(arr1, arr2, 12);
return 0;
}
模拟实现memcpy
#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* destination, const void* source, size_t num)
{
size_t i = 0;
assert(destination != NULL);
assert(source != NULL );
char* dest = (char*)destination;
char* sour = (char*)source;
for(i=0;i<num;i++)
{
dest[i] = sour[i];
}
return destination;
}
int main()
{
int arr1[10] = { 0 };
int arr2[] = { 1,2,3 };
my_memcpy(arr1, arr2, 12);
return 0;
}
#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dest, const void* source, size_t num)
{
//每次拷贝一个字节最为合适
assert(dest != NULL);
assert(source != NULL);
size_t i = 0;
char* ret = (char*)dest;
char* s1 = (char*)dest;
const char* s2 = (char*)source;
for (i = 0; i < num; i++)
{
*(char*)dest = *(char*)source;
s1++;
s2++;
}
return ret;
}
int main()
{
int arr1[10] = { 0 };
int arr2[] = { 1,2,3 };
my_memcpy(arr1, arr2, 12);
return 0;
}
#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dest, const void* source, size_t num)
{
//每次拷贝一个字节最为合适
void* ret = dest;
assert(dest != NULL);
assert(source != NULL);
while (num--)
{
*(char*)dest = *(char*)source;
((char*)dest)++;
((char*)source)++;
}
return ret;
}
int main()
{
int arr1[10] = { 0 };
int arr2[] = { 1,2,3 };
my_memcpy(arr1, arr2, 12);
return 0;
}
memcpy函数的注意事项
- 函数memcpy从source位置开始向后复制num个字节的数据到dest内存位置
- 这个函数在遇到\0的时候并不会停下来
- 如果source和dest有任何的重叠,其结果是未定义的,也就是说memcpy不处理这种情况。
Memmove
memmove的函数原型
void *memmove( void *dest, const void *src, size_t count );
memmove的拷贝会分为以下的两种情况
如下图所示:
分情况讨论
- 一种是dest>source
- 另一种是source<dest
memmove的函数原型
void *memmove( void *dest, const void *src, size_t count );
模拟实现memmove
#include<stdio.h>
#include<assert.h>
void* my_memmove(void* destination, const void* source, int count)
{
int i = 0;
assert(destination != NULL);
assert(source != NULL);
if (destination < source)
{
//从前往后拷贝
char* dest = (char*)destination;
char* sour = (char*)source;
for (i = 0; i <count; i++)
{
dest[i] = sour[i];
}
}
else
{
while (count--)
{
*((char*)destination + count) = *((char*)source + count);
}
}
return destination;
}
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(arr1 + 2, arr1, 16);
return 0;
}
memmove函数的注意事项
- 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以有重叠的
- 如果源空间和目标空间出现重叠的部分,就要使用memmove函数进行处理
Memcmp
memcmp函数原型
int memcmp( const void *buf1, const void *buf2, size_t count );
memcmp—>在两个缓冲区比较(在缓冲区中比较两个字符)
#include<stdio.h>
int main()
{
int arr1[] = { 1,2,3,4 };
int arr2[] = { 1,2,4,5 };
int ret = memcmp(arr1, arr2, 12);
printf("%d", ret);
return 0;
}
返回值和strcmp的含义一样
- 返回值 > 0 ptr1 > ptr2
- 返回值 = 0 ptr1 == ptr2
- 返回值 < 0 ptr1 < ptr2
模拟实现
int my_memcmp(const void* ptr1, const void* ptr2, size_t num)
{
assert(ptr1&&ptr2);
const char* ch_ptr1 = (char*)ptr1;
const char* ch_ptr2 = (char*)ptr2;
while (num&&*ch_ptr1&&*ch_ptr2)
{
if (*((unsigned char*)ch_ptr1) > *((unsigned char*)ch_ptr2)) //注意库中的都是转成无符号整数
{
return 1;
}
else if (*((unsigned char*)ch_ptr1) < *((unsigned char*)ch_ptr2))
{
return -1;
}
else
{
ch_ptr1++;
ch_ptr2++;
num--;
}
}
if (num == 0)
return 0;
if (*ch_ptr1 == '\0')
return -1;
if (*ch_ptr2 == '\0')
return 1;
}
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int my_memcmp1(const void *p1, const void *p2, size_t count)//方法1
{
assert(p1);
assert(p2);
char *dest = (char *)p1;
char *src = (char*)p2;
while (count && (*dest == *src))
{
count--;
dest++;
src++;
}
if (count == 0)
return 0;
return *dest - *src;
}
int my_memcmp2(const void *p1, const void *p2, size_t count)//方法2
{
assert(p1);
assert(p2);
int ret = 0;
char *dest = (char *)p1;
char *src = (char*)p2;
while (count && (!(ret = (*dest - *src))))
{
dest++;
src++;
count--;
}
if (ret > 0)
{
return 1;
}
else if (ret < 0)
{
return -1;
}
return 0;
}
int main()
{
int arr1[] = {1,2,3,4,5,6};
int arr2[] = {1,2,3,1000000,5,6};//清楚内存是怎样放置的
int ret = my_memcmp2(arr1, arr2, 16);
printf("%d", ret);
system("pause");
return 0;
}