今天又來寫一篇C的文章,這里要講的是C語言中的幾個內(nèi)存函數(shù),主要是講解功能和用法,望能耐心觀看哦。望官方也多多曝光。
目錄
memcpy
?memmove
memset
?memcmp
memcpy
?memcpy??是?C?語言標(biāo)準(zhǔn)庫中的一個函數(shù),用于復(fù)制內(nèi)存塊的內(nèi)容。它的主要作用是將一個源內(nèi)存區(qū)域的內(nèi)容復(fù)制到另一個目標(biāo)內(nèi)存區(qū)域,且是按照所給字節(jié)數(shù)進(jìn)行復(fù)制。
?
函數(shù)原型:
?
?
void?*memcpy(void?*dest,?const?void?*src,?size_t?n);
?
參數(shù)說明:
?
?dest?:指向目標(biāo)內(nèi)存區(qū)域的指針,復(fù)制的結(jié)果將存儲在這個位置。
? src?:指向源內(nèi)存區(qū)域的指針,要復(fù)制的內(nèi)容將從這個位置讀取。
? n?:要復(fù)制的字節(jié)數(shù)。
?
函數(shù)行為:
?
1.??memcpy??會從源內(nèi)存區(qū)域復(fù)制指定數(shù)量的字節(jié)到目標(biāo)內(nèi)存區(qū)域。
2.?復(fù)制是按字節(jié)進(jìn)行的,不考慮數(shù)據(jù)類型或字節(jié)序。
3.?函數(shù)返回指向目標(biāo)內(nèi)存區(qū)域的指針。
?
代碼使用例子:
#include <stdio.h>
#include <string.h>
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;
}
?
代碼解析:上面代碼中我們調(diào)用函數(shù)memcpy函數(shù),進(jìn)行傳參,將arr1前20個字節(jié)的內(nèi)容,復(fù)制到arr2中。根據(jù)結(jié)果確實如此,20個字節(jié)為5個整形元素大小,所以這里從arr1中1,2,3,4,5 復(fù)制到arr2中,至于后面的5個0,是因為在VS中如果未對數(shù)組中進(jìn)行初始化的元素,會默認(rèn)為0.
為了讓大家更了解這個函數(shù),這里為大家模擬實現(xiàn)一下memcpy函數(shù):
void* Memcpy(void* dst, const void* src, size_t count)
{
void* ret = dst;
assert(dst);
assert(src);
/*
* copy from lower addresses to higher addresses
*/
while (count--) {
*(char*)dst = *(char*)src;
dst = (char*)dst + 1;
src = (char*)src + 1;
}
return(ret);
}
這里面強(qiáng)制轉(zhuǎn)化為char*的指針是因為讓指針dst和src都是一個一個字節(jié)的往后訪問。?
?需要注意的是:memcpy是不能對兩個有重疊部分的指針完成準(zhǔn)確的復(fù)制的,所以我們需要看下一個有重疊部分也可以完成操作的函數(shù)memmove。
?memmove
?memmove??是?C?語言標(biāo)準(zhǔn)庫中的一個函數(shù),它與??memcpy??類似,用于復(fù)制內(nèi)存塊的內(nèi)容。與??memcpy??不同的是,?memmove??可以在源和目標(biāo)內(nèi)存區(qū)域有重疊的情況下安全地進(jìn)行復(fù)制。
?
函數(shù)原型:
?
?
void?*memmove(void?*dest,?const?void?*src,?size_t?n);
?
?參數(shù)說明:
?
?dest?:指向目標(biāo)內(nèi)存區(qū)域的指針,復(fù)制的結(jié)果將存儲在這個位置。
? src?:指向源內(nèi)存區(qū)域的指針,要復(fù)制的內(nèi)容將從這個位置讀取。
? n?:要復(fù)制的字節(jié)數(shù)。
?
函數(shù)行為:
?
1.??memmove??用于在不同的內(nèi)存位置之間復(fù)制數(shù)據(jù),即使源和目標(biāo)區(qū)域有重疊也能正確工作。
2.?它會根據(jù)源和目標(biāo)的相對位置,以適當(dāng)?shù)姆绞綇?fù)制數(shù)據(jù),確保結(jié)果是正確的。
?
代碼簡單使用例子:
#include <stdio.h>
#include <string.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
memmove(arr1 + 2, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
?
代碼解析:這里很明顯即使我們調(diào)用memmove函數(shù)時傳過去的指針地址是明顯有重疊部分的,但是這里我們看見結(jié)果確實是沒問題的,將arr的前20個字節(jié)即5個元素復(fù)制到arr+2往后的元素。?
還是為了大家更好理解函數(shù)的邏輯,給大家模擬實現(xiàn)一下memmove函數(shù) :
void* memmove(void* dst, const void* src, size_t count)
{
void* ret = dst;
if (dst <= src || (char*)dst >= ((char*)src + count)) {
/*
* Non-Overlapping Buffers
* copy from lower addresses to higher addresses
*/
while (count--) {
*(char*)dst = *(char*)src;
dst = (char*)dst + 1;
src = (char*)src + 1;
}
}
else {
/*
* Overlapping Buffers
* copy from higher addresses to lower addresses
*/
dst = (char*)dst + count - 1;
src = (char*)src + count - 1;
while (count--) {
*(char*)dst = *(char*)src;
dst = (char*)dst - 1;
src = (char*)src - 1;
}
}
return(ret);
}
?這里面強(qiáng)制轉(zhuǎn)化為char*的指針是因為讓指針dst和src都是一個一個字節(jié)的往后訪問。?
memset
?memset??是?C?語言標(biāo)準(zhǔn)庫中的一個函數(shù),用于將指定的內(nèi)存區(qū)域填充為特定的值。
?
函數(shù)原型:
?
?
void?*memset(void?*str,?int?c,?size_t?n);
?
?
參數(shù)說明:
?
?str?:指向要填充的內(nèi)存區(qū)域的指針。
?c?:要填充的特定值。通常是一個整數(shù)類型的值。
?n?:要填充的字節(jié)數(shù)。
?
函數(shù)行為:
?
1.??memset??使用指定的值??c??填充內(nèi)存區(qū)域的前??n??個字節(jié)。
2.?填充是按字節(jié)進(jìn)行的,無論內(nèi)存區(qū)域的實際數(shù)據(jù)類型如何。
?
簡單代碼使用例子:
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "hello world";
memset(str, 'x', 6);
printf(str);
return 0;
}
?
函數(shù)較為簡單就不多加解釋了。?
?memcmp
memcmp是一個用于比較內(nèi)存區(qū)域的函數(shù)
?函數(shù)原型:
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
?
參數(shù)說明:兩個需要比較的內(nèi)存塊的起始地址?ptr1?和?ptr2,以及需要比較的字節(jié)數(shù)?num。
函數(shù)行為:
函數(shù)會比較?ptr1?和?ptr2?指向的內(nèi)存塊前?num?個字節(jié)的內(nèi)容,返回值為整型,表示比較結(jié)果:如果兩個內(nèi)存塊的前?num?個字節(jié)完全相等,則返回0;如果?ptr1?指向的內(nèi)存塊小于?ptr2?指向的內(nèi)存塊,則返回負(fù)數(shù);如果?ptr1?指向的內(nèi)存塊大于?ptr2?指向的內(nèi)存塊,則返回正數(shù)。
?
代碼簡單實用例子:
#include <stdio.h>
#include <string.h>
int main()
{
char buffer1[] = "hello";
char buffer2[] = "good";
int n;
n = memcmp(buffer1, buffer2, sizeof(buffer1));
if (n > 0)
printf("'%s' 比 '%s'大.\n", buffer1, buffer2);
else if (n < 0)
printf("'%s' 比 '%s'小.\n", buffer1, buffer2);
else
printf("'%s' 與 '%s'一樣大.\n", buffer1, buffer2);
return 0;
}
?文章來源:http://www.zghlxwxcb.cn/news/detail-835314.html
今天文章就結(jié)束了,覺得有用,可以點(diǎn)個贊再走唔。?文章來源地址http://www.zghlxwxcb.cn/news/detail-835314.html
到了這里,關(guān)于來不及哀悼了,接下來上場的是C語言內(nèi)存函數(shù)memcpy,memmove,memset,memcmp的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!