引言
本文介紹memcpy的使用和模擬實現、memmove的使用和模擬實現、memcmp使用、memset使用
?
? ? ? ? ? ? ? ???豬巴戒:個人主頁?
???????????????所屬專欄:《C語言進階》
? ? ? ? 🎈跟著豬巴戒,一起學習C語言🎈
目錄
引言
memcpy
memcpy的使用
memcpy的模擬實現
memmove
memcpy函數不用來處理重疊的內存的數據拷貝:
memmove的模擬實現
?總結:
?模擬實現代碼
memcmp
memset
memcpy
void * memcpy ( void * destination, const void * source, size_t num )
- memcpy的作用就是將source的內容拷貝到destination
- num說明了拷貝多少個字節
- 返回值是destination.
memcpy的使用
#include<stdio.h>
#include<string.h>
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[20] = { 0 };memcpy(arr2, arr1, 20);int i = 0;for (i = 0; i < 5; i++){printf("%d ", arr2[i]);}return 0;
}
?
memcpy的模擬實現
?內存函數就是無論是什么類型的數據都可以使用。
void* ,屬于通用類型的指針,可以存放任意類型的地址。
assert,斷言,保證dest和source不是空指針。
num是需要拷貝的字節數。
通過將地址轉化為(char*)的形式,將需要拷貝的內容一個字節一個字節地將它們拷貝,就可以實現各種數據的拷貝。
然后dest轉移到下一個字節,source轉移到下一個字節,知道拷貝完num個字節算結束。
#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dest, const void* source, size_t num)
{assert(dest && source);void* start = dest;while (num--){*(char*)dest = *(char*) source;dest = (char*)dest + 1;source = (char*)source + 1;}return start;
}
memmove
void * memmove ( void * destination, const void * source, size_t num )
- 和memcpy的差別就是memmove函數處理的源內存塊和?標內存塊是可以重疊的。
- 參數和memcpy是一樣的。?
memcpy函數不用來處理重疊的內存的數據拷貝:
將arr1數組改成{1,2,1,2,3,4,5,8,9,10},從第三位元素開始,拷貝自己的第一到第五個元素
#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dest, const void* source, size_t num)
{assert(dest && source);void* start = dest;while (num--){*(char*)dest = *(char*) source;dest = (char*)dest + 1;source = (char*)source + 1;}return start;
}
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };my_memcpy(arr1 + 2, arr1, 20);int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}return 0;
}
?
memcpy在重疊內存拷貝的時候,第三個元素被改成1,第四個元素被改成2,
而第五個元素本來是應該賦值為3的,但是第三個元素已經被改成1了。
第六個元素本來是由第四個元素重新賦值,但是第四個元素被改成了2.
?
memmove的模擬實現
如果說我們要將紅色部分拷貝到藍色部分
從前向后拷貝不行,我們要將紅色的部分拷貝到藍色的部分,先將第一個元素拷貝到第三個元素,紅色區域的內存被改變,等到將第三個元素拷貝到第五個元素的時候,第三個元素已經發生改變。
從后向前拷貝,如果我們可以先將第五個元素拷貝到第七個元素,這樣紅色的三、四、五元素先拷貝完后被改變就可以把數值3,4,5成功傳到第五、六、七個元素。
?
?這一次,
從后向前拷貝不行,我們要將紅色部分拷貝到藍色的部分,先將第七個元素拷貝到第五個元素,首先改變了第五個元素的內容,到時候第五個元素還要對第三個元素進行拷貝。
從前向后拷貝,如果我們先將第三個元素拷貝到第一個元素,等輪到第三個元素進行拷貝的時候,第三個元素里的內容已經轉出去了,轉到第一個元素了,那么第三個元素的內容就可以隨便修改了。
?
?總結:
為了保證source中的數據在拷貝之前就被修改,
- 當dest在source的右邊的時候,采用從后向前的方式
- 當dest在source的左邊的時候,采用從前向后的方式
?模擬實現代碼
#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest, const void* source, size_t num)
{assert(dest && source);void* start = dest;if (dest < source){//從前向后while (num--){*(char*)dest = *(char*)source;dest = (char*)dest + 1;source = (char*)source + 1;}}else{//從后向前拷貝while (num--){*((char*)dest + num) = *((char*)source + num);}}return start;
}
memcmp
可以比較任意類型的數據
int memcmp ( const void * ptr1, const void * ptr2, size_t num )
- ptr1指向的第一個空間
- ptr2指向的第二塊空間
- ptr1和ptr2之間的內存比較
- num表示需要比較的字節大小
?
?arr1和arr2比較,arr1比arr2小,返回小于0的數值。
int main()
{int arr1[] = { 1,2,3,4,5 };int arr2[] = { 1,3,2 };int ret = memcmp(arr1, arr2, 12);printf("%d", ret);return 0;
}
??
memset
void * memset ( void * ptr, int value, size_t num )
- ptr需要填充的地址空間
- value,填充什么字符
- num,填充幾個字節
#include<stdio.h>
#include<string.h>
int main()
{char arr[] = "hello world";memset(arr, 'x', 5);printf("%s\n", arr);return 0;
}
?