詳解C語言的mem系列函數(shù)
1.memchr
memchr的函數(shù)聲明:
void *memchr(const void *str, int c, size_t n);
作用:
memchr函數(shù)從str位置后的n個位置開始尋找,尋找第一個和c相同的字符。如果成功,memchr函數(shù)返回一個指向該字符位置的指針,如果沒有沒有找到指定字符,則返回NULL。
實例:
#include <stdio.h>
#include <string.h>
int main()
{
const char* a = "my blog";
if (memchr(a, 'g', 7) != NULL)
printf("g is found\n");
if (memchr(a, 'g', 2) != NULL)
printf("g is found\n");
return 0;
}函數(shù)的實現(xiàn):
?void* my_memchr(const char* str,int c,size_t n)
{
assert(str != NULL);
while ((n--) && (*(str++) - c));
if (!(*str - c))
return NULL;
return str;
}注意事項:形參中的c是一個無符號字符。
2.memcmp
函數(shù)的聲明:
int memcmp( const void *buf1, const void *buf2, size_t count );
作用:
memcmp用于比較buf1 和 buf2 的前count個字節(jié)進行比較,如果buf1大于buf2,該函數(shù)返回一個正數(shù),如果小于則返回一個負數(shù),相等則返回0。
實例:
#include <stdio.h>
#include <string.h>
int main()
{
char str1[15];
char str2[15];
int ret;
memcpy(str1, "aBcDDDD", 8);
memcpy(str2, "aBCdddd", 8);
ret = memcmp(str1, str2, 7);
printf("%s ", str1);
if (ret > 0)
printf("大于");
else if (ret < 0)
printf("小于");
else
printf("等于");
printf(" %s\n", str2);
return 0;
}函數(shù)的實現(xiàn):
首先我們需要了解memcmp是怎么比較大小的。通過不斷地調(diào)整上面實例的兩個字符串,我發(fā)現(xiàn),該函數(shù)是從第一個字節(jié)開始比較,如果相同,則繼續(xù)比較下一個字節(jié),如果有大小差異,則將這兩個字節(jié)的大小差異作為結(jié)果輸出。
int my_memcmp(const void* buf1,const void *buf2,size_t count)
{
assert(buf1 && buf2);
while ((count--) && !(*(((char*)buf1)++) - *(((char*)buf2)++)));
return *(--(char*)buf1) - *(--(char*)buf2);//這里要 -- 是因為上面的最后還++了一下
}3.memcpy
函數(shù)的聲明:
void *memcpy( void *dest, const void *src, size_t count );
作用:
該函數(shù)將 src 的 count 個字節(jié)復制到 dest。該函數(shù)返回 dest 的起始位置。
實例:
#include <stdio.h>
#include <string.h>
int main()
{
char arr[50] = { 0 };
char* b = "csdn.com";
memcpy(arr, b, strlen(b));
printf("%s", arr);
return 0;
}函數(shù)的實現(xiàn):
void* my_memcpy(void* a, const void* b, size_t count)
{
assert(a && b);
void* ret = a;
while (count--)
{
*(char*)a = *(char*)b;
a = (char*)a + 1;
b = (char*)b + 1;
}
return ret;
}4.memmove
函數(shù)聲明:
void *memmove( void *dest, const void *src, size_t count );
作用:
該函數(shù)的作用和memcpy類似。但是為什么會有memmove呢?
我們看下面這段代碼
#include <stdio.h>
#include <string.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
memcpy(arr + 3, arr, 7);
int i = 0;
for (i = 0; i < 10; i++)
printf("%d ", arr[i]);
return 0;
}我們可能認為答案是 1 2 3 1 2 3 4 5 6 7
但是vs2022給出的結(jié)果是

這是因為,內(nèi)存只有一塊,可能會沖突 。比如 4 這個位置,一開始 4 被修改為 1 ,再后來,當dest指針指到這個1的時候,他又會把這個1放到后面的位置。而memmove就能解決這個問題。
它是如何解決的呢?

對于剛才這種情況,我們發(fā)現(xiàn) dest(紅) 大于 src(藍),如果我們從左開始,往右開始修改,那么肯定會出現(xiàn)剛才那種情況,但是如果是從右往左呢? 思考后我們發(fā)現(xiàn),這是可行的,就好像右邊的人在追左邊的人,然后左邊的人不斷地往后丟東西,都丟在右邊的人的身上。同時,我們發(fā)現(xiàn),如果src(藍)的最右端超過了dest(紅)的最右端,這種方法好像又不適用了,也不能再從右往左了。

我們知道 ,dest和src的大小應該都是count,所以不存在上面這種情況。
那就可以開始具體實現(xiàn)了。
void* my_memmove(void* a,const void* b,size_t count) //a:dest b:source
{
assert(a && b);
void* ret = a;
//s<d 從右往左
if (b < a)
{
a = (char*)a + count - 1;
b = (char*)b + count - 1;
while (count--)
{
*(char*)a = *(char*)b;
a = (char*)a - 1;
b = (char*)b - 1;
}
}
else
{
while (count--)
{
*(char*)a = *(char*)b;
a = (char*)a + 1;
b = (char*)b + 1;
}
}
return ret;
}5.memset
函數(shù)聲明:
void *memset( void *dest, int c, size_t count );
作用:就是可以初始化一塊內(nèi)存為具體值。
實例:
#include <stdio.h>
#include <string.h>
int main()
{
char p[20] = "what is csdn";
memset(p, '#', 4);
printf("%s", p);
return 0;
}函數(shù)實現(xiàn):
void* my_memset(void* dest, int c, size_t count)
{
void* tmp = dest;
while (count--)
*(((char*)dest)++) = (char)c;
return tmp;
}總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
C++中priority_queue與仿函數(shù)實現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于C++中priority_queue與仿函數(shù)實現(xiàn)的相關(guān)資料,優(yōu)先級隊列是一種容器適配器,其底層通常采用vector容器,并通過堆算法來維護元素的順序,文中通過代碼介紹的非常詳細《》需要的朋友可以參考下2024-10-10

