欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語(yǔ)言模擬實(shí)現(xiàn)字符串庫(kù)函數(shù)的示例講解

 更新時(shí)間:2023年01月13日 15:38:08   作者:叫我小秦就好了  
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言模擬實(shí)現(xiàn)字符串庫(kù)函數(shù)的具體方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

字符串檢驗(yàn)

strlen

函數(shù)原型

/// @brief 返回給定空終止字符串的長(zhǎng)度,即首元素為 str 所指,且不包含首個(gè)空字符的字符數(shù)組中的字符數(shù)
/// @param str 指向要檢測(cè)的字符串的指針
/// @return 字符串 str 的長(zhǎng)度
size_t strlen( const char *str );

空終止字符串即 C 語(yǔ)言中以 ‘\0’ 作為終止符的字符串,strlen 計(jì)算字符串的長(zhǎng)度并返回,返回的長(zhǎng)度不包含 ‘\0’。

char arr[] = "qgw";
// num 的值是 3
int num = strlen(arr);

模擬實(shí)現(xiàn)

下面的實(shí)現(xiàn)方式比較簡(jiǎn)單,采用遍歷字符串的方式,遇到 ‘\0’ 就退出循環(huán),返回結(jié)果。

size_t my_strlen(const char* str) {
    size_t cnt = 0;
    while (*str != '\0') {
        ++str;
        ++cnt;
    }
    return cnt;
}

strcmp

函數(shù)原型

/// @brief 以字典序比較二個(gè)字符串
/// @param str rhs 要比較的兩字符串
/// @return 相等返回 0
int strcmp(const char* lhs, const char* rhs);

返回值:

  • 兩字符串字典序相同,返回 0
  • lhs 字典序大于 rhs,返回一個(gè)正數(shù)
  • lhs 字典序小于 rhs,返回一個(gè)負(fù)數(shù)

模擬實(shí)現(xiàn)

實(shí)現(xiàn)的思路是:遍歷兩個(gè)字符串,直到出現(xiàn)不同或有字符串結(jié)束。

res 存儲(chǔ)兩字符串比較的結(jié)果,如果等于 0 循環(huán)繼續(xù),不等于 0 直接退出,lhs 指向的字符大于 rhs 指向的字符就為正數(shù),否則反之。

若 lhs 先結(jié)束,rhs 還沒(méi)結(jié)束,此時(shí) res 為負(fù)數(shù),\0 的 ASCII 碼為 0,是最小的。若 rhs 先結(jié)束,lhs 還沒(méi)結(jié)束,此時(shí) res 為正數(shù)。若同時(shí)結(jié)束,res 剛好為 0 返回。

int my_strcmp(const char* lhs, const char* rhs) {
    int res = 0;
    while ((res = *lhs - *rhs) == 0 && *lhs != '\0' && *rhs != '\0') {
        ++lhs;
        ++rhs;
    }
    return res;
}

strstr

函數(shù)原型

/// @brief 在 str 中查找 substr 子串
/// @param str 指向要檢驗(yàn)的空終止字符串的指針
/// @param substr 指向要查找的空終止字節(jié)字符串的指針
/// @return 指向于 str 中找到的子串首字符的指針,或若找不到該子串則為空指針
char *strstr( const char* str, const char* substr );

若 substr 指向空,則會(huì)返回 str。

模擬實(shí)現(xiàn)

下面實(shí)現(xiàn)的方法為暴力匹配子串,實(shí)際中可以使用 KMP 或 BM 等字符串搜索函數(shù)優(yōu)化這一過(guò)程。

char* my_strstr(const char* str, const char* substr) {
	if (substr == NULL) {
		return str;
	}

	// 遍歷 str 所有字符,看以其起始字符是否匹配
	while (*str != '\0') {
		const char* backStr = str;
		const char* backSub = substr;
		while (*backStr != '\0' && *backSub != '\0' && *backStr == *backSub) {
			++backStr;
			++backSub;
		}
		// 如果 substr 走完了,說(shuō)明匹配成功了,返回此時(shí)的 str
		if (*backSub == '\0') {
			return str;
		}
		++str;
	}
}

字符串操作

strcpy

函數(shù)原型

/// @brief 復(fù)制 src 所指向的空終止字符串,包含空終止符,到首元素為 dest 所指的字符數(shù)組
/// @param dest 指向要寫(xiě)入的字符數(shù)組的指針
/// @param src 指向要復(fù)制的空終止字符串的指針
/// @return 返回 dest 的副本
char *strcpy( char *dest, const char *src );

需要注意的是:

1.若 dest 數(shù)組長(zhǎng)度不足則行為未定義

即 dest 數(shù)組不足以包含 src 中所有元素,此時(shí)大概率會(huì)因越屆訪問(wèn)崩潰

2.若字符串覆蓋則行為未定義

現(xiàn)在主流編譯器都可以處理有覆蓋的情況,比如:MSVC、GCC

3.若 dest 不是指向字符數(shù)組的指針或 src 不是指向空終止字符串的指針則行為未定義

模擬實(shí)現(xiàn)

下面的方法先記錄要返回的地址,最后遍歷 src 遇到 \0,此時(shí)退出循環(huán)。

注意:該實(shí)現(xiàn)方法并不能解決字符串有覆蓋的情況。

char* my_strcpy(char* dest, const char* src) {
    char* res = dest;
    while (*dest = *src) {
        ++dest;
        ++src;
    }
    return res;
}

strcat

函數(shù)原型

/// @brief 后附 src 所指向的空終止字符串的副本到 dest 所指向的空終止字符串的結(jié)尾
/// @param dest 指向要后附到的空終止字符串的指針
/// @param src 指向作為復(fù)制來(lái)源的空終止字符串的指針
/// @return 返回 dest 的副本
char *strcat( char *dest, const char *src );

需要注意的是:

會(huì)用字符 src[0] 替換 dest 末尾的 \0

若目標(biāo)數(shù)組對(duì)于 src 和 dest 的內(nèi)容以及空終止符不夠大,則行為未定義

若字符串重疊,則行為未定義

若 dest 或 src 不是指向空終止字符串的指針,則行為未定義

模擬實(shí)現(xiàn)

因?yàn)闀?huì)先用 src 第一個(gè)字符替換 dest 結(jié)尾的 \0,所以要先找到 dest 結(jié)尾 \0。然后再遍歷 src,將其添加到 dest 結(jié)尾。

char* my_strcat(char* dest, const char* src) {
    char res = dest;
    // 先找 \0 的位置
    while (*dest != '\0') {
        ++dest;
    }
    // 追加到 dest 后面
    while (*dest = *src) {
        ++dest;
        ++src;
    }
    return res;
}

內(nèi)存操作

memcpy

函數(shù)原型

/// @brief 從 src 所指向的對(duì)象復(fù)制 count 個(gè)字符到 dest 所指向的對(duì)象
/// @param dest 指向要復(fù)制的對(duì)象的指針
/// @param src 指向復(fù)制來(lái)源對(duì)象的指針
/// @param count 復(fù)制的字節(jié)數(shù)
/// @return 返回 dest 的副本
void* memcpy(void* dest, const void* src, size_t count);

要注意的是:

若訪問(wèn)發(fā)生在 dest 數(shù)組結(jié)尾后則行為未定義

若對(duì)象重疊,則行為未定義

也就是說(shuō)在標(biāo)準(zhǔn)中 memcpy 也不能處理對(duì)象重疊的情況

若 dest 或 src 為非法或空指針則行為未定義

模擬實(shí)現(xiàn)

下面給出的實(shí)現(xiàn)方式與 strcpy 相似,不過(guò)是改用 count 變量來(lái)控制循環(huán)次數(shù)。

memcpy 是最快的內(nèi)存到內(nèi)存復(fù)制子程序。它通常比必須掃描其所復(fù)制數(shù)據(jù)的 strcpy,或必須預(yù)防以處理重疊輸入的 memmove更高效。

void* my_memcpy(void* dest, const void* src, size_t count) {
    void* res = dest;
    while (count--) {
        *(char*)dest = *(char*)src;
        ++(char*)dest;
        ++(char*)src;
    }
    return res;
}

memmove

函數(shù)原型

/// @brief 從 src 所指向的對(duì)象復(fù)制 count 個(gè)字節(jié)到 dest 所指向的對(duì)象
/// @param dest 指向要復(fù)制的對(duì)象的指針
/// @param src 指向復(fù)制來(lái)源對(duì)象的指針
/// @param count 復(fù)制的字節(jié)數(shù)
/// @return 返回 dest 的副本
void* memmove(void* dest, const void* src, size_t count);

memmove 是不是看起來(lái)和 memcpy 一模一樣,但 memmove 可以處理內(nèi)存重疊的情況,這也就說(shuō)明它要做一些檢查,來(lái)保證能夠處理內(nèi)存重疊的情況。

1.無(wú)重疊

直接調(diào)用更高校的 memcpy

2.有重疊,dest 在 src 之前,正常正向復(fù)制

3.有重疊,dest 在 src 之后,需要反向復(fù)制

模擬實(shí)現(xiàn)

通過(guò)對(duì)上圖的觀察,我們可以發(fā)現(xiàn):若 dest 在 src 的后面并且存在內(nèi)存重疊,就需要反向復(fù)制。

我們可以簡(jiǎn)化這一函數(shù),對(duì)無(wú)重疊的情況不去調(diào)用 memcpy 而是包含在下面兩種情況中。

dest 在 src 之前,采用正向復(fù)制

dest 在 src 之后,采用反向復(fù)制

void* my_memmove(void* dest, const void* src, size_t count) {
    void* res = dest;
    if (dest < src) {
        while (count--) {
            *(char*)dest = *(char*)src;
            ++(char*)dest;
            ++(char*)src;
        }
    } else {
        while (count--) {
            *((char*)dest + count) = *((char*)src + count);
        }
    }
}

到此這篇關(guān)于C語(yǔ)言模擬實(shí)現(xiàn)字符串庫(kù)函數(shù)的示例講解的文章就介紹到這了,更多相關(guān)C語(yǔ)言字符串庫(kù)函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實(shí)現(xiàn)職工工資管理系統(tǒng)課程設(shè)計(jì)

    C++實(shí)現(xiàn)職工工資管理系統(tǒng)課程設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)職工工資管理系統(tǒng)課程設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C++11中l(wèi)onglong超長(zhǎng)整型和nullptr初始化空指針

    C++11中l(wèi)onglong超長(zhǎng)整型和nullptr初始化空指針

    本文介紹?C++11?標(biāo)準(zhǔn)中新添加的?long?long?超長(zhǎng)整型和?nullptr?初始化空指針,在?C++11?標(biāo)準(zhǔn)下,相比?NULL?和?0,使用?nullptr?初始化空指針可以令我們編寫(xiě)的程序更加健壯,本文結(jié)合示例代碼給大家詳細(xì)講解,需要的朋友跟隨小編一起看看吧
    2022-12-12
  • C++ Boost Random隨機(jī)函數(shù)詳解

    C++ Boost Random隨機(jī)函數(shù)詳解

    Boost是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱。Boost庫(kù)是一個(gè)可移植、提供源代碼的C++庫(kù),作為標(biāo)準(zhǔn)庫(kù)的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開(kāi)發(fā)引擎之一,是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱
    2022-11-11
  • C語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)開(kāi)辟存儲(chǔ)楊輝三角

    C語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)開(kāi)辟存儲(chǔ)楊輝三角

    這篇文章主要介紹了如何利用C語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)開(kāi)辟存儲(chǔ)楊輝三角,可以靈活的開(kāi)辟空間,充分的利用空間。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以參考一下
    2022-03-03
  • C語(yǔ)言實(shí)現(xiàn)高精度減法

    C語(yǔ)言實(shí)現(xiàn)高精度減法

    高精度的本質(zhì)是將數(shù)字以字符串的形式讀入,然后將每一位分別存放入int數(shù)組中,通過(guò)模擬每一位的運(yùn)算過(guò)程,來(lái)實(shí)現(xiàn)最終的運(yùn)算效果,下面我們就來(lái)看看C語(yǔ)言如何實(shí)現(xiàn)高精度減法吧
    2023-11-11
  • C語(yǔ)言中帶頭雙向循環(huán)鏈表基本操作的實(shí)現(xiàn)詳解

    C語(yǔ)言中帶頭雙向循環(huán)鏈表基本操作的實(shí)現(xiàn)詳解

    無(wú)頭單向非循環(huán)鏈表結(jié)構(gòu)簡(jiǎn)單,一般不會(huì)單獨(dú)用來(lái)存數(shù)據(jù)。而帶頭雙向循環(huán)鏈表的結(jié)構(gòu)較為復(fù)雜,一般用在單獨(dú)存儲(chǔ)數(shù)據(jù)。本文將介紹帶頭雙向循環(huán)鏈表的基本操作,需要的可以參考一下
    2022-11-11
  • QT線程池的使用(QThreadPool類(lèi)和QRunnable類(lèi))

    QT線程池的使用(QThreadPool類(lèi)和QRunnable類(lèi))

    本文主要介紹了QT線程池的使用(QThreadPool類(lèi)和QRunnable類(lèi)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • C語(yǔ)言簡(jiǎn)易實(shí)現(xiàn)掃雷小游戲

    C語(yǔ)言簡(jiǎn)易實(shí)現(xiàn)掃雷小游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言簡(jiǎn)易實(shí)現(xiàn)掃雷小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • C中實(shí)現(xiàn)矩陣乘法的一種高效的方法

    C中實(shí)現(xiàn)矩陣乘法的一種高效的方法

    本篇文章介紹了,在C中實(shí)現(xiàn)矩陣乘法的一種高效的方法。需要的朋友參考下
    2013-05-05
  • C語(yǔ)言超全面講解字符串函數(shù)

    C語(yǔ)言超全面講解字符串函數(shù)

    字符串函數(shù)(String?processing?function)也叫字符串處理函數(shù),指的是編程語(yǔ)言中用來(lái)進(jìn)行字符串處理的函數(shù),如C,pascal,Visual以及LotusScript中進(jìn)行字符串拷貝,計(jì)算長(zhǎng)度,字符查找等的函數(shù)
    2022-06-06

最新評(píng)論