最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語(yǔ)言?模擬實(shí)現(xiàn)memcpy與memmove函數(shù)詳解

 更新時(shí)間:2022年04月08日 17:46:43   作者:不一樣的煙火a  
這篇文章主要介紹了C語(yǔ)言詳解如何模擬內(nèi)存函數(shù),用到了mencpy與memmove兩個(gè)函數(shù),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步

一、memcpy函數(shù)的介紹

1.函數(shù)的聲明

void * memcpy ( void * destination, const void * source, size_t num );

2.函數(shù)功能與注意事項(xiàng)

  • 函數(shù)memcpy從source的位置開(kāi)始向后復(fù)制num個(gè)字節(jié)的數(shù)據(jù)到destination的內(nèi)存位置。
  • 注意這個(gè)函數(shù)在遇到 '\0' 的時(shí)候并不會(huì)停下來(lái)。
  • 如果source和destination有任何的重疊,復(fù)制的結(jié)果都是未定義的。
  • memcpy函數(shù)可以拷貝任何的類型的數(shù)據(jù),不像strcpy函數(shù)只能拷貝字符串。

3.函數(shù)的使用

#include <stdio.h>
#include <string.h>//使用memcpy函數(shù)時(shí)記得引用它的頭文件
int main()
{
	int arr1[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int arr2[5] = { 0 };//總共大小為20字節(jié)
	memcpy(arr1, arr2, 20//拷貝20個(gè)字節(jié)的數(shù)據(jù));//將arr2中的數(shù)據(jù)拷貝到arr1中
	int i = 0;
	printf("拷貝后arr1中的數(shù)據(jù)為:");
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

運(yùn)行結(jié)果:

二、模擬實(shí)現(xiàn)memcpy函數(shù)

1.模擬分析

1.因?yàn)槲覀儾恢牢覀円截惖氖鞘裁搭愋偷臄?shù)據(jù),可能是char類型的數(shù)據(jù),也可能是int類型的數(shù)據(jù),還有可能是double類型的數(shù)據(jù),這些不同類型數(shù)據(jù)的大小是不同的。為了實(shí)現(xiàn)一個(gè)能拷貝所有類型數(shù)據(jù)的memcpy函數(shù),我們就只能一個(gè)字節(jié)一個(gè)字節(jié)的拷貝,因?yàn)樽钚☆愋偷拇笮∈且粋€(gè)字節(jié),這樣就能將所有類型的數(shù)據(jù)都進(jìn)行拷貝了。

2.因?yàn)槲覀儾恢纻鞯絤emcpy函數(shù)的地址是什么類型,所以我們?cè)诮邮諅鬟^(guò)來(lái)的地址時(shí)要用void*類型的指針來(lái)接收。

3.由于我們只需要將源地址存儲(chǔ)的數(shù)據(jù)拷貝到目標(biāo)地址里面,所以只需要改變目標(biāo)地址處存儲(chǔ)的內(nèi)容,而不需要改變?cè)吹刂诽幋鎯?chǔ)的地址。所以我們就需要用const void*類型的指針來(lái)接收源地址。

4.為了實(shí)現(xiàn)鏈?zhǔn)皆L問(wèn),我們要將傳進(jìn)來(lái)的目標(biāo)起始地址(destination)返回。由于這個(gè)函數(shù)在執(zhí)行的時(shí)候會(huì)改變destination存儲(chǔ)的內(nèi)容,所以我們要重新創(chuàng)建一個(gè)void*類型的指針來(lái)存儲(chǔ)這個(gè)地址。

5.為了避免傳進(jìn)來(lái)的地址是空指針,我們需要用assert來(lái)斷言傳進(jìn)來(lái)的地址不是空指針。

2.模擬實(shí)現(xiàn)

#include<stdio.h>
#include<assert.h>
//模擬實(shí)現(xiàn)memcpy
void* my_memcpy(void* dest, const void* scr, size_t count)
{
	assert(dest && scr);//斷言傳進(jìn)來(lái)的地址不是空指針
	void* ret = dest;//保存目標(biāo)起始地址
	while (count--)//拷貝源地址存儲(chǔ)的數(shù)據(jù)
	{
		*(char*)dest = *(char*)scr;
		(char*)dest = (char*)dest + 1;
		(char*)scr = (char*)scr + 1;
	}
	return ret;//返回目標(biāo)起始地址
}
 
 
 
 
//應(yīng)用模擬實(shí)現(xiàn)的函數(shù)
int main()
{
	int arr1[] = { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 };
	int arr2[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	my_memcpy(arr2, arr1, 24);//拷貝6個(gè)字節(jié)的數(shù)據(jù)
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

運(yùn)行結(jié)果:

三、memmove函數(shù)的介紹

1.函數(shù)的聲明

void * memmove ( void * destination, const void * source, size_t num );

2.為什么會(huì)有memmove函數(shù)

為什么會(huì)有memmove這個(gè)函數(shù)呢,這個(gè)還要從上面的memcpy函數(shù)說(shuō)起。因?yàn)閙emcpy函數(shù)不能將一個(gè)數(shù)組的中的數(shù)據(jù)拷貝到自身(也就是目標(biāo)數(shù)據(jù)是自己,源數(shù)據(jù)也是自己,只不過(guò)是一個(gè)數(shù)組里面不同的位置的數(shù)據(jù)拷貝到另外一個(gè)位置上),如果像這樣拷貝就會(huì)出現(xiàn)重疊拷貝,會(huì)導(dǎo)致結(jié)果不是我們預(yù)期的結(jié)果。

就像下面這個(gè)代碼:

//應(yīng)用模擬實(shí)現(xiàn)的memcpy函數(shù)
int main()
{
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	my_memcpy(arr + 2, arr, 24);//預(yù)期出現(xiàn)結(jié)果為1 2 1 2 3 4 5 6 9 10
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);//實(shí)際出現(xiàn)結(jié)果
	}
	return 0;
}

運(yùn)行結(jié)果:

 出現(xiàn)預(yù)期結(jié)果和實(shí)際結(jié)果不同的原因:

出現(xiàn)這種結(jié)果的原因就是因?yàn)閙emcpy函數(shù)將自身數(shù)據(jù)拷貝到自身不同位置的時(shí)候出現(xiàn)了重疊拷貝。源數(shù)據(jù)的起始地址為arr,目標(biāo)數(shù)據(jù)的起始地址arr + 2,當(dāng)我們一進(jìn)來(lái)memcpy這個(gè)函數(shù)的時(shí)候,我們就先將arr處的數(shù)據(jù)拷貝到arr + 2處,將arr + 1處的數(shù)據(jù)拷貝到arr + 3處,當(dāng)我們想要將arr + 2處的數(shù)據(jù)拷貝到arr + 4處的時(shí)候,我們發(fā)現(xiàn)arr + 2處的數(shù)據(jù)已經(jīng)被替換成了arr處的數(shù)據(jù)(1),于是我們就只能將1拷貝到arr + 4處;當(dāng)我們要將arr + 3處的數(shù)據(jù)拷貝到arr + 5處的時(shí)候,我們發(fā)現(xiàn)arr + 3處的數(shù)據(jù)早已被替換成了arr + 1處的數(shù)據(jù)(2),所以我們只能將2拷貝到arr + 5處,就像這樣反復(fù)的重疊拷貝,拷貝的數(shù)據(jù)一直都是1/2/1/2/1/2,直到拷貝完我們想要拷貝的字節(jié)數(shù)。

于是為了將自身的數(shù)據(jù)拷貝到自身不同的位置處,我們就需要用memmove函數(shù)來(lái)實(shí)現(xiàn),memmove函數(shù)就是為了解決上面這種問(wèn)題而被創(chuàng)造的。

3.函數(shù)功能與注意事項(xiàng)

  • memmove和memcpy的差別就是memmove函數(shù)處理的源內(nèi)存塊和目標(biāo)內(nèi)存塊是可以重疊的。
  • 如果源空間和目標(biāo)空間出現(xiàn)重疊,就得使用memmove函數(shù)處理。

4.函數(shù)的使用

#include<stdio.h>
#include<string.h>//使用memmove函數(shù)時(shí)記得引用它的頭文件
int main()                  
{
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	memmove(arr + 2, arr, 24);//預(yù)期出現(xiàn)結(jié)果為1 2 1 2 3 4 5 6 9 10
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);//實(shí)際出現(xiàn)結(jié)果
	}
	return 0;
}

 這次我們發(fā)現(xiàn)用memmove函數(shù)來(lái)拷貝的預(yù)期結(jié)果和實(shí)際結(jié)果就一樣了,下面我們就講講memmove函數(shù)的模擬實(shí)現(xiàn)。

四、模擬實(shí)現(xiàn)memmove函數(shù)

1.模擬分析

1.將地址傳進(jìn)函數(shù)和函數(shù)接收地址的方法和上面的memcpy函數(shù)是一樣的,memcpy函數(shù)需要注意的地方memmove函數(shù)同樣需要注意,這里就不重復(fù)講了,嘿嘿。

2.memmove函數(shù)還需要注意的一點(diǎn)就是需要分析該怎么拷貝才不會(huì)重疊,下面為圖解:

情況一:dest小于等于src的地址

像下面這樣從前往后拷貝,這樣就不會(huì)重疊了。

 情況二:dest大于scr的地址

像下面這樣從后往前拷貝,這樣就不會(huì)重疊了。

2.模擬實(shí)現(xiàn)

#include<stdio.h>
#include<assert.h>
//模擬實(shí)現(xiàn)memmove
void* my_memmove(void* dest, const void* scr, size_t count)
{
	assert(dest && scr);//斷言傳進(jìn)來(lái)的地址不是空指針
	void* ret = dest; //保存目標(biāo)起始地址
	if (dest <= scr)//從前往后拷貝
	{
		while (count--)
		{
			*(char*)dest = *(char*)scr;
			(char*)dest = (char*)dest + 1;
			(char*)scr = (char*)scr + 1;
		}
	}
	else//從后往前拷貝
	{
		while (count--)
		{
			*((char*)dest + count) = *((char*)scr + count);
		}
	}
	return ret;
}
 
 
 
 
 
//應(yīng)用模擬實(shí)現(xiàn)的函數(shù)
int main()                  
{
	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	my_memmove(arr + 2, arr, 24);//預(yù)期出現(xiàn)結(jié)果為1 2 1 2 3 4 5 6 9 10
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);//實(shí)際出現(xiàn)結(jié)果
	}
	return 0;
}

  運(yùn)行結(jié)果

到此這篇關(guān)于C語(yǔ)言 模擬實(shí)現(xiàn)memcpy與memmove函數(shù)詳解的文章就介紹到這了,更多相關(guān)C語(yǔ)言 memcpy函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)和雙向鏈表操作

    C語(yǔ)言實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)和雙向鏈表操作

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)雙向鏈表操作,需要的朋友可以參考下
    2017-03-03
  • C語(yǔ)言中判斷int,long型等變量是否賦值的方法詳解

    C語(yǔ)言中判斷int,long型等變量是否賦值的方法詳解

    聲明了int ,long型等局部變量,在利用一些方法給這些變量賦值之后,想判斷這些變量是不是真的被賦初值了,怎么辦
    2013-07-07
  • C++訪問(wèn)std::variant類型數(shù)據(jù)的幾種方式小結(jié)

    C++訪問(wèn)std::variant類型數(shù)據(jù)的幾種方式小結(jié)

    std::variant是?C++17中引入的一個(gè)新的類模板,提供了一種存儲(chǔ)不同類型的值的方式,本文主要介紹了C++訪問(wèn)std::variant類型數(shù)據(jù)的幾種方式小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • C++中char[]能修改char*卻不行

    C++中char[]能修改char*卻不行

    本文主要介紹了C++中char[]能修改char*卻不行,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • C++實(shí)現(xiàn)智能柜管理系統(tǒng)

    C++實(shí)現(xiàn)智能柜管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)智能柜管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C語(yǔ)言Turbo C下實(shí)現(xiàn)俄羅斯方塊

    C語(yǔ)言Turbo C下實(shí)現(xiàn)俄羅斯方塊

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言Turbo C下寫(xiě)的俄羅斯方塊,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • C++中虛表是什么意思(概念及示例)

    C++中虛表是什么意思(概念及示例)

    虛函數(shù)表,以及虛函數(shù)指針是實(shí)現(xiàn)多態(tài)性(Polymorphism)的關(guān)鍵機(jī)制,這篇文章主要介紹了C++中虛表是什么意思(概念及示例),需要的朋友可以參考下
    2024-03-03
  • C++數(shù)據(jù)結(jié)構(gòu)深入探究棧與隊(duì)列

    C++數(shù)據(jù)結(jié)構(gòu)深入探究棧與隊(duì)列

    棧和隊(duì)列,嚴(yán)格意義上來(lái)說(shuō),也屬于線性表,因?yàn)樗鼈円捕加糜诖鎯?chǔ)邏輯關(guān)系為 "一對(duì)一" 的數(shù)據(jù),但由于它們比較特殊,本章講解分別用隊(duì)列實(shí)現(xiàn)棧與用棧實(shí)現(xiàn)隊(duì)列
    2022-05-05
  • C++ LibCurl實(shí)現(xiàn)Web指紋識(shí)別功能

    C++ LibCurl實(shí)現(xiàn)Web指紋識(shí)別功能

    Web指紋識(shí)別是一種通過(guò)分析Web應(yīng)用程序的特征和元數(shù)據(jù),以確定應(yīng)用程序所使用的技術(shù)棧和配置的技術(shù),本文將通過(guò)C++中LibCurl庫(kù)實(shí)現(xiàn)簡(jiǎn)單是指紋識(shí)別功能,感興趣的可以了解下
    2023-11-11
  • C語(yǔ)言編寫(xiě)簡(jiǎn)單拼圖游戲

    C語(yǔ)言編寫(xiě)簡(jiǎn)單拼圖游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言編寫(xiě)簡(jiǎn)單拼圖游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03

最新評(píng)論

邵阳县| 小金县| 从化市| 平江县| 集安市| 都匀市| 南京市| 曲沃县| 修文县| 牙克石市| 台北市| 德兴市| 永昌县| 申扎县| 济源市| 方山县| 漳浦县| 凉山| 信阳市| 垣曲县| 如皋市| 漳平市| 咸宁市| 威远县| 旺苍县| 盐源县| 施秉县| 府谷县| 韩城市| 嘉禾县| 东明县| 聂荣县| 昆明市| 文昌市| 汕头市| 枣庄市| 重庆市| 惠州市| 吉安市| 瓦房店市| 云林县|