溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

用C語言模擬實現memcpy函數,memmove函數和memset函數

發布時間:2020-07-08 23:17:39 來源:網絡 閱讀:3677 作者:檸檬dream 欄目:編程語言

模擬實現memcpy函數:

函數原型:void *memcpy (void *p,void *m, size_t num);

memcpy與strcpy相比,memcpy函數用來做內存拷貝,可以用它拷貝任何數據類型的對象,并且可以指定拷貝的數據長度。stycpy函數也是用來做內存拷貝,并且只能拷貝字符串類型的數據。memcpy并不是遇到"\0"就結束,而是一定會拷貝完num個字節。而strcpy 遇到"\0"就結束。

memcpy函數代碼:

#include <stdio.h>
#include <assert.h>
void my_memcpy(void *p,const void *m,size_t num)
{
	char *str1 = (char *)p;
	const char *str2 = (const char *)m;
	assert(p);
	assert(m);
	while(num)
	{
		*str1=*str2;
		str1++;
		str2++;
		num--;
	} 
}
int main()
{
	int arr[]={1,2,3,4,5,6,7,8,9};
	int i;
	my_memcpy(arr,arr+3,sizeof(int)*5);
	for(i=0;i<9;i++)
	{
		printf("%d",arr[i]);
	}
	return 0;
}

 memcpy可以拷貝任何數據類型的對象,比如,上段代碼中用memcpy實現了拷貝int 型的數組,用memcpy實現數組的拷貝只能是后面的拷貝前面的,上面代碼中從數組的arr+3向arr拷貝,在main函數中存入形參(arr,arr+3,sizeof(int)*5),在調用函數中用void型的指針接收(void *p,const void* m,size_t num),void可以指向任何類型的指針,但是由于復制的時候要一個個字節去復制,所以我們需要把void轉換成char類型,然后char類型的兩個指針進行拷貝,指針地址加加。

  

  模擬實現memmove函數;

memmove和memcpy函數都是C語言中的庫函數,作用是拷貝一定長度的內存的內容,它們的作用是一樣的,唯一的區別就是當內存發生局部重疊的時候,memmove保證拷貝的結果是正確的,memcpy不保證拷貝的結果是正確的。

memmove函數代碼:

#include <stdio.h>
#include <assert.h>

void my_memmove(void *p,const void *m,size_t num)
{
	char *str1 = (char *)p;
	const char *str2 = (const char *)m;
	assert(p);
	assert(m);
	if (str1>str2 && str1 < str2+num)
	{
		while (num--)
		{
			*(str1+num) = *(str2+num);
		}
	}
	else
	{
		while(num)
		{
			*str1=*str2;
			str1++;
			str2++;
			num--;
		}
	}
}

int main()
{
	int arr[]={1,2,3,4,5,6,7,8,9};
	int i;
	//my_memmove(arr,arr+3,sizeof(int)*5);
	my_memmove(arr+3,arr+1,sizeof(int)*5);
	for(i=0;i<9;i++)
	{
		printf("%d",arr[i]);
	}
	return 0;
}

memmove分兩種情況一種是拷貝時內存內部沒有發生局部重疊的時候,它的拷貝方式跟memcpy是相同的,另一種是內存內部發生局部重疊時,相當于(str1>str2&&str1<str2+num),用memmove拷貝實現從最后一個往前拷貝,保證了結果的正確性。


  模擬實現memset函數:

函數原型是:void *memset(void *src,int num,size_t len);

memset函數通常用來對一塊已經分配地址的內存進行初始化,并且通常初始化為0.

#include <stdio.h>
#include <string.h>
void my_memset (void *src,int num,size_t len)
{
	char *ptr=(char*)src;
	while(len--)
	{
		*ptr=((char*)num);
		ptr++;
	}
}

int main()
{
	int arr[10];
	int i;
	my_memset(arr,0,5*sizeof(int));
	for (i=0;i<10;i++)
	{
		printf("%d ",arr[i]);
	}
	return 0;
}

一定需要注意的是,memset是按照字節對初始化空間進行初始化的,也就是說,函數里面的第二個參數的那個初值是按照一個一個字節往第一個參數所指區域賦值的,所以對于單字節數據類型(char)可以初始化為任何值,但對于非但字節數據類型只能初始化為0.

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女