欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言內(nèi)存函數(shù)的實(shí)現(xiàn)示例

 更新時(shí)間:2024年08月26日 08:31:50   作者:黎相思  
本文主要介紹了C語言內(nèi)存函數(shù)的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1.memcpy使用和模擬實(shí)現(xiàn)

mem -- memory在應(yīng)用中是記憶的意思,在計(jì)算機(jī)中是內(nèi)存的意思

1.1 memcpy的使用: 

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

memcpy - C++ Reference 

參數(shù)和返回值的類型是void*的指針是因?yàn)槿魏晤愋偷臄?shù)據(jù)都有可能拷貝,所以不能寫死,void*的指針可以接收任何類型的地址。 

  • 函數(shù)memcpy從source的位置開始向后復(fù)制num個(gè)字節(jié)的數(shù)據(jù)到destination指向的內(nèi)存位置。
  • 這個(gè)函數(shù)在遇到'\0'的時(shí)候并不會(huì)停下來。
  • 如果source和destination有任何的重疊,復(fù)制的結(jié)果都是未定義的。
#include <stdio.h>
#include <string.h>
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = { 0 };
	memcpy(arr2, arr1 + 2, 20);//后面的20是字節(jié)個(gè)數(shù),一個(gè)整型四個(gè)字節(jié)
	for (int i = 0; i < 20; i++)
	{
		printf("%d ", arr2[i]);
	}

	return 0;
}

注意:目標(biāo)空間必須可修改,目標(biāo)空間必須足夠大。 

1.2 memcpy的模擬實(shí)現(xiàn):  

#include <stdio.h>
#include <assert.h>
void* my_memcpy(void* dest, const void* src, size_t num)
{
    void* ret = dest;
    assert(dest && src);
	//void* 的指針不能進(jìn)行直接運(yùn)算 void* 的指針是無具體類型的指針
	for (int i = 0; i < num; i++)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
		/*
		(char*)dest++; //強(qiáng)轉(zhuǎn)是臨時(shí)的,加加的時(shí)候也是無具體類型的
		(char*)src++;

		//這種寫法不能保證在所有編譯器上都保證可行
		++(char*)dest;//這種在c++中編不過去,因?yàn)镃++中強(qiáng)制類型轉(zhuǎn)換的結(jié)果是臨時(shí)的
		++(char*)src;//臨時(shí)的變量是不能++的
		*/
	}
    return ret;
}
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = { 0 };
	my_memcpy(arr2, arr1 + 2, 20);//后面的20是字節(jié)個(gè)數(shù),一個(gè)整型四個(gè)字節(jié)
	for (int i = 0; i < 20; i++)
	{
		printf("%d ", arr2[i]);
	}

	return 0;
}

將arr1中的12345拷貝放到arr1中的34567的位置。 

int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memcpy(arr1+2, arr1, 20);//后面的20是字節(jié)個(gè)數(shù),一個(gè)整型四個(gè)字節(jié)
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}

	return 0;
}

 那么這里為什么會(huì)有問題呢?

所有當(dāng)我們時(shí)候自己寫的my_memcpy拷貝數(shù)據(jù)的時(shí)候當(dāng)我拷貝的這兩個(gè)空間是重疊的時(shí)候,就會(huì)出錯(cuò),所有memcpy不負(fù)責(zé)這種重疊內(nèi)存的拷貝,非要使用結(jié)果是未定義的,C語言標(biāo)準(zhǔn)沒有定義這個(gè)。

對(duì)于重疊的內(nèi)存,交給memmove來處理。 

2. memmove 使用和模擬實(shí)現(xiàn)

2.1 memmove的使用:

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

和memcpy的差別就是memmove函數(shù)的處理的源內(nèi)存塊和目標(biāo)內(nèi)存塊是可以重疊的。

如果源空間和目標(biāo)空間重疊,就得使用memmove函數(shù)處理。

#include <stdio.h>
#include <string.h>
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove(arr1+2, arr1, 20);//后面的20是字節(jié)個(gè)數(shù),一個(gè)整型四個(gè)字節(jié)
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

2.2 memmove的模擬實(shí)現(xiàn): 

#include <stdio.h>
#include <assert.h>
void* my_memmove(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest && src);
	if (dest < src)
	{
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
		}
	}
	return ret;
}
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr1+2, arr1, 20);//后面的20是字節(jié)個(gè)數(shù),一個(gè)整型四個(gè)字節(jié)
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

其實(shí)我們庫中的memcpy函數(shù)也能實(shí)現(xiàn)重疊拷貝。

 這是因?yàn)镃語言規(guī)定memcpy只要能實(shí)現(xiàn)不重疊的拷貝就行,重疊的拷貝交給memmove。

我們發(fā)現(xiàn)vs上的庫函數(shù)memcpy函數(shù)也能實(shí)現(xiàn)重疊內(nèi)存的拷貝,但是不能保證別的編譯器也能實(shí)現(xiàn)。

3.  memset函數(shù)的使用

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

memset - C++ Reference

#include <stdio.h>
#include <string.h>
int main()
{
	char arr[] = "hello world";//把hello world中的world改x
	memset(arr + 6, 'x', 5);
	printf("%s\n", arr);
	return 0;
}

前面的數(shù)組是char類型,那么int類型的數(shù)組應(yīng)該如何使用memset呢?

#include <stdio.h>
#include <string.h>
int main()
{
	int arr[10] = { 0 };
	//memset(arr, 1, 4); //不能這樣寫,因?yàn)樽詈笠粋€(gè)參數(shù)的單位是字節(jié)
	//被改之后就是0x01 0x01 0x01 0x01,轉(zhuǎn)換成10進(jìn)制就是16843009,這是不對(duì)的
	//所有把數(shù)組中的每個(gè)元素設(shè)置成1是做不到的,因?yàn)樗前醋止?jié)設(shè)置的,一個(gè)元素
	//就占4個(gè)字節(jié)
	
	//借助for循環(huán)可以實(shí)現(xiàn)
	for (int i = 0; i < 4; i++)
	{
		memset(arr + i, 1, 1);
	}
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

4. memcmp函數(shù)的使用 

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

memcmp - C++ Reference

#include <stdio.h>
#include <string.h>
int main()
{
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 1,2,3,6,5 };
	int ret = memcmp(arr1, arr2, 12);//比較前三個(gè),一個(gè)整型四個(gè)字節(jié),12個(gè)字節(jié)
	printf("%d\n", ret);
	return 0;
}

前12個(gè)字節(jié)相等,所有返回0。 

前13個(gè)字節(jié),arr1比arr2小,所以返回-1。

memcmp對(duì)于什么類型都可以比較。

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

相關(guān)文章

  • C++ main函數(shù)的幾點(diǎn)細(xì)節(jié)

    C++ main函數(shù)的幾點(diǎn)細(xì)節(jié)

    這篇文章主要介紹了C++ main函數(shù)的幾點(diǎn)細(xì)節(jié),幫助大家更好的理解和學(xué)習(xí)C++,感興趣的朋友可以了解下
    2020-08-08
  • C++?函數(shù)重載背后的原理

    C++?函數(shù)重載背后的原理

    這篇文章主要介紹了C++?函數(shù)重載背后的原理,我們不僅僅需要學(xué)會(huì)重載的使用,更要了解C++為什么支持函數(shù)重載,下面我們一起進(jìn)入文章學(xué)習(xí)該內(nèi)容吧
    2022-05-05
  • C/C++ 中sizeof(''a'')對(duì)比詳細(xì)介紹

    C/C++ 中sizeof(''a'')對(duì)比詳細(xì)介紹

    這篇文章主要介紹了C/C++ 中sizeof('a')的值對(duì)比詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • C++實(shí)現(xiàn)拓?fù)渑判颍ˋOV網(wǎng)絡(luò))

    C++實(shí)現(xiàn)拓?fù)渑判颍ˋOV網(wǎng)絡(luò))

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)拓?fù)渑判颍闹惺纠a介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • C語言新手入門速通手冊(cè)

    C語言新手入門速通手冊(cè)

    C 語言是一種通用的、面向過程式的計(jì)算機(jī)程序設(shè)計(jì)語言。1972 年,為了移植與開發(fā) UNIX 操作系統(tǒng),丹尼斯·里奇在貝爾電話實(shí)驗(yàn)室設(shè)計(jì)開發(fā)了 C 語言。C 語言是一種廣泛使用的計(jì)算機(jī)語言,它與 Java 編程語言一樣普及,二者在現(xiàn)代軟件程序員之間都得到廣泛使用
    2022-04-04
  • OpenMP task construct 實(shí)現(xiàn)原理及源碼示例解析

    OpenMP task construct 實(shí)現(xiàn)原理及源碼示例解析

    這篇文章主要為大家介紹了OpenMP task construct 實(shí)現(xiàn)原理及源碼示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Qt獲取git版本信息的具體方法

    Qt獲取git版本信息的具體方法

    這篇文章主要介紹了Qt獲取git版本信息的具體方法,今天又碰到這個(gè)問題了,想根據(jù)具體的git版本信息做代碼問題確認(rèn),文中有詳細(xì)的解決方案,具有一定的參考價(jià)值,需要的朋友可以參考下
    2024-04-04
  • 給C語言初學(xué)者的學(xué)習(xí)建議

    給C語言初學(xué)者的學(xué)習(xí)建議

    在本篇文章里小編給大家分享的是關(guān)于C語言學(xué)習(xí)建議的相關(guān)內(nèi)容,有興趣的朋友們可以學(xué)習(xí)參考下。
    2020-06-06
  • C++構(gòu)造函數(shù)初始化列表的實(shí)現(xiàn)詳解

    C++構(gòu)造函數(shù)初始化列表的實(shí)現(xiàn)詳解

    構(gòu)造函數(shù)主要作用在于創(chuàng)建對(duì)象時(shí)為對(duì)象的成員屬性賦值,構(gòu)造函數(shù)由編譯器自動(dòng)調(diào)用,無須手動(dòng)調(diào)用;析構(gòu)函數(shù)主要作用在于對(duì)象銷毀前系統(tǒng)自動(dòng)調(diào)用,執(zhí)行一 些清理工作
    2022-09-09
  • 冒泡算法的改進(jìn)具體實(shí)現(xiàn)

    冒泡算法的改進(jìn)具體實(shí)現(xiàn)

    這篇文章主要介紹了冒泡算法的改進(jìn)具體實(shí)現(xiàn),有需要的朋友可以參考一下
    2013-12-12

最新評(píng)論