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

memcpy
void * memcpy ( void * destination, const void * source, size_t num );
這是一個內(nèi)存復(fù)制函數(shù),該函數(shù)會從source的位置開始向后復(fù)制num個字節(jié)的數(shù)據(jù)到destination的內(nèi)存位置。
這個函數(shù)在遇到 ‘\0' 的時候并不會停下來。
用法如下:
#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)容,以免造成越界。
模擬實現(xiàn)如下:
//memcpy的模擬實現(xiàn)
#include<stdio.h>
#include<string.h>
#include<assert.h>
//不會考慮內(nèi)存重疊的情況
void* my_memcpy(void* dest, const void* source, size_t nums) {
//先記錄下dest的初始位置,便于后續(xù)返回
void* ret = dest;
//判斷傳入的兩個指針是否為空
assert(dest, source);
//利用循環(huán)來控制拷貝字節(jié)的個數(shù)
while (nums--) {
//由于傳入的是void*類型的指針,所以在使用前要強制轉(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 );
這個函數(shù)是用來比較指定字節(jié)數(shù)的內(nèi)存空間是否相同。
返回值如下:

上圖來自于這里
當(dāng)ptr1的內(nèi)容小于ptr2的內(nèi)容,就返回一個小于零的數(shù),當(dāng)ptr1的內(nèi)容大于ptr2的內(nèi)容,就返回一個大于零的數(shù),相等則返回零。
由于用法比較簡單,就不進行演示啦!
模擬實現(xiàn)如下:
#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_memcmp(const void* p1, const void* p2, size_t num) {
//判斷傳入的兩個指針是否為空
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這個函數(shù)就會出現(xiàn)錯誤,為了避免出錯,我們就來學(xué)習(xí)一下memmove這個函數(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會變成{3,4,5,6,5,6,7,8,9,10}
這個函數(shù)的模擬實現(xiàn)要分情況討論
1.如果dest在source前面,那么就有可能會出現(xiàn)有一部分內(nèi)存重疊的情況,我們就需要在source中,先拷貝前面的數(shù)據(jù)在拷貝后面的數(shù)據(jù),即從前往后拷貝。
2.如果dest在source后面,兩個指針相減的數(shù)值小于要移動的字節(jié)數(shù),那么也會有內(nèi)存重疊的情況,那么此時,我們就需要先拷貝后面的數(shù)據(jù),在拷貝前面的數(shù)據(jù),即從后向前拷貝。
3.如果dest與source之間的差值大于要拷貝的字節(jié)數(shù),那么此時就屬于是兩塊不重疊的內(nèi)存之間的拷貝,此時即使是用memcpy也不會有問題。
綜上,我們可以已dest在source前后作為分界線。
如果dest在source前面,那么我們就從前往后拷貝,如果dest在source后面,那么我們就從后往前拷貝。
具體代碼實現(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在第一次進入循環(huán)的時候已經(jīng)減過1了
*((char*)dest + num)= *((char*)source + num);
}
}
return ret;
}
memset
void * memset ( void * ptr, char value, size_t num );
這個函數(shù)一般用于初始化一段內(nèi)存。
我們只需要傳入內(nèi)存空間的地址,需要初始化的字符,還有需要初始化的字節(jié)數(shù)即可。
由于這個函數(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)容!
- C語言的字符串函數(shù),內(nèi)存函數(shù)筆記詳解
- c語言重要的字符串與內(nèi)存函數(shù)
- C語言詳解如何應(yīng)用模擬字符串和內(nèi)存函數(shù)
- C語言超詳細(xì)講解字符串函數(shù)和內(nèi)存函數(shù)
- C語言深入詳解四大內(nèi)存函數(shù)的使用
- C語言字符串函數(shù),字符函數(shù),內(nèi)存函數(shù)使用及模擬實現(xiàn)
- 深入了解C語言中的字符串和內(nèi)存函數(shù)
- 深度解析三個常見的C語言內(nèi)存函數(shù)
- C語言內(nèi)存函數(shù)的實現(xiàn)示例
- C語言內(nèi)存函數(shù)的具體使用
- C語言實現(xiàn)內(nèi)存函數(shù)的示例代碼
相關(guān)文章
C語言實現(xiàn)linux網(wǎng)卡連接檢測的方法
這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)linux網(wǎng)卡連接檢測的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-06-06
C語言實現(xiàn)簡單學(xué)生選課管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)簡單學(xué)生選課管理系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-02-02
基于linux下C開發(fā)中的幾點技術(shù)經(jīng)驗總結(jié)
本篇文章是對linux下C開發(fā)中的幾點技術(shù)經(jīng)驗總結(jié)進行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05

