C語言字符函數,字符串函數以及內存函數

那么博主寫這一片博客的目的就是為下一篇c++的string類做鋪墊,那么下面就請期待博主的下一篇文章吧。?

目錄

1.字符函數

2.字符串函數(均在string.h頭文件中)

strlen的使用和模擬實現

strcpy 的使用和模擬實現?

?strcat 的使用和模擬實現

?strcmp的使用和模擬實現

?strncpy 函數的使用

strncat 函數的使用

strncmp函數的使用

?strstr 的使用和模擬實現

strtok函數的使用

?strerror 函數的使用

3.C語言內存函數

memcpy使用和模擬實現

?memmove使用和模擬實現(可以實現自己給自己追加)

?memset函數的使用

?memcmp函數的使用


1.字符函數

? ? ? ??C語言標準庫中的字符處理函數主要是在ctype.h頭文件中定義的。先來看字符函數的速查表。

感覺很生澀?沒關系,咱們來看幾個例子:

寫 ?個代碼,將字符串中的?寫字?轉?寫,其他字符不變。

int main ()

{

int i = 0;

char str[] = "Test String.\n";

char c;

while (str[i])

{

????????c = str[i];

????????if (islower(c))

????????c -= 32;//小寫字母與大寫字母之間的ASCII值相差32。

????????putchar(c);

???????? i++;

}

????????return 0;

}

那么字符函數咱們就不過多的闡述了。下面看字符串函數。

2.字符串函數(均在string.h頭文件中)

strlen的使用和模擬實現

size_t? strlen (const char*str)?

? ? ? ?1.??字符串以 ?'\0' 作為結束標志,strlen函數返回的是在字符串中 '\0' 前面出現的字符個數(不包含'\0')

? ? ? ?2. 參數指向的字符串必須要以 '\0' 結束。

? ? ? ?3. 注意函數的返回值為size_t,是無符號的

? ? ? ? ?4.strlen的使用需要包含頭文件

那么下面咱們來看strlen的模擬實現,下面我提供了三種實現方式:

int my_strlen(const char * str)

{

????????int count = 0;

????????assert(str);

????????while(*str)

{

????????count++;

????????str++;

}

????????return count;

}//這個得引入一個新變量

int my_strlen(const char * str)

{

????????assert(str);

????????if(*str == '\0')

????????return 0;

????????else

????????return 1+my_strlen(str+1);?

}//采用遞歸的方式

int my_strlen(char *s)

{

????????assert(str);

????????char *p = s;

????????while(*p != '\0' )

{

????????p++;

}

????????return p-s;?

}//采用指針減指針的方式,這個方法在C語言指針這一篇博客有講解

OK,下面進入六個函數的講解

strcpy 的使用和模擬實現?

char *strcpy? (char*destination,const char*source)

1.源字符串必須以?'\0' 結束。

2.會將源字符串中的 '\0' 拷貝到目標空間。

?3.目標空間必須足夠大,以確保能存放源字符串。

4. 目標空間必須可修改?

5.從源頭開始拷貝。

但是這樣你打印的話,只能打印出來“xxx”,因為,打印自動到'\0'停止,所以你打印不出完整的拷貝后的字符串,不過可以通過調試觀察。

以上也是strcpy函數的模擬實現。

思路:

1.由于返回起始空間的地址,所以要先保存起始空間的地址,防止后面++后,找不到起始空間的地址了。

2.接著斷言,防止p與p1指針傳的是無效地址。

3.然后把p1指向的字符串中的字符挨個拷貝到p指向的字符串中,之后p1指向的字符串中的字符位置與p指向的字符串中的位置都往后挪動一位。依次重復。

?strcat 的使用和模擬實現

char*strcat? (char*destination,const char*source)

1.源字符串必須以 '\0' 結束。

?2.目標字符串中也得有 \0 ,否則沒辦法知道追加從哪里開始。

3. 目標空間必須有足夠的大,能容納下源字符串的內容。

4. 目標空間必須可修改。?

5.destination中的'\0'也會被覆蓋

以上是strcat的模擬實現,需要注意的是這里不可以自己給自己追加,否則會導致未定義。

思路:

1.首先先斷言一下,由于這里傳的是起始空間的地址,所以還要創建一個變量,用來存儲起始地址。

2.之后先去找destination中的'\0',找到之后,就從這開始拷貝即可,需要注意的是,source中的'\0'也會別拷貝到目標字符串中。

?strcmp的使用和模擬實現

int? ?strcmp? (const char*str1,const char*str2)

其實這個函數就是一個用于比較字符串大小的工具。?

1.第?個字符串大于第二個字符串,則返回大于0的數字 ?

2.第?個字符串等于第二個字符串,則返回0 ?

3.第?個字符串小于第二個字符串,則返回小于0的數字 ?

4.那么如何判斷兩個字符串?比較兩個字符串中對應位置上字符ASCII碼值的大小。

下面看strcmp函數的模擬實現:

不過要注意的是這里博主用的編譯器是vs,并且返不返回1,-1,0,純看編譯器,有的編譯器就是不返回這幾個數字。

模擬實現代碼思路:

1.還是老樣子先斷言,之后從第一個字符的ASCII值開始比較。

2.如果第一個字符相等,那么++,繼續往后比較,如果比較完了,直到最后一個標識字符'\0'都相等,那么就返回0.

3.如果第一個字符串的第一個字符比第二個字符串的第一個字符大,那么就返回1(vs下),否則返回-1.

以上三個函數都是長度不受限制的,那么下面看3個長度受限制的。

?strncpy 函數的使用

?char * strncpy? ?( char * destination, const char * source, size_t num );

1.拷貝num個字符(不是字節)從源字符串到目標空間。

2.如果源字符串的長度小于num,則拷貝完源字符串之后,在目標的后邊追加'\0'(可通過調試觀察),直到num個?。

該函數就是strcpy函數的減縮版,模擬實現方式差不多,這里就不做演示了。

strncat 函數的使用

char * strncat? ?( char * destination, const char * source, size_t num );

1.將source指向字符串的num個字符追加到destination指向的字符串末尾,再追加?個'\0'字符。

很細節,方便打印?

2.如果source 指向的字符串的長度小于num的時候,它不會像strncpy一樣,在后面追加'\0',而是直接不管,直接在destination的字符串末尾加一個'\0'即可。

strncmp函數的使用

int? strncmp? ( const char * str1, const char * str2, size_t num );

比較str1和str2的前num個字符,如果相等就繼續往后比較,最多比較num個字母,如果提前發現不? 樣,就提前結束,大的字符所在的字符串大于另外?個。如果num個字符都相等,就是相等返回0。?(就是比strcmp函數多了個限制條件)

?strstr 的使用和模擬實現

strstr的作用是用來查找子串的。

char * strstr? ?( const char * str1, const char * str2);

1.函數返回字符串str2在字符串str1中第一次出現的位置。

2.字符串的比較匹配不包含 '\0' 字符,以 '\0 '作為結束標志。

來看它的模擬實現吧。

思路:

1.首先先斷言一下,因為要返回起始空間的地址,所以說要創建一個變量存放起始地址。

2.先來一個循環,條件是找的時候第一個字符串!='\0',之后,將指向第一個字符串的指針再賦值給s1,指向第二個字符串的指針再賦值給s2,之后便可以開始比較了。

3.如果說找到了s1跟s2相等的字符,那么各自++,繼續往后比較,但凡有一個字符不相等了,直接退出循環,cur++,(即返回第一個字符串的起始地址,并且加一,讓它從第一個字符串的第二個字符開始比較)。

4.如果說,比較完了,而且正好發現了第一個字符串中藏了第二個字符串,就是到了if階段,那么這時候,s2就到了'\0'的位置,這時候直接返回當時找的第一個字符串的起始地址即可。

5.不過這里需要注意的是,你打印的時候,是會遇到'\0'才會停止的,所以說,比如,第一個字符串“abcdef”,第二個字符串“cde”,那么可以打印出cdef。

strtok函數的使用

1.sep參數指向?個字符串,定義了用作分隔符的字符集合?

2.第?個參數指定?個字符串,它包含了0個或者多個由sep字符串中?個或者多個分隔符分割的標 記。

?3.strtok函數找到str中的下?個標記,并將其用?\0 結尾,返回?個指向這個標記的指針。

(注: strtok函數會改變被操作的字符串,所以被strtok函數切分的字符串?般都是臨時拷貝的內容并且可修改。)

?4.strtok函數的第?個參數不為 中的位置。 NULL ,函數將找到str中第一個標記,strtok函數將保存它在字符串

?5.strtok函數的第?個參數為 NULL ,函數將在同?個字符串中被保存的位置開始,查找下?個標 記。

?6.如果字符串中不存在更多的標記,則返回 NULL 指針

?strerror 函數的使用

char* strerror ( int errnum );

strerror 函數可以把參數部分錯誤碼對應的錯誤信息的字符串地址返回來。 在不同的系統和C語言標準庫的實現中都規定了?些錯誤碼,?般是放在 errno.h 這個頭文件中說明 的,C語言程序啟動的時候就會使用?個全局的變量errno來記錄程序的當前錯誤碼,只不過程序啟動 的時候errno是0,表示沒有錯誤,當我們在使用標準庫中的函數的時候發?了某種錯誤,就會將對應 的錯誤碼,存放在errno中,而?個錯誤碼的數字是整數很難理解是什么意思,所以每?個錯誤碼都 是有對應的錯誤信息的。strerror函數就可以將錯誤對應的錯誤信息字符串的地址返回?。

3.C語言內存函數(也在string.h頭文件中)

memcpy使用和模擬實現(覆蓋原理)

void * memcpy ( void * destination, const void * source, size_t num );

1.函數memcpy從source的位置開始向后復制num個字節的數據到destination指向的內存位置。

2. 這個函數在遇到 '\0' 的時候并不會停下來

3.如果source和destination有任何的重疊,復制的結果都是未定義的?。

4.對于重疊的內存,交給memmove來處理。

來看它的模擬實現

思路:

1.由于也是返回起始空間的地址,所以說先定義一個臨時變量,用來存儲起始空間的地址,之后再斷言。

2.以count--為循環條件,決定了要拷貝的次數,并且讓source中的字符拷貝到destination中,一個字符拷貝完之后,++,直到count被減完,才停止賦值。

?memmove使用和模擬實現(可以實現自己給自己追加)

void * memmove ( void * destination, const void * source, size_t num );

其實memmove的用法與memcpy基本一樣,就以下不同點:

1.和memcpy的差別就是memmove函數處理的源內存塊和目標內存塊是可以重疊的。

?2.如果源空間和目標空間出現重疊,就得使用memmove函數處理。?

來看它的模擬實現:

?memset函數的使用

void * memset ( void * ptr, int value, size_t num );

memset是用來設置內存的,將內存中的值以字節為單位設置成想要的內容。?

?memcmp函數的使用

int memcmp ( const void * ptr1, const void * ptr2, size_t num );

比較從ptr1和ptr2指針指向的位置開始,向后的num個字節 ,這個其實也是比較類的函數,與strcmp,strncmp差不多。

下面來看它的返回值:

再來看一個例子:

相信大家對這個函數也已經理解了吧。

以上內容是我個人理解,若有不對,還請指出!謝謝!

本篇完...............

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/73303.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/73303.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/73303.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

_DISPATCHER_HEADER結構中的WaitListHead和_KWAIT_BLOCK的關系

第一部分: // // Wait block // // begin_ntddk begin_wdm begin_nthal begin_ntifs begin_ntosp typedef struct _KWAIT_BLOCK { LIST_ENTRY WaitListEntry; struct _KTHREAD *RESTRICTED_POINTER Thread; PVOID Object; struct _KWAIT_BLOCK *R…

flutter 自定義控件RenderObjectWidget使用

CustomWidget的自定義組件的注釋還是比較清晰的 參考文檔Flutter實戰 import package:flutter/cupertino.dart; import package:flutter/gestures.dart; import package:flutter/material.dart; /* * 如果組件不會包含子組件,則我們可以直接繼承自 LeafRenderObject…

機器視覺場景應用中,有沒有超景深的工業鏡頭

在機器視覺領域,確實存在具有超景深特性的工業鏡頭,這類鏡頭通過特殊的光學設計或技術手段,能夠顯著擴大清晰成像的縱向范圍,從而滿足復雜檢測場景中對多平面物體清晰成像的需求。以下是相關技術要點及典型鏡頭類型: 1. 遠心鏡頭 遠心鏡頭是超景深鏡頭的典型代表,其特點包…

【Linux】同步原理剖析及模擬BlockQueue生產消費模型

📢博客主頁:https://blog.csdn.net/2301_779549673 📢博客倉庫:https://gitee.com/JohnKingW/linux_test/tree/master/lesson 📢歡迎點贊 👍 收藏 ?留言 📝 如有錯誤敬請指正! &…

光流 | 基于KLT算法的人臉檢測與跟蹤原理及公式,算法改進,matlab代碼

===================================================== github:https://github.com/MichaelBeechan CSDN:https://blog.csdn.net/u011344545 ===================================================== 人臉檢測與跟蹤 一、KLT算法原理與分析1. 核心思想2. 數學模型二、人臉…

<數據集>軌道異物識別數據集<目標檢測>

數據集下載鏈接:https://download.csdn.net/download/qq_53332949/90527370 數據集格式:VOCYOLO格式 圖片數量:1659張 標注數量(xml文件個數):1659 標注數量(txt文件個數):1659 標注類別數:6 標注類別…

LabVIEW液壓振動錘控制系統

在現代工程機械領域,液壓振動錘的高效與精準控制日益顯得重要。本文通過LabVIEW軟件,展開液壓振動錘啟停共振控制技術的研究與應用,探討如何通過改進控制系統來優化液壓振動錘的工作性能,確保其在復雜工況下的穩定性與效率。 ? …

【開源寶藏】30天學會CSS - DAY7 第七課 CSS 關鍵幀打造Preloader 追逐動畫

你的代碼實現了一個 方形軌跡預加載動畫(Preloader Animation),其中三個 span 元素沿著一個 22 網格 軌跡循環移動。現在,我們將 拆解核心實現步驟,讓你能一步步理解并調整動畫效果。 第 0 步:項目概覽 你…

在shell腳本內部獲取該腳本所在目錄的絕對路徑

目錄 需求描述 方法一:使用 dirname 和 readlink 命令 方法二:使用 BASH_SOURCE 變量 方法三:僅使用純 Bash 實現 需求描述 工作中經常有這樣情況,需要在腳本內部獲取該腳本自己所在目錄的絕對路徑。 假如有一個腳本/a/b/c/…

常考計算機操作系統面試習題(一下)

目錄 操作系統基本類型 操作系統的功能 操作系統的主要任務 進程與線程 進程狀態轉變 內存管理 文件系統與文件管理 虛擬存儲器 設備管理 磁盤調度 死鎖 信號量機制 文件打開與管理 進程與線程的互斥與同步 進程同步 進程調度 文件分配磁盤塊的方法 程序執行…

GPT-SoVITS本地部署:低成本實現語音克隆遠程生成音頻全流程實戰

文章目錄 前言1.GPT-SoVITS V2下載2.本地運行GPT-SoVITS V23.簡單使用演示4.安裝內網穿透工具4.1 創建遠程連接公網地址 5. 固定遠程訪問公網地址 前言 今天要給大家安利一個絕對能讓你大呼過癮的聲音黑科技——GPT-SoVITS!這款由花兒不哭大佬精心打造的語音克隆神…

JVM(基礎篇)

一.初識JVM 1.什么是JVM JVM全稱Java Virtyal Machine,中文譯名 Java虛擬機 。JVM本質上是一個運行在計算機上的程序,他的職責是運行Java字節碼文件(將字節碼解釋成機器碼)。 2.JVM的功能 解釋和運行:對字節碼文件中的指令號,實時…

【高并發內存池】第四彈---深入理解PageCache:整體設計、核心實現及Span獲取策略詳解

?個人主頁: 熬夜學編程的小林 💗系列專欄: 【C語言詳解】 【數據結構詳解】【C詳解】【Linux系統編程】【Linux網絡編程】【項目詳解】 目錄 1、pagecache 1.1、整體設計 1.2、核心實現 1.3、獲取Span 1.3.1、獲取一個非空的Span 1.3…

深入理解C語言數據結構之快速排序三路劃分

在數據結構和算法的世界里,排序算法是基石一般的存在。快速排序作為一種高效的排序算法,以其平均情況下的優秀時間復雜度而被廣泛應用。今天,讓我們深入探討快速排序的一種變體——三路劃分的快速排序,看看它是如何在C語言中施展魔…

Java實現后量子密碼(PQC)與國密算法(SM4)混合加密

以下是使用Java實現一種后量子密碼(PQC)與國密算法(SM4)混合加密的示例方案。該方案結合了后量子密碼的抗量子特性與國密算法的國產化合規要求,適合需要雙重安全保障的場景。 一 . 方案驗證 1.代碼截圖 2.運行測試 二 . 方案設計 密鑰交換:使用后量子密碼(如Kyber)生…

【SQL Server數據庫備份詳細教程】

🎥博主:程序員不想YY啊 💫CSDN優質創作者,CSDN實力新星,CSDN博客專家 🤗點贊🎈收藏?再看💫養成習慣 ?希望本文對您有所裨益,如有不足之處,歡迎在評論區提出…

SpringBoot古典舞在線交流平臺設計與實現

隨著古典舞文化的普及,越來越多的人希望通過線上平臺交流學習。幽絡源作為一站式綜合平臺,致力于為用戶提供免費源碼、技術教程及網絡兼職資源。本文將詳細介紹基于SpringBoot的古典舞在線交流平臺的設計與實現,幫助開發者快速搭建一個功能完…

關于絕對時間、人類時間、本地時間、時區時間的對比分析,結合編程場景(如Java)進行說明

以下是關于絕對時間、人類時間、本地時間、時區時間的對比分析,結合編程場景(如Java)進行說明: 1. 定義與核心區別 (1) 絕對時間(Absolute Time) 定義:不受時區影響,以固定時間起點…

go語言中的strings庫

strings庫 func EqualFold func EqualFold(s, t string) bool判斷兩個utf-8編碼字符串(將unicode大寫、小寫、標題三種格式字符視為相同)是否相同。 func main() {fmt.Println(strings.EqualFold("hello", "hello")) //truefmt.…

Git沖突解決

目錄 一、Git沖突產生的原因二、解決Git沖突的步驟1. 發現沖突2. 查看沖突文件3. 手動解決沖突4. 提交解決后的代碼5. 完成合并 三、預防Git沖突的小技巧四、總結 在團隊協作開發中,Git沖突是常見的問題。當多個開發者同時修改了同一個文件的不同部分,然…