詳解C語言的mem系列函數(shù)
1.memchr
memchr的函數(shù)聲明:
void *memchr(const void *str, int c, size_t n);
作用:
memchr函數(shù)從str位置后的n個(gè)位置開始尋找,尋找第一個(gè)和c相同的字符。如果成功,memchr函數(shù)返回一個(gè)指向該字符位置的指針,如果沒有沒有找到指定字符,則返回NULL。
實(shí)例:
#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ù)的實(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; }
注意事項(xiàng):形參中的c是一個(gè)無符號(hào)字符。
2.memcmp
函數(shù)的聲明:
int memcmp( const void *buf1, const void *buf2, size_t count );
作用:
memcmp用于比較buf1 和 buf2 的前count個(gè)字節(jié)進(jìn)行比較,如果buf1大于buf2,該函數(shù)返回一個(gè)正數(shù),如果小于則返回一個(gè)負(fù)數(shù),相等則返回0。
實(shí)例:
#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ù)的實(shí)現(xiàn):
首先我們需要了解memcmp是怎么比較大小的。通過不斷地調(diào)整上面實(shí)例的兩個(gè)字符串,我發(fā)現(xiàn),該函數(shù)是從第一個(gè)字節(jié)開始比較,如果相同,則繼續(xù)比較下一個(gè)字節(jié),如果有大小差異,則將這兩個(gè)字節(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);//這里要 -- 是因?yàn)樯厦娴淖詈筮€++了一下 }
3.memcpy
函數(shù)的聲明:
void *memcpy( void *dest, const void *src, size_t count );
作用:
該函數(shù)將 src 的 count 個(gè)字節(jié)復(fù)制到 dest。該函數(shù)返回 dest 的起始位置。
實(shí)例:
#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ù)的實(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類似。但是為什么會(huì)有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; }
我們可能認(rèn)為答案是 1 2 3 1 2 3 4 5 6 7
但是vs2022給出的結(jié)果是
這是因?yàn)椋瑑?nèi)存只有一塊,可能會(huì)沖突 。比如 4 這個(gè)位置,一開始 4 被修改為 1 ,再后來,當(dāng)dest指針指到這個(gè)1的時(shí)候,他又會(huì)把這個(gè)1放到后面的位置。而memmove就能解決這個(gè)問題。
它是如何解決的呢?
對(duì)于剛才這種情況,我們發(fā)現(xiàn) dest(紅) 大于 src(藍(lán)),如果我們從左開始,往右開始修改,那么肯定會(huì)出現(xiàn)剛才那種情況,但是如果是從右往左呢? 思考后我們發(fā)現(xiàn),這是可行的,就好像右邊的人在追左邊的人,然后左邊的人不斷地往后丟東西,都丟在右邊的人的身上。同時(shí),我們發(fā)現(xiàn),如果src(藍(lán))的最右端超過了dest(紅)的最右端,這種方法好像又不適用了,也不能再從右往左了。
我們知道 ,dest和src的大小應(yīng)該都是count,所以不存在上面這種情況。
那就可以開始具體實(shí)現(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)存為具體值。
實(shí)例:
#include <stdio.h> #include <string.h> int main() { char p[20] = "what is csdn"; memset(p, '#', 4); printf("%s", p); return 0; }
函數(shù)實(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++與QML進(jìn)行數(shù)據(jù)交互的常見方法總結(jié)
這篇文章主要為大家詳細(xì)介紹了C++與QML進(jìn)行數(shù)據(jù)交互的常見方法,文中 的示例代碼講解詳細(xì),具有一定的參考價(jià)值,有需要的小伙伴可以跟隨小編一起了解一下2023-10-10C語言實(shí)現(xiàn)的排列組合問題的通用算法、解決方法
這篇文章主要介紹了C語言實(shí)現(xiàn)的排列組合問題的通用算法、解決方法,本文使用C語言實(shí)現(xiàn)在程序中解決這個(gè)問題,需要的朋友可以參考下2014-08-08C語言接口與實(shí)現(xiàn)方法實(shí)例詳解
這篇文章主要介紹了C語言接口與實(shí)現(xiàn)方法,包括接口的概念、實(shí)現(xiàn)方法及抽象數(shù)據(jù)類型等,并配合實(shí)例予以說明,需要的朋友可以參考下2014-09-09C/C++中的?Qt?StandardItemModel?數(shù)據(jù)模型應(yīng)用解析
QStandardItemModel?是標(biāo)準(zhǔn)的以項(xiàng)數(shù)據(jù)為單位的基于M/V模型的一種標(biāo)準(zhǔn)數(shù)據(jù)管理方式,本文給大家介紹C/C++中的?Qt?StandardItemModel?數(shù)據(jù)模型應(yīng)用解析,感興趣的朋友跟隨小編一起看看吧2021-12-12北郵計(jì)算機(jī)考研復(fù)試題的C語言解答精選
這篇文章主要介紹了北郵計(jì)算機(jī)考研復(fù)試題目的C語言解答精選,選自2012年的一些基礎(chǔ)的上機(jī)題目,需要的朋友可以參考下2015-08-08C語言?使用qsort函數(shù)來進(jìn)行快速排序
排序方法有很多種:選擇排序,冒泡排序,歸并排序,快速排序等。?看名字都知道快速排序是目前公認(rèn)的一種比較好的排序算法。因?yàn)樗俣群芸?,所以系統(tǒng)也在庫里實(shí)現(xiàn)這個(gè)算法,便于我們的使用。?這就是qsort函數(shù)2022-02-02