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

C語言內(nèi)存函數(shù)的使用及其模擬實(shí)現(xiàn)

 更新時(shí)間:2021年10月19日 10:32:40   作者:Ersansui  
這篇文章主要介紹了C語言內(nèi)存函數(shù)的使用及其模擬實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

前言

在C語言中,我們除了會(huì)經(jīng)常用到與字符相關(guān)的函數(shù),我們還會(huì)使用到與內(nèi)存相關(guān)的庫函數(shù)。今天我們就來學(xué)習(xí)幾個(gè)常見的內(nèi)存函數(shù)吧!

在這里插入圖片描述

memcpy

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

這是一個(gè)內(nèi)存復(fù)制函數(shù),該函數(shù)會(huì)從source的位置開始向后復(fù)制num個(gè)字節(jié)的數(shù)據(jù)到destination的內(nèi)存位置。

這個(gè)函數(shù)在遇到 ‘\0' 的時(shí)候并不會(huì)停下來。

用法如下:

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[] = "Pierre de Fermat";
	char arr2[40];
	memcpy(arr2, arr1, strlen(arr1) + 1);
	printf("%s\n", arr2);
	return 0;
}

上述代碼的arr2的輸出結(jié)果為arr1中的內(nèi)容。

我們要注意,在目標(biāo)空間中,要保證有足夠的空間放得下要拷貝的內(nèi)容,以免造成越界。

模擬實(shí)現(xiàn)如下:

//memcpy的模擬實(shí)現(xiàn)
#include<stdio.h>
#include<string.h>
#include<assert.h>
//不會(huì)考慮內(nèi)存重疊的情況
void* my_memcpy(void* dest, const void* source, size_t nums) {
	//先記錄下dest的初始位置,便于后續(xù)返回
	void* ret = dest;
	//判斷傳入的兩個(gè)指針是否為空
	assert(dest, source);
	//利用循環(huán)來控制拷貝字節(jié)的個(gè)數(shù)
	while (nums--) {
		//由于傳入的是void*類型的指針,所以在使用前要強(qiáng)制轉(zhuǎn)換為char*
		*(char*)dest = *(char*)source;
		dest = ((char*)dest) + 1;
		source = ((char*)source) + 1;
	}
	return ret;
}

memcmp

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

這個(gè)函數(shù)是用來比較指定字節(jié)數(shù)的內(nèi)存空間是否相同。

返回值如下:

在這里插入圖片描述

上圖來自于這里

當(dāng)ptr1的內(nèi)容小于ptr2的內(nèi)容,就返回一個(gè)小于零的數(shù),當(dāng)ptr1的內(nèi)容大于ptr2的內(nèi)容,就返回一個(gè)大于零的數(shù),相等則返回零。

由于用法比較簡(jiǎn)單,就不進(jìn)行演示啦!

模擬實(shí)現(xiàn)如下:

#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_memcmp(const void* p1, const void* p2, size_t num) {
	//判斷傳入的兩個(gè)指針是否為空
	assert(p1 && p2);
	//利用循環(huán)依次比較
	int i = 0;
	for (i = 0; i < num; i++) {
		if (*((char*)p1 + i) > (*(char*)p2 + i)) {
			return 1;
		}
		else if(*((char*)p1 + i) < (*(char*)p2 + i)){
			return -1;
		}
	}
	return 0;
}

memmove

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

上面我們已經(jīng)學(xué)習(xí)過memcpy 函數(shù)的使用了,但是,如果我們的源空間和目標(biāo)空間有重復(fù)的部分,那么memcpy這個(gè)函數(shù)就會(huì)出現(xiàn)錯(cuò)誤,為了避免出錯(cuò),我們就來學(xué)習(xí)一下memmove這個(gè)函數(shù)吧!

int main() {
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove(arr+2, arr, 16);
	printf("%s\n", arr);
	return 0;
}

上面的代碼執(zhí)行后,arr會(huì)變成{3,4,5,6,5,6,7,8,9,10}

這個(gè)函數(shù)的模擬實(shí)現(xiàn)要分情況討論

1.如果dest在source前面,那么就有可能會(huì)出現(xiàn)有一部分內(nèi)存重疊的情況,我們就需要在source中,先拷貝前面的數(shù)據(jù)在拷貝后面的數(shù)據(jù),即從前往后拷貝。

2.如果dest在source后面,兩個(gè)指針相減的數(shù)值小于要移動(dòng)的字節(jié)數(shù),那么也會(huì)有內(nèi)存重疊的情況,那么此時(shí),我們就需要先拷貝后面的數(shù)據(jù),在拷貝前面的數(shù)據(jù),即從后向前拷貝。

3.如果dest與source之間的差值大于要拷貝的字節(jié)數(shù),那么此時(shí)就屬于是兩塊不重疊的內(nèi)存之間的拷貝,此時(shí)即使是用memcpy也不會(huì)有問題。

綜上,我們可以已dest在source前后作為分界線。

如果dest在source前面,那么我們就從前往后拷貝,如果dest在source后面,那么我們就從后往前拷貝。

具體代碼實(shí)現(xiàn)如下:

#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memmove(void* dest, void* source, size_t num) {
	assert(dest &&  source);
	//記錄初始dest的位置,方便后續(xù)返回
	void* ret = dest;
	//如果dest在source的前面,那么我們可以從前往后拷貝,防止數(shù)據(jù)被覆蓋
	if (dest < source) {
		while (num--) {
			*(char*)dest = *(char*)source;
			dest = (char*)dest + 1;
			source = (char*)source + 1;
		}
	}
	else {
		while (num--) {
			//下面的num在第一次進(jìn)入循環(huán)的時(shí)候已經(jīng)減過1了
			*((char*)dest + num)= *((char*)source + num);
		}
	}
	return ret;
}

memset

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

這個(gè)函數(shù)一般用于初始化一段內(nèi)存。

我們只需要傳入內(nèi)存空間的地址,需要初始化的字符,還有需要初始化的字節(jié)數(shù)即可。

由于這個(gè)函數(shù)的用法也比較簡(jiǎn)單,所以我們也不進(jìn)行用法演示啦!

模擬實(shí)現(xiàn)如下:

#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memset(void* dest, char ch, size_t num) {
	void* ret = dest;
	assert(dest);
	while (num--) {
		*(char*)dest = ch;
		((char*)dest)++;
	}
	return ret;
}

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • C語言實(shí)現(xiàn)酒店預(yù)訂管理系統(tǒng)

    C語言實(shí)現(xiàn)酒店預(yù)訂管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)酒店預(yù)訂管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 深入理解:Java是類型安全的語言,而C++是非類型安全的語言

    深入理解:Java是類型安全的語言,而C++是非類型安全的語言

    本篇文章是對(duì)Java是類型安全的語言,而C++是非類型安全的語言進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • C語言超詳細(xì)講解猜數(shù)字游戲的實(shí)現(xiàn)

    C語言超詳細(xì)講解猜數(shù)字游戲的實(shí)現(xiàn)

    現(xiàn)在很多游戲都有抽獎(jiǎng)抽卡的功能,其實(shí)這個(gè)就類似于猜數(shù)字,生成一個(gè)隨機(jī)數(shù),然后你去猜,猜對(duì)了就得獎(jiǎng)。猜到一定次數(shù)就會(huì)保底。要實(shí)現(xiàn)猜數(shù)字的小游戲,首先是要讓程序生成隨機(jī)數(shù),這就要用到rand、srand和time這三個(gè)函數(shù),其次要了解時(shí)間戳
    2022-07-07
  • 基于Matlab LBP實(shí)現(xiàn)植物葉片識(shí)別功能

    基于Matlab LBP實(shí)現(xiàn)植物葉片識(shí)別功能

    局部二值模式(LBP)是由Ojala等人于2002年提出,它被用于特征提取,而且提取的特征是圖像的紋理特征。本文將利用Matlab和LBP實(shí)現(xiàn)植物葉片識(shí)別,需要的可以參考一下
    2022-02-02
  • C++ 實(shí)現(xiàn)靜態(tài)鏈表的簡(jiǎn)單實(shí)例

    C++ 實(shí)現(xiàn)靜態(tài)鏈表的簡(jiǎn)單實(shí)例

    這篇文章主要介紹了C++ 實(shí)現(xiàn)靜態(tài)鏈表的簡(jiǎn)單實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • C++右值引用與移動(dòng)構(gòu)造函數(shù)基礎(chǔ)與應(yīng)用詳解

    C++右值引用與移動(dòng)構(gòu)造函數(shù)基礎(chǔ)與應(yīng)用詳解

    左值和右值都是針對(duì)表達(dá)式,左值是指表達(dá)式結(jié)束后依然存在的持久對(duì)象,右值是指表達(dá)式結(jié)束時(shí)就不再存在的臨時(shí)對(duì)象,下面這篇文章主要給大家介紹了關(guān)于C++11右值引用和移動(dòng)語義的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • C++ Qt開發(fā)之PushButton按鈕組件的使用詳解

    C++ Qt開發(fā)之PushButton按鈕組件的使用詳解

    Qt 是一個(gè)跨平臺(tái)C++圖形界面開發(fā)庫,利用Qt可以快速開發(fā)跨平臺(tái)窗體應(yīng)用程序,本文將重點(diǎn)介紹QPushButton按鈕組件的常用方法及靈活運(yùn)用,感興趣的小伙伴可以學(xué)習(xí)一下
    2023-12-12
  • CLOSE_WAIT狀態(tài)解決方案

    CLOSE_WAIT狀態(tài)解決方案

    這篇文章主要介紹了CLOSE_WAIT狀態(tài)解決方案,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C/C++中輸入多組數(shù)據(jù)的方法

    C/C++中輸入多組數(shù)據(jù)的方法

    這篇文章主要為大家詳細(xì)介紹了C/C++中輸入多組數(shù)據(jù)的三種方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • C/C++位操作實(shí)例總結(jié)

    C/C++位操作實(shí)例總結(jié)

    這篇文章主要介紹了C/C++位操作實(shí)例總結(jié),是C/C++程序設(shè)計(jì)中很重要的概念,需要的朋友可以參考下
    2014-08-08

最新評(píng)論