網站首頁 編程語言 正文
1.memchr
memchr的函數聲明:
void *memchr(const void *str, int c, size_t n);
作用:
?memchr函數從str位置后的n個位置開始尋找,尋找第一個和c相同的字符。如果成功,memchr函數返回一個指向該字符位置的指針,如果沒有沒有找到指定字符,則返回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; }
函數的實現:
?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
函數的聲明:
int memcmp( const void *buf1, const void *buf2, size_t count );
作用:
memcmp用于比較buf1 和 buf2 的前count個字節進行比較,如果buf1大于buf2,該函數返回一個正數,如果小于則返回一個負數,相等則返回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; }
函數的實現:
首先我們需要了解memcmp是怎么比較大小的。通過不斷地調整上面實例的兩個字符串,我發現,該函數是從第一個字節開始比較,如果相同,則繼續比較下一個字節,如果有大小差異,則將這兩個字節的大小差異作為結果輸出。
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
函數的聲明:
void *memcpy( void *dest, const void *src, size_t count );
作用:
該函數將 src 的 count 個字節復制到 dest。該函數返回 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; }
函數的實現:
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
函數聲明:
void *memmove( void *dest, const void *src, size_t count );
作用:
該函數的作用和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給出的結果是
這是因為,內存只有一塊,可能會沖突?。比如 4? 這個位置,一開始 4 被修改為 1 ,再后來,當dest指針指到這個1的時候,他又會把這個1放到后面的位置。而memmove就能解決這個問題。
它是如何解決的呢?
對于剛才這種情況,我們發現 dest(紅) 大于 src(藍),如果我們從左開始,往右開始修改,那么肯定會出現剛才那種情況,但是如果是從右往左呢???思考后我們發現,這是可行的,就好像右邊的人在追左邊的人,然后左邊的人不斷地往后丟東西,都丟在右邊的人的身上。同時,我們發現,如果src(藍)的最右端超過了dest(紅)的最右端,這種方法好像又不適用了,也不能再從右往左了。
我們知道 ,dest和src的大小應該都是count,所以不存在上面這種情況。
那就可以開始具體實現了。
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
函數聲明:
void *memset( void *dest, int c, size_t count );
作用:就是可以初始化一塊內存為具體值。
實例:
#include <stdio.h> #include <string.h> int main() { char p[20] = "what is csdn"; memset(p, '#', 4); printf("%s", p); return 0; }
函數實現:
void* my_memset(void* dest, int c, size_t count) { void* tmp = dest; while (count--) *(((char*)dest)++) = (char)c; return tmp; }
總結
原文鏈接:https://blog.csdn.net/roseisbule/article/details/122754823
相關推薦
- 2022-03-07 axios和ajax的區別點總結_AJAX相關
- 2023-06-05 Qt利用QNetwork實現上傳數據的示例代碼_C 語言
- 2022-07-24 python單向循環鏈表實例詳解_python
- 2022-03-23 C語言新手初階教程之三子棋實現_C 語言
- 2023-11-15 【深度學習】YOLOv5斷點訓練——中斷后繼續訓練
- 2023-05-13 python中flatten()函數用法詳解_python
- 2022-07-29 C++數據結構之單鏈表的實現_C 語言
- 2023-01-23 C#實現懸浮窗口的方法詳解_C#教程
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支