1.memcpy
功能:把source指向的前num個字節(jié)內容拷貝到destination指向的位置去,可以拷貝任意類型的數(shù)據(jù)。
注:1.memcpy并不關心\0,畢竟傳的也不一定是字符串,因此拷貝過程中遇到\0也不會停下來。
2.num的單位是字節(jié),并不是要拷貝的元素個數(shù)
3.如果source和destination有任何的重疊,拷貝的結果都是未定義的。什么意思呢?舉個例子,我現(xiàn)在要把arr1中的12345拷貝到34567的位置上去。
打印結果卻并沒有如愿,這是因為當我們把1拷貝到了3的位置上,2拷貝到了4的位置上,數(shù)組arr1的內容已經(jīng)被改變了,當我們要拷貝3到5的位置上時,3已經(jīng)變成了1,于是就把1拷貝過去了。于是出現(xiàn)了上圖所示的情況。
也就是說memcpy只用于處理不重疊內存的數(shù)據(jù)。
模擬實現(xiàn)memcpy
像這種能夠操作各種類型數(shù)據(jù)的函數(shù),其底層實現(xiàn)原理基本上都和char*類型的指針有關系,比如memcpy,還有我們前面已經(jīng)模擬實現(xiàn)過的庫函數(shù)qsort。因為char*類型的指針走一步就跳過一個字節(jié),字節(jié)又是內存單元的最小單位,不管是什么類型的數(shù)據(jù),只要一個字節(jié)一個字節(jié)的操作,最終都可以達成目的。
因此在這里我們就把des和src兩個指針強制類型轉換成char*類型的,然后解引用對他們指向的那一個字節(jié)單元的內容進行賦值操作,賦值完一個字節(jié)之后再進行下一個字節(jié)單元的操作。注意強制類型轉換只是一個臨時的操作,并不是說我們在進行賦值的時候把des和src強制類型轉換成char*類型的了,他就一直是char*類型的了,因此要讓des和src指向下一個字節(jié)單元,應該寫成des=(char*)des+1。
2.memmove
功能:也是拷貝內存數(shù)據(jù)
和memcpy的差別就是memmove函數(shù)處理的源內存塊和目標內存塊是可以重疊的。如果源空間和目標空間出現(xiàn)重疊,就得使用memmove函數(shù)處理。
像剛才那個例子,我們就可以使用memmove解決
模擬實現(xiàn)memmove
思路:要在有重疊的數(shù)據(jù)里面實現(xiàn)拷貝,最大的問題就是在拷貝的過程中會改變原來位置的內容,第一想法是可以申請一塊內存在里面存放原本數(shù)據(jù)的相同內容,這樣當然可以,但是第一這種寫法比較麻煩,第二會造成內存的浪費。能不能不申請內存就實現(xiàn)在同一塊內存中拷貝內容呢?
當然可以,舉個例子,12345678這串數(shù)字,現(xiàn)在我要把345處的內容拷貝成123,也就是最終讓數(shù)字變成12123678,此時des在src的后面,如果我先把1拷貝到3的位置,那么后面在想把3拷貝到6處時就很尷尬,因為此時的3已經(jīng)變成了1,但是如果我倒著拷貝,先把3拷貝到6的地方,再把2拷貝到5的地方,再把1拷貝到3的地方,不就行了嗎?
再舉一個例子,如果我要把345拷貝到123的位置,此時des在src的前面,我們直接把3拷貝到1的位置,4拷貝到2的位置,5拷貝到3的位置即可。
也就是說,如果dessrc,就從后往前拷貝。如果兩塊數(shù)據(jù)沒有重疊,那從前或者從后都可以。
在代碼中從后往前找的時候,先判斷num是否為0,然后--,第一次的時候num是20,進入循環(huán)之后已經(jīng)--了,變成了19,因此(char*)des + num與(char*)src + num都指向了最后一個要拷貝的位置。并隨著num的減小不斷指向前面位置。文章來源:http://www.zghlxwxcb.cn/news/detail-826535.html
注:memcpy能做的,memmove都能做。但是memmove能做的,memcpy不一定能做。文章來源地址http://www.zghlxwxcb.cn/news/detail-826535.html
到了這里,關于【C語言】內存函數(shù)memcpy和memmove的功能與模擬實現(xiàn)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!