一篇文章教你自己動(dòng)手實(shí)現(xiàn)C語(yǔ)言庫(kù)函數(shù)
memmove
函數(shù)聲明
void * memmove ( void * destination, const void * source, size_t num );
函數(shù)作用
將num字節(jié)的值從source指向的位置復(fù)制到destination指向的內(nèi)存塊。復(fù)制就像使用了中間緩沖區(qū)一樣進(jìn)行,從而允許目標(biāo)和源重疊。
該函數(shù)不檢查source中是否有任何終止的空字符——它總是精確地復(fù)制num字節(jié)。
為了避免溢出,目標(biāo)和源參數(shù)所指向的數(shù)組的大小必須至少為num字節(jié)。
返回destination。
實(shí)現(xiàn)memmove
#include <stdio.h> #include <string.h> #include <assert.h> //實(shí)現(xiàn)memmove void* my_memmove(void* dst, const void* src, size_t n) { assert(dst && src); char* dst_temp = (char*)dst; char* src_temp = (char*)src; if (src_temp<dst_temp && src_temp + n>dst_temp)//src在dst前,兩者交錯(cuò),需從后往前復(fù)制 { while (n) { *(dst_temp + n - 1 )= *(src_temp + n - 1); n--; } } else { while (n--) { *dst_temp++ = *src_temp++; } } return dst; } int main() { int a[10] = { 0,1,2,3,4,5,6,7,8,9 }; my_memmove(a+2, a, 4*sizeof(int)); for (int i = 0; i < 10; ++i) { printf("%d ", a[i]); } return 0; }
memcpy
函數(shù)聲明
void * memcpy ( void * destination, const void * source, size_t num );
函數(shù)作用
將num個(gè)字節(jié)的值從source所指向的位置開(kāi)始直接復(fù)制到destination所指向的內(nèi)存塊。
該函數(shù)不檢查source中是否有任何終止的空字符——它總是精確地復(fù)制num字節(jié)。
為了避免溢出,目標(biāo)和源參數(shù)所指向的數(shù)組的大小必須至少為num字節(jié),并且不能重疊(對(duì)于重疊的內(nèi)存塊,memmove是一種更安全的方法)。
返回destination。
實(shí)現(xiàn)memcpy
//實(shí)現(xiàn)memcpy void* my_memcpy(void* dst, const void* src, size_t n) { assert(dst && src); char* dst_temp = (char*)dst; char* src_temp = (char*)src; while (n--) { *dst_temp++ = *src_temp++; } return dst; } int main() { int a[10] = { 0,1,2,3,4,5,6,7,8,9 }; my_memcpy(a+2, a, 4*sizeof(int)); for (int i = 0; i < 10; ++i) { printf("%d ", a[i]); } return 0; }
重疊的區(qū)間將會(huì)被提前破壞。
strstr
函數(shù)聲明
char * strstr (char * str1, const char * str2 );
函數(shù)作用
查找子字符串
返回一個(gè)指向str1中第一次出現(xiàn)的str2的指針,如果str2不是str1的一部分,則返回一個(gè)空指針。
匹配過(guò)程不包括結(jié)束空字符,但它在此停止。
實(shí)現(xiàn)strstr
/實(shí)現(xiàn)strstr char* my_strstr(const char* mom,const char* son) { char* cp=mom; char* i, *j; if (*son == '\0') { return mom; } while (*cp != '\0') { i = cp; j = son; while (i && *i == *j) { i++; j++; if (*j == '\0') return cp; } cp++; } return NULL; } int main() { char mom[] = "abcdefghijk"; char son[] = "ghi"; printf("%s\n",my_strstr(mom, son)); return 0; }
strcat
函數(shù)聲明
char * strstr (char * str1, const char * str2 );
函數(shù)作用
連接字符串
將source字符串的副本粘貼追加到目標(biāo)字符串。destination中的結(jié)束空字符被source中的第一個(gè)字符覆蓋,并且在由destination中的兩個(gè)字符串聯(lián)形成的新字符串的末尾包含一個(gè)空字符。
目標(biāo)和源不應(yīng)重疊。
返回destionation。
實(shí)現(xiàn)strcat
/實(shí)現(xiàn)strstr char* my_strstr(const char* mom,const char* son) { char* cp=mom; char* i, *j; if (*son == '\0') { return mom; } while (*cp != '\0') { i = cp; j = son; while (i && *i == *j) { i++; j++; if (*j == '\0') return cp; } cp++; } return NULL; } int main() { char mom[] = "abcdefghijk"; char son[] = "ghi"; printf("%s\n",my_strstr(mom, son)); return 0; }
strcmp
函數(shù)聲明
char * strcat ( char * destination, const char * source );
函數(shù)作用
比較字符串str1和字符串str2。
這個(gè)函數(shù)開(kāi)始比較每個(gè)字符串的第一個(gè)字符。如果它們彼此相等,則繼續(xù)執(zhí)行下面的對(duì),直到字符不同或到達(dá)一個(gè)終止的空字符為止。
返回值
1)<0 第一個(gè)不匹配的字符在ptr1中的值比在ptr2中的值低
2)=0 兩個(gè)字符串的內(nèi)容相等
3)>0 第一個(gè)不匹配的字符在ptr1中的值大于ptr2中的值
實(shí)現(xiàn)strcmp
char* my_strcat(char* dst,const char* src) { assert(dst && src); int len1 = strlen(dst); char* start = dst + len1; while (*start++ = *src++) { ; } return dst; } int main() { char mom[26] ="abcdefg"; char son[] = "hijk"; printf("%s\n",my_strcat(mom, son)); return 0; }
strcpy
函數(shù)聲明
int strcmp ( const char * str1, const char * str2 );
函數(shù)作用
復(fù)制字符串
將source指向的字符串復(fù)制到destination指向的數(shù)組中,包括終止空字符(并在此點(diǎn)停止)。
為了避免溢出,destination指向的數(shù)組的大小應(yīng)該足夠長(zhǎng),以包含與source相同的字符串(包括結(jié)束的null字符),并且不應(yīng)該在內(nèi)存中與source重疊。
返回destination。
實(shí)現(xiàn)strcpy
//實(shí)現(xiàn)strcpy char* my_strcpy(char* dst, const char* src) { char* start = dst; assert(dst && src); while (*dst++ = *src++); return start; } int main() { char mom[26] ="abcdefg"; char son[] = "abq"; my_strcpy(mom, son); printf("%s\n",mom); return 0; }
strlen
函數(shù)聲明
size_t strlen ( const char * str );
函數(shù)作用
獲取字符串長(zhǎng)度
返回C字符串str的長(zhǎng)度。
C字符串的長(zhǎng)度由結(jié)束空字符決定:C字符串的長(zhǎng)度等于字符串開(kāi)頭和結(jié)束空字符之間的字符數(shù)(不包括結(jié)束空字符本身)。
char mystr[100]="test string";
定義了一個(gè)長(zhǎng)度為100個(gè)字符的字符數(shù)組,但是用于初始化mystr的C字符串長(zhǎng)度只有11個(gè)字符。因此,當(dāng)sizeof(mystr)計(jì)算為100時(shí),strlen(mystr)返回11。
實(shí)現(xiàn)strlen
//實(shí)現(xiàn)strlen size_t my_strlen(const char* str) { size_t len = 0; while (*str++) { len++; } return len; } int main() { char mom[26] ="abcdefg"; printf("%d\n",my_strlen(mom)); return 0; }
output:7
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
- C語(yǔ)言庫(kù)函數(shù)qsort的使用詳解
- C語(yǔ)言常用庫(kù)函數(shù)的使用及模擬實(shí)現(xiàn)詳解例舉
- C語(yǔ)言 超詳細(xì)講解庫(kù)函數(shù)
- C語(yǔ)言庫(kù)函數(shù)中qsort()的用法
- C語(yǔ)言strcpy庫(kù)函數(shù)詳解
- 實(shí)現(xiàn)C語(yǔ)言常用字符串庫(kù)函數(shù)
- C語(yǔ)言實(shí)現(xiàn)常用字符串庫(kù)函數(shù)(推薦)
- 一篇文章帶你實(shí)現(xiàn)C語(yǔ)言中常用庫(kù)函數(shù)的模擬
- C語(yǔ)言模擬實(shí)現(xiàn)庫(kù)函數(shù)詳解
相關(guān)文章
C++實(shí)踐分?jǐn)?shù)類(lèi)中運(yùn)算符重載的方法參考
今天小編就為大家分享一篇關(guān)于C++實(shí)踐分?jǐn)?shù)類(lèi)中運(yùn)算符重載的方法參考,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-02-02C++實(shí)現(xiàn)一個(gè)線(xiàn)程安全的單例工廠實(shí)現(xiàn)代碼
這篇文章主要介紹了 C++實(shí)現(xiàn)一個(gè)線(xiàn)程安全的單例工廠實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2017-05-05C++容器適配與棧的實(shí)現(xiàn)及dequeque和優(yōu)先級(jí)詳解
這篇文章主要介紹了C++容器適配與棧的實(shí)現(xiàn)及dequeque和優(yōu)先級(jí),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2022-10-10QT基于TCP實(shí)現(xiàn)文件傳輸系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了QT基于TCP實(shí)現(xiàn)文件傳輸系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08一文教你Qt如何操作SQLite數(shù)據(jù)庫(kù)
Sqlite 數(shù)據(jù)庫(kù)作為 Qt 項(xiàng)目開(kāi)發(fā)中經(jīng)常使用的一個(gè)輕量級(jí)的數(shù)據(jù)庫(kù),可以說(shuō)是兼容性相對(duì)比較好的數(shù)據(jù)庫(kù)之一。本文為大家介紹了Qt操作SQLite數(shù)據(jù)庫(kù)的具體方法,希望對(duì)大家有所幫助2023-03-03基于Qt OpenCV實(shí)現(xiàn)圖像數(shù)據(jù)采集軟件
這篇文章主要為大家詳細(xì)介紹了如何利用Qt+OpenCV實(shí)現(xiàn)圖像數(shù)據(jù)采集軟件,文中的示例代碼講解詳細(xì),對(duì)我學(xué)習(xí)或工作有一定參考價(jià)值,感興趣的可以了解一下2022-07-07C++實(shí)現(xiàn)LeetCode(41.首個(gè)缺失的正數(shù))
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(41.首個(gè)缺失的正數(shù)),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07如何使用arm-none-eabi-gcc編譯器搭建STM32的Vscode開(kāi)發(fā)環(huán)境
這篇文章主要介紹了使用arm-none-eabi-gcc編譯器搭建STM32的Vscode開(kāi)發(fā)環(huán)境,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07C++創(chuàng)建窗口程序的實(shí)現(xiàn)示例
Windows窗體應(yīng)用程序是C#語(yǔ)言中的一個(gè)重要應(yīng)用,本文主要介紹了C++創(chuàng)建窗口程序的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01