柚子快報邀請碼778899分享:學習 C語言——內存函數(shù)
柚子快報邀請碼778899分享:學習 C語言——內存函數(shù)
在之前我們已經(jīng)學習了字符的相關函數(shù),例如strcpy;strcat等,但如果我們要實現(xiàn)除字符類型外的數(shù)據(jù)時,這些函數(shù)就無法使用了,這時就要用到c語言中的內存函數(shù)了,內存函數(shù)就可以實現(xiàn)對整型;結構體類型等數(shù)據(jù)的處理了,接下來就一起來了解這些函數(shù)的作用以及使用方法吧! ?
1.memcpy
1.1memcpy的作用以及使用
首先來了解memcpy的作用是拷貝內存塊,將源空間的內存拷貝num字節(jié)到目標空間內存當中,且在拷貝過程中能指定想要拷貝的字節(jié)個數(shù),因此在該函數(shù)的參數(shù)有三個,第一個參數(shù)是目標空間的起始址,第二個是源空間的起始地址,最后一個參數(shù)是想要拷貝的字節(jié)數(shù)
同時該函數(shù)的返回值是目標空間的起始地址
注: ? 這個函數(shù)在遇到 '\0' 的時候并不會停下來。? ? ? ?? 如果source和destination有任何的重疊,復制的結果都是未定義的。
#include
#include
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
memcpy(arr2, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
例如以上代碼中就是將arr1中的前面20個字節(jié)拷貝到arr2中,也就是將arr1中的前5個元素拷貝到arr2中
?但注意memcpy無法實現(xiàn)在同一塊內存空間內兩個重疊空間的之間拷貝,例如在以上arr1中就無法將內存中的1 2 3 4 5拷貝到3 4 5 6 7,要實現(xiàn)這種情況的拷貝就要使用到memmove再下文中會講解到
1.2memcpy的模擬實現(xiàn)?
以下的模擬實現(xiàn)有什么錯誤的地方嗎?
void* my_memcpy(void* dest, const void* src,size_t num)
{
assert(dest && src);
void* str = dest;
while (num--)
{
*((char*)dest) = *((char*)src);
((char*)dest)++ ;
((char*)src)++ ;
}
return str;
}
以上的代碼在運行時程序是會報錯的,原因是dest和src原來的類型是void*,是不能進行解引用的,而且在進行強制類型轉換為char*后也只能進行一次轉換,后置++這次就不可使用了
這時就需把以上代碼修改為以下形式?
void* my_memcpy(void* dest, const void* src,size_t num)
{
assert(dest && src);
void* str = dest;
while (num--)
{
*((char*)dest) = *((char*)src);
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return str;
}
2.memmove
2.1memmove的作用以及使用
memmove的功能也是實現(xiàn)內存塊的拷貝,將源空間的內存拷貝num字節(jié)到目標空間內存當中,且在拷貝過程中能指定想要拷貝的字節(jié)個數(shù),函數(shù)的參數(shù)和memcpy相同,因此在該函數(shù)的參數(shù)也有三個,第一個參數(shù)是目標空間的起始址,第二個是源空間的起始地址,最后一個參數(shù)是想要拷貝的字節(jié)數(shù)函數(shù)的參數(shù)和memcpy相同
注:? 和memcpy的差別就是memmove函數(shù)處理的源內存塊和?標內存塊是可以重疊的。? 如果源空間和?標空間出現(xiàn)重疊,就得使?memmove函數(shù)處理。
例如在以上的要將內存中的1 2 3 4 5拷貝到3 4 5 6 7
#include
#include
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;
}
以上代碼輸出結果如下?
2.2 memmove的模擬實現(xiàn)
通過測試發(fā)現(xiàn)memmove確實可以實現(xiàn)重疊內存的拷貝,那么我們應該如何實現(xiàn)memmove的模擬實現(xiàn)呢? 這時在模擬實現(xiàn)之前我們先要來思考拷貝的兩個內存快在不同情況下時從前向后拷貝,還是從后向前拷貝
在這種情況中就需要將源空間的數(shù)據(jù)從后向前拷貝 ?
在這種情況中就需要將源空間的數(shù)據(jù)從前向后拷貝?
使用通過以上的例子就可以發(fā)現(xiàn)拷貝的規(guī)律在src void* my_memmove(void* dest, const void* src,size_t num) { assert(dest && src); void* str = dest; if (dest < src) { while (num--) { *((char*)dest) = *((char*)src); dest = (char*)dest + 1; src = (char*)src + 1; } } else { while (num--) { *((char*)dest+num) = *((char*)src+num); } } return str; } 3.memset memset是用來設置內存的,將內存中的值以字節(jié)為單位設置成想要的內容。在該函數(shù)的參數(shù)有三個,第一個是值指向要填充的內存塊指針,第二個是要設置的值,最后為要設置為該值的字節(jié)數(shù) 該函數(shù)的返回值為要填充空間的指針ptr 使用范例 #include #include int main() { char str[] = "abcdef"; memset(str, 'x', 5); printf("%s", str); return 0; } 將字符串中的前5字節(jié)都設置為x ? 4.memcmp memcmp作用是用來比較從ptr1和ptr2指針指向的位置開始,向后的num個字節(jié) ,mwmcmp的作用于strncmp相識,但strncmp只能對字符類型的數(shù)據(jù)進行比較,而memcmp能針對所有類型數(shù)據(jù)的比較 如果兩個指針對應位置處的數(shù)據(jù)大小,如果相等就繼續(xù)比較下一個指針處的數(shù)據(jù)大小,直到兩個不相等且未超過要比較的字節(jié)數(shù),如果第一個對應位置處的數(shù)據(jù)大就返回大于零的數(shù),如果第二個對應位置處的數(shù)據(jù)大就返回小于零的數(shù),一直到要比較字節(jié)數(shù)內都相等就返回零 #include #include int main() { char buffer1[] = "DWgaOtP12df0"; char buffer2[] = "DWGAOTP12DF0"; int n; n = memcmp(buffer1, buffer2, sizeof(buffer1)); if (n > 0) printf("'%s' is greater than '%s'.\n", buffer1, buffer2); else if (n < 0) printf("'%s' is less than '%s'.\n", buffer1, buffer2); else printf("'%s' is the same as '%s'.\n", buffer1, buffer2); return 0; } ?以上代碼輸出結果是什么呢? sizeof(buffer1)計算的是整個數(shù)組的大小,所有使用memcmp是對buffer1和buffer2兩個數(shù)組全部元素的比較,在數(shù)組buffer1與buffer2中前面兩元素都為DW,所以到第三個才能比較出大小,因為g的Ascll值大于G所以mwmcmp返回值大于0,之后程序進入n>0的if語句 最終輸出'DWgaOtP12df0' is greater than 'DWGAOTP12DF0'. 柚子快報邀請碼778899分享:學習 C語言——內存函數(shù) 參考文章
本文內容根據(jù)網(wǎng)絡資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉載請注明,如有侵權,聯(lián)系刪除。