目錄
- memcpy
- 模擬memcpy的實作
- memmove
- memmove的模擬實作
- memcmp
- memset
memcpy
從名字中我們就可以猜出這個函式的功能應該是有關記憶體拷貝的,它的基本格式為
void* memcpy(void* dest, const void* src, size_t num);
其中dest為目標記憶體,src為原記憶體,num表示需要拷貝的位元組數,假如我們現在有
arr1[20] = {1,2,3,4,5,6,7,8,9,10};
arr2[20] = {0};
這樣兩個陣列,我們想把arr1中的前四個元素拷貝arr2中應該怎么做呢?我們可以這樣使用這個庫函式
memcpy(arr2, arr1, 10*sizeof(int));
模擬memcpy的實作
void* my_memcpy(void* dest, const void* src, size_t num)
{
int i = 0;
void* ret = dest;
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
memmove
在實際運用時,我們對于那些記憶體有重疊的記憶體拷貝通常使用memmove函式,那么什么是記憶體重疊呢?

注意當我們想把圖中紅色方框內的數字拷貝到藍色方框內時,他們中3和4的記憶體就是重疊的,試想如果利用我們剛剛模擬的my_memcpy來對這個數字進行交換會發生什么是呢?我們會發現首先3會被1覆寫4被2覆寫,目前為止都沒什么問題,但之后給5的位置賦值時我們會發現,剛剛的3已經被賦值為1,所以5和6本應被賦值為3和4,結果最后卻被賦值為1和2,所以我們的my_memcpy其實是不適用有重疊的記憶體拷貝的,但值得一提的是,vs中的memcpy是可以實作這一個功能的,說明vs的功能確實很強大,但筆者還是建議大家在有重疊記憶體拷貝中使用memmove,因為在大多數編譯器底下的memcpy是無法實作這一功能的,所以為了咱們代碼的通用性,還是建議讀者們注意區分
memmove的模擬實作
void* my_memmove(void* dest, const void* src, size_t num)
{
void* ret = dest;
if (dest == src)
{
return ret;
}
while (num--)
{
if (src < dest)
{
*((char*)dest + num) = *((char*)src+num);
}
if (src > dest)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
return 0;
}
關于這些代碼的實作我想仔細地講講他們的邏輯,我們繼續用上面的圖來打比方,

比方說我想把紅色框內的數字拷貝到藍色框內,那我們按順序拷貝顯然不能成功,那我們應該如何實作功能呢?讓我們看看按照倒序來拷貝會不會成功,我們先把4拷貝到6上3到5上,2到4上,1到3上,這樣確實就成功了,那么再讓我們想想,如果想把藍色方框內的數字拷貝到紅色方框內又該怎么做呢?倒序顯然不能解決這個問題了,也就是說在源的記憶體大于目的記憶體時應該用順序排序,那么我們就可以理解這些模擬代碼了
memcmp
這是一個大小比較函式,基本格式為
int memcmp(void* arr1, void* arr2, size_t num);
arr1和arr2是用來比較大小的兩個元素,num是需要比較的位元組數,比方說我們有兩個陣列進行比較
int arr1 = "123";
int arr2 = "124";
int ret = memcmp(arr1, arr2, 9);
printf("%d\n", ret);
arr1和arr2在記憶體中的存放方式為

我們可以看到在這兩個陣列的前八個位元組中的元素都是相等的,而第9個位元組中arr2的值更大,所以該函式會得出arr2更大的結論,所以它會回傳一個負數,也就是說,當函式前面的元素更大時回傳值為正,前面的值小時回傳值為負,相同時回傳0
memset
該函式的功能為,為某片記憶體空間賦值,基本格式
void* memset(void* dest, int c, size_t count);
dest為目標記憶體空間,c為改變的目標值,count為被改變的位元組數
用例
int arr[] = {1,2,3,4,5};
此時arr后的記憶體為

然后我們添加代碼
memset(arr, 1, 20);

此時arr后的記憶體就被重置了
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/301807.html
標籤:其他
上一篇:資料在記憶體中的存盤(一)
下一篇:常用的字串函式詳解
