Memcpy,Memmove,Memcmp函數詳解

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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章