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

C語(yǔ)言深入詳解四大內(nèi)存函數(shù)的使用

 更新時(shí)間:2022年07月07日 08:53:18   作者:龍兆萬(wàn)  
這篇文章主要介紹了C語(yǔ)言的四大內(nèi)存函數(shù),講解了mencpy、memmove、memcmp、memset函數(shù),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步

1.memcpy

與字符串函數(shù) strcpy 類似,也是進(jìn)行拷貝。但是需要注意的是,strcpy 是針對(duì)字符串進(jìn)行拷貝,而 memcpy 是針對(duì)內(nèi)存進(jìn)行拷貝。

如何理解呢?strcpy 進(jìn)行拷貝的時(shí)候,只能一個(gè)字節(jié)一個(gè)字節(jié)的拷貝,但要實(shí)現(xiàn) 整型、浮點(diǎn)型等數(shù)據(jù)類型拷貝的時(shí)候,就不得不用到 memcpy 了。

我們觀察 strcpy 的函數(shù)聲明:

char * strcpy ( char * destination, const char * source );

再觀察 memcpy 的函數(shù)聲明:

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

可以看到 strcpy 的局限在于只能接收 字符型 的指針,但 memcpy 對(duì)于類型可以在函數(shù)內(nèi)部實(shí)現(xiàn)自定義。

我們?yōu)g覽cplusplus對(duì)參數(shù)作出的解釋:

現(xiàn)在我們要研究如何使用:

#include <stdio.h>
#include <string.h>
int main()
{
	int dest[10] = { 0 };
	int src[10] = { 1,2,3,4,5,6,7,8,9,10 };
	memcpy(dest, src, 20);//拷貝 20 個(gè)字節(jié)
	return 0;
}

我們從 src 數(shù)組中,拷貝 20 個(gè)字節(jié)的數(shù)據(jù)放到 dest 數(shù)組中。那么我們通過(guò) 調(diào)試—窗口—監(jiān)視來(lái)觀察 dest 數(shù)組中的變化:

未經(jīng) memcpy 前:

經(jīng) memcpy 后:

可以直觀地看到, dest 數(shù)組中前 20 個(gè)字節(jié)的內(nèi)容發(fā)生了改變。

使用起來(lái)倒是不復(fù)雜,那我們能不能用自己的代碼去模擬實(shí)現(xiàn)一個(gè) memcpy 函數(shù)?

#include <stdio.h>
void* AnalogMemcpy(void* dest, const void* src, unsigned int num)
{
	void* start = dest;//定義一個(gè)記錄 dest 初始地址的指針
	while (num--)//一個(gè)字節(jié)一個(gè)字節(jié)拷貝
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return start;//返回此指針
}
int main()
{
	int dest[10] = { 0 };
	int src[10] = { 1,2,3,4,5,6,7,8,9,10 };
	AnalogMemcpy(dest, src, 20);
	return 0;
}

我們的實(shí)現(xiàn)思路非常簡(jiǎn)單,因?yàn)楣俜浇o出第三個(gè)參數(shù)的定義是:要復(fù)制的字節(jié)數(shù)。那我們順?biāo)浦垡粋€(gè)字節(jié)一個(gè)字節(jié)的拷貝。

但是到這里,可能會(huì)存在這樣一個(gè)問(wèn)題: char 類型是一個(gè)字節(jié),我們使用 memcpy 時(shí)也是一個(gè)字節(jié)一個(gè)字節(jié)的拷貝,那為什么 strcpy 不能拷貝整型?

在我們自己模擬實(shí)現(xiàn) strcpy 的時(shí)候,拷貝的停止條件是什么?是 src 字符串碰到 '\0' 。默認(rèn)我們的設(shè)備是小端存儲(chǔ)模式,那么我們使用 strcpy 進(jìn)行拷貝的時(shí)候就會(huì)出現(xiàn)這種情況:

現(xiàn)在我們使用模擬實(shí)現(xiàn)的 memcpy 函數(shù)來(lái)執(zhí)行這段代碼:

#include <stdio.h>
void* AnalogMemcpy(void* dest, const void* src, unsigned int num)
{
	void* start = dest;//定義一個(gè)記錄 dest 初始地址的指針
	while (num--)//一個(gè)字節(jié)一個(gè)字節(jié)拷貝
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return start;//返回此指針
}
int main()
{
	int dest[10] = { 1,2,3,4,5,6,7,8,9,10 };
	AnalogMemcpy(dest + 3, dest, 20);
	return 0;
}

這段代碼的意思是這樣的:

但事實(shí)上真正的結(jié)果是:

這該如何解釋呢?其實(shí)不難:

那么我們暫且定下一個(gè)結(jié)論:

memcpy 只能處理空間不重疊的數(shù)據(jù)拷貝。

2.memmove

這個(gè)函數(shù)與 memcpy 的功能相同,都是進(jìn)行數(shù)據(jù)拷貝。但是不同的點(diǎn)是:memmove 是用來(lái)處理空間重疊的數(shù)據(jù)拷貝的。

這是 memmove 的函數(shù)聲明:

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

既然是處理空間重疊的情況,那我們直接對(duì)上一個(gè)代碼進(jìn)行處理:

可以看到, memmove 符合我們的預(yù)期實(shí)現(xiàn)了效果。

我們現(xiàn)在來(lái)挑戰(zhàn)一下如何模擬實(shí)現(xiàn)一個(gè) memmove 函數(shù):

#include <stdio.h>
void* AnalogMemmove(void* dest, const void* src, unsigned int num)
{
	void* start = dest;//定義一個(gè)記錄 dest 初始地址的指針
 
	if (src < dest)//如果 src 在 dst 的左邊
	{
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
		}
	}
	else
	{
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	return start;//返回這個(gè)指針
}
int main()
{
	int dest[10] = { 1,2,3,4,5,6,7,8,9,10 };
	AnalogMemmove(dest + 3, dest, 20);
	return 0;
}

乍一看,這個(gè)代碼比較復(fù)雜,事實(shí)上,只有兩種情況。

我們來(lái)分析一下:

但是!這里要注意了,上面使使用自己模擬的 memcpy 不能實(shí)現(xiàn)空間重疊拷貝的,但庫(kù)函數(shù)原裝的 memcpy 能夠?qū)崿F(xiàn)空間重疊拷貝嗎?

我們來(lái)看庫(kù)函數(shù) memcpy 能否實(shí)現(xiàn)空間重疊拷貝:

#include <stdio.h>
#include <string.h>
int main()
{
	int dest[10] = { 1,2,3,4,5,6,7,8,9,10 };
	memcpy(dest + 3, dest, 20);
	return 0;
}

這就奇了怪了!既然庫(kù)函數(shù) memcpy 能夠?qū)崿F(xiàn)空間重疊的拷貝,那還需要 memmove 做什么?

事實(shí)上,對(duì)于我使用的 Visual Studio 2022 這款編譯器來(lái)說(shuō),memcpy 是可以實(shí)現(xiàn)空間重復(fù)拷貝的。也就是說(shuō)可能在其他的編譯器上實(shí)現(xiàn)不了空間重疊拷貝,但 Visual Studio 2022 這款編譯器賦予了 memcpy 這項(xiàng)功能。

3.memcmp

與 strcmp 類似的,這個(gè)函數(shù)也是進(jìn)行比較的函數(shù),我們觀察一下它的函數(shù)聲明:

int memcmp ( const void * ptr1, const void * ptr2, size_t num );

那么對(duì)于這些參數(shù)以及返回值的解釋是:

因?yàn)槲覀儗W(xué)習(xí)過(guò) strcmp ,那我們現(xiàn)在直接使用它:

#include <stdio.h>
#include <string.h>
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = { 1,2,3,3,4,5,6,7,8,9 };
	int ret=memcmp(arr1, arr2, 20);
	if (ret > 0)
		printf("arr1 > arr2\n");
	else if (ret < 0)
		printf("arr1 < arr2\n");
	else
		printf("arr1 == arr2\n");
	return 0;
}

與 strcmp 的原理是一致的,這里就不贅述了。

4.memset

直譯過(guò)來(lái)就是內(nèi)存設(shè)置。事實(shí)上也是這么回事。

觀察它的函數(shù)聲明:

void * memset ( void * ptr, int value, size_t num );

它的作用是以及參數(shù)的意義:

說(shuō)白了就是:你需要提供一個(gè)指針,這個(gè)指針指向的要被填充的內(nèi)存。然后提供一個(gè)值,這個(gè)值決定了每個(gè)字節(jié)要被填充為什么內(nèi)容。最后提供一個(gè)數(shù),這個(gè)數(shù)指的是你要填充多少個(gè)字節(jié)。

我們寫一個(gè)例子:

#include <stdio.h>
#include <string.h>
int main()
{
	int arr[10] = { 0 };
	memset(arr, 1, 4);
	return 0;
}

這就奇了怪了,我們不是設(shè)置四個(gè)字節(jié)為 1 嗎?千萬(wàn)不要么想。我們上面強(qiáng)調(diào)過(guò)了,這個(gè)函數(shù)是對(duì)每個(gè)字節(jié)填充。

我們分析一下我們寫的例子:

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

相關(guān)文章

  • C語(yǔ)言實(shí)現(xiàn)電話簿管理系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)電話簿管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)電話簿管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • C++全面細(xì)致講解復(fù)數(shù)類

    C++全面細(xì)致講解復(fù)數(shù)類

    本文章向大家介紹C++ 標(biāo)準(zhǔn)庫(kù)中的復(fù)數(shù)類,主要包括C++ 標(biāo)準(zhǔn)庫(kù)中的復(fù)數(shù)類使用實(shí)例、應(yīng)用技巧、基本知識(shí)點(diǎn)總結(jié)和需要注意事項(xiàng),具有一定的參考價(jià)值,需要的朋友可以參考一下
    2022-06-06
  • C語(yǔ)言二叉樹(shù)的非遞歸遍歷實(shí)例分析

    C語(yǔ)言二叉樹(shù)的非遞歸遍歷實(shí)例分析

    這篇文章主要介紹了C語(yǔ)言二叉樹(shù)的非遞歸遍歷,包括了先序遍歷、中序遍歷與后序遍歷,需要的朋友可以參考下
    2014-09-09
  • 在Visual Studio使用C++開(kāi)發(fā)Metro應(yīng)用

    在Visual Studio使用C++開(kāi)發(fā)Metro應(yīng)用

    這篇文章主要介紹了在Visual Studio使用C++開(kāi)發(fā)Metro應(yīng)用的示例,盡管只是一個(gè)Hello world,但可以體現(xiàn)出VS下為開(kāi)發(fā)者提供的方便,需要的朋友可以參考下
    2015-07-07
  • C指針原理教程之編譯原理-小型計(jì)算器實(shí)現(xiàn)

    C指針原理教程之編譯原理-小型計(jì)算器實(shí)現(xiàn)

    本文給大家分享的是如何使用C語(yǔ)言編寫一個(gè)小型計(jì)算器的實(shí)例代碼,有需要的小伙伴可以參考下
    2019-02-02
  • 詳解C語(yǔ)言數(shù)組越界及其避免方法

    詳解C語(yǔ)言數(shù)組越界及其避免方法

    這篇文章主要介紹了詳解C語(yǔ)言數(shù)組越界及其避免方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之二叉鏈表創(chuàng)建二叉樹(shù)

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之二叉鏈表創(chuàng)建二叉樹(shù)

    這篇文章主要介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之?二叉鏈表創(chuàng)建二叉樹(shù),下文我們?yōu)榱烁奖愕氖褂枚鏄?shù)結(jié)構(gòu)體,可以使用?typedef?對(duì)結(jié)構(gòu)體進(jìn)行命名,具體內(nèi)容需要的小伙伴可以參考一下
    2022-02-02
  • VS Code遠(yuǎn)程連接Linux服務(wù)器調(diào)試C程序的操作方法

    VS Code遠(yuǎn)程連接Linux服務(wù)器調(diào)試C程序的操作方法

    這篇文章主要介紹了VS Code遠(yuǎn)程連接Linux服務(wù)器調(diào)試C程序的操作方法,打開(kāi)遠(yuǎn)程 Linux 服務(wù)器上的文件夾本文以 /root/ 為例,給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-12-12
  • C++中std的使用及說(shuō)明

    C++中std的使用及說(shuō)明

    這篇文章主要介紹了C++中std的使用及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • 簡(jiǎn)單介紹C++中變量的引用

    簡(jiǎn)單介紹C++中變量的引用

    這篇文章主要簡(jiǎn)單介紹了C++中變量的引用,是C++入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09

最新評(píng)論

大冶市| 浪卡子县| 乐平市| 常山县| 杨浦区| 兴安盟| 青州市| 梅州市| 涪陵区| 民权县| 垦利县| 教育| 贡山| 称多县| 金寨县| 洞口县| 金堂县| 武定县| 宜都市| 天津市| 农安县| 柞水县| 额济纳旗| 惠东县| 青铜峡市| 奎屯市| 鄂尔多斯市| 灵武市| 曲靖市| 青龙| 中超| 上思县| 涟源市| 大关县| 逊克县| 泊头市| 关岭| 延安市| 天峻县| 郁南县| 东至县|