天天看點

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

@toc

本篇文章将會詳細介紹和學習字元串操作函數,<code>重點介紹處理字元和字元串的庫函數和字元操作分類改寫函數,記憶體操作函數的使用和注意事項,還有自己模拟實作該函數的代碼練習。</code>

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

求字元串長度

strlen

長度不受限制的字元串函數

strcpy

strcat

strcmp

長度受限制的字元串函數介紹

strncpy

strncat

strncmp

字元串查找

strstr

strtok

誤資訊報告

strerror

字元操作

記憶體操作函數

memcpy

memmove

memset

memcmp

c語言中對字元和字元串的處理很是頻繁,但是c語言本身是沒有字元串類型的,字元串通常放在常量字元串 中或者字元數組 中。 字元串常量 适用于那些對它不做修改的字元串函數.

在之前學習中,我們會經常使用一個字元串函數求字元串的長度-- strlen。

strlen求字元串長度的算法分析:strlen接收到字元串起始位置的位址時,比較該位址處的内容是否為’\0’,若不為’\0’, 直到找到 /0 為止

圖解:

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
函數介紹:strlen size_t strlen(const char* str); 頭檔案:string.h 函數名:strlen 函數參數:str,參數類型是const char* ,即需要進行求字元串長度的起始位址 <code>函數傳回類型: size_t,size_t是unsigned int的類型重定義,是無符号整型。庫函數使用size_t類型可能考慮的是字元串的長度不可能是負數,是以用了無符号類型size_t。</code> 函數功能:計算字元串的長度

重點内容:

(1)字元串以’\0’作為結束标志,strlen函數傳回的是在字元串中’\0’前面出現的字元個數(不包含’\0’)。 (2)參數指向的字元串必須要以’\0’結束。(如果沒有’\0’,可能會出現随機值) (3)<code>注意函數的傳回值為size_t(可以了解為unsigned),是無符号的(易錯)(strlen(“abc”) - strlen("abcdef) &amp;lt; 0為假,注意strlen傳回類型)</code> (4)學會strlen函數的模拟實作

strlen函數的模拟實作三種方法:

①計數器方法 ②遞歸方法(不建立臨時變量求字元串長度) ③指針 - 指針方法
【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

如果我們要<code>将一個字元串的内容拷貝到另外一個字元串空間中</code>時,需要使用字元串拷貝- -strcpy函數,在正式介紹<code>strcpy函數</code>之前,我們先看一段代碼:

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

strcpy函數進行字元串拷貝的算法分析:

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
函數介紹:strcpy char strcpy(char destination,const char source); 函數名:strcpy 函數參數: 參數1:destination, 類型:char ,表示将字元串拷貝的目的地位置 參數2:source,類型:char ,表示被拷貝字元串拷貝的源位址起始位置。 `函數傳回類型: char, 實際上就是傳回destination(目的地)的起始位置` 函數功能:字元串拷貝
(1) copies the c string pointed by source into the array pointed by destination, including the terminating nulcharacter(and stopping at that point). (2)<code>源字元串必須以‘\0’結束。 (源字元串如果沒有’\0’, 那麼strcpy在拷貝的時候,不知道什麼時候停止,可能會造成越界通路)</code> (3)會将源字元串中的’ \0 ’拷貝到目标空間。 (4)<code>目标空間必須足夠大,以確定能存放源字元串</code>。 (目标空間不夠大,也會導緻越界通路) (5)<code>目标空間必須可變</code>(不能是常量字元串,比如:char* arr1 ="asdsffdf") (要将源字元串的内容拷貝到目标空間,目标空間當然要可以變化,才能接收拷貝過來的字元) (6)學會模拟實作。

模拟實作strcpy

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

如果我們要<code>将一個字元串的内容追加到另外一個字元串的末尾空間中</code>時,需要使用字元串拷貝-- - strcat函數,在正式介紹<code>strcat函數</code>之前,我們先看一段代碼:

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

strcat在進行追加的時候是否會将’\0’追加過去?

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

strcat函數進行字元串追加的算法分析:

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
函數介紹:strcat char strcat(char destination,const char source); 函數名:strcat 參數1:destination, 類型:char ,表示将字元串追加的目的地位置 參數2:source,類型:char* ,表示被追加字元串的源位址起始位置。 *函數傳回類型: char,實際上就是傳回destination(目的地)的起始位置** 函數功能:字元串追加
(1)appends a copy of the source string to the destination string.the terminating null character in destination is overwritten by the first character of source, and a null - character is included at the end ofthe new string formed by the concatenation of both in destination. (2)<code>源字元串必須以‘\0’結束。目标空間也必須包含’\0’,以确定追加的起始位置</code> (3)目标空間必須有足夠的大,能容納下源字元串的内容。 (4)目标空間必須可修改。 (5)字元串自己給自己追加,如何 ? <code>用strcat自己給自己追加會導緻程式崩潰,無法實作自己追加自己!</code>(從’\0’開始追加,自己追加自己的時候,’\0‘改成了被追加的首字元,再尋找追加字元串結束的’\0’時,找不到’\0’,會導緻死循環)

的模拟實作strcat

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

思考:strcat為什麼不能自己追加自己?

strcat從’\0’開始追加,自己追加自己的時候,’\0‘改成了被追加的首字元,再尋找追加字元串結束的’\0’時,找不到’\0’,會導緻死循環。 怎麼樣才能自己追加自己呢? 使用strncat函數,後面會進行詳細講解

如果我們<code>要比較兩個字元串的是否相等,或者比較字元串大小,不能用操作符 == 來直接進行判斷</code>,而是需要用到字元串<code>比較函數strcmp</code>

strcmp函數進行字元串追加的算法分析:

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
函數介紹:strcmp int strcmp(const char str1,const char str2); 函數名:strcmp 參數1:str1, 類型:char ,表示将進行比較的第一個字元串 參數2:參數2:str2, 類型:char ,表示将進行比較的第二個字元串 函數傳回類型: int, 傳回兩個字元串比較的結果 函數功能:字元串比較
(1)this function starts comparing the first character of each string.lf they are equal to each other, itcontinues with the following pairs until the characters differ or until a terminating null - character isreached. 标準規定︰ (2)第一個字元串大于第二個字元串,則傳回大于o的數字。 (3)第一個字元串等于第二個字元串,則傳回0 (4)第一個字元串小于第二個字元串,則傳回小于0的數字 <code>strcmp那麼如何判斷兩個字元串?&lt;br/&gt;逐個字元ascll碼進行比較</code>

模拟實作strcmp

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

<code>strncpy與strcpy相比較多了一個字母n</code>,這個<code>n代表的是需要拷貝字元的個數</code>,也就是說strncpy需要<code>關注拷貝字元的個數</code>,而不是像strcpy那樣關注’\0’。

舉例:

算法圖解分析:

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
char strncpy(char destination,const char source,size_t num); 函數名:strncpy 【參數1】destination,類型:char,拷貝字元的目的地位置,即接收字元的起始位置 【參數2】source,類型:char ,拷貝字元的源位址,即拷貝字元串的開始位置。 【參數3】num,類型size_t,拷貝字元的個數,用來控制拷貝字元的長度。 函數傳回類型:char ,傳回接收字元的起始位置。 函數功能:指定個數的字元串拷貝

重點内容

(1)copies the first num characters of source to destination.lf the end of the source c string(which issignaled by a null - character) is found before num characters have been copied, destination is paddedwith zeros until a total of num characters have been written to it. (2)拷貝num個字元從源字元串到目标空間。 (3)如果源字元串的長度小于num,則拷貝完源字元串之後,在目标的後邊追加0,直到num個。 (4)如果拷貝的字元長度大于目的地空間的容量,則會破壞dest字元串後面的\0,要避免這種情況發生

模拟實作strncpy

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

strcat函數是字元串追加,在使用的時候以src的’\0’作為追加結束标志,是以在使用strcat來追加一個字元串數組本身的時候,會因\0被提前覆寫而無法追加成功。

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

strncat與strcat相比多了一個字母n,這個n代表的是需要追加字元的個數,也就是說<code>strncat需要關注追加字元的個數,而不是像strcat那樣關注’\0’。</code>

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

strncat在追加字元串的時候,會自動在末尾處添加字元串結束标志’\0’。(這也是我們在追加的時候,不用關注原dest, src中’\0’,僅需關注追加字元的個數的原因)

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

情況二程式示範效果:

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
char strncat(char destination,const char source,size_t num); 函數名:strncat 【參數1】destination,類型:char,被追加字元的目的地位置,即接收追加字元的起始位置 【參數2】source,類型:char ,追加字元的源位址,即追加字元串的開始位置。 【參數3】num,類型size_t,追加字元的個數,用來控制追加字元的長度。 函數功能:指定個數的字元串追加
(1)appends the first num characters of source to destination, plus a terminating null - character. (2)lf the length of the c string in source is less than num, only the content up to the terminating null - character is copied. (3)如果追加的字元長度大于目的地空間的剩餘容量,則出現越界通路,要避免這種情況發生。

strcmp用來比較兩個字元串的大小,其算法思想如下:

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

而strncmp與strcmp相比多了一個字母n,這個n代表的是需要比較字元的個數,也就是說strncmp需要關注比較字元的個數,而不是像strcmy那樣僅關注’\0’。

strncmp的傳回結果與strcmp一樣,傳回 &gt; 0, == 0, &lt; 0 的整數。

以下面代碼為例:

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
int strncmp(const char p1,const char p2,size_t count); 頭檔案:string.h 【參數1】p1,char 類型,表示用來比較的其中一個字元串。 【參數2】p2,char 類型,表示用來比較的另一個字元串。 【參數3】count,size_t類型,表示參與比較的字元個數。 函數傳回類型:int類型,根據比較的具體結果傳回相應的數值 exit : returns &lt;0 if str1 &lt; str2 returns =0 if str1 == str2 returns &gt;0 if str1 &gt; str2 函數功能: compares two strings for ordinal order.the comparison stops after : (1) a difference between the strings is found, (2) the end of the strings is reached, or (3) count characters have been compared.
(1)比較到出現另個字元不一樣或者一個字元串結束或者num個字元全部比較完。
【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

庫函數參考:

<code>查找字元串,找子字元串</code>

找到字元串傳回的是子字元串的位址,找不到傳回空指針。

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
char strstr(const char str1, const char* str2); 函數名:strstr 【參數1】str1,char ,用于查找字元串的母串。 【參數2】str2,char,待查找字元串的子串。 <code>函數傳回類型:char* ,傳回查找到的位址</code> 函數功能:查找字元串 / 找子字元串
(1)<code>如果在str1中查找了字串str2,則傳回str1中字串str2的起始位址</code> (2)<code>如果查找不到,傳回空指針null</code> (3)如果str1中含有多個str2字串内容,傳回的是第一個被查找到的str2起始位址

模拟實作strstr:( <code>kmp算法</code> )

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

其實庫函數的實作邏輯跟我們實作的方式是一樣的,兩者有所差別的是代碼風格,庫函數的代碼風格更

加簡練,需要有一定的程式設計功底!

庫函數源代碼參考:

char strtok (char str, const char* sep); 函數名:strtok <code>【參數1】str,要被分割的字元串起始位置&lt;br/&gt;【參數2】sep,被用于分割的字元集合起始位置</code> <code>函數傳回類型:char* ,标記的位置</code> 函數功能:字元串分割 詳解: (1)sep參數是個字元串,定義了用作分隔符的字元集合 (2)第一個參數指定一個字元串,它包含了0個或者多個由sep字元串中一個或者多個分隔符分割的标記。 (3)<code>strtok函數找到str中的下一個标記,并将其用\0結尾,傳回一個指向這個标記的指針。</code> (注:strtok函數會改變被操作的字元串,是以在使用strtok函數切分的字元串一般都是臨時拷貝的内容并且可修改。) (4)<code>strtok函數的第一個參數不為(null),函數将找到str中第一個标記,strtok函數将儲存它在字元串中的位置。</code> (5)<code>strtok函數的第一個參數為(null),函數将在同一個字元串中被儲存的位置開始,查找下一個标記。</code> (6)如果字元串中不存在更多的标記,則傳回null指針。

應用舉例:

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
*char strerror(int errnum); 頭檔案:string.h , errno.h** 函數名:strerror <code>函數參數:errnum, int類型,表示錯誤碼編号</code> *函數傳回類型:char ,傳回錯誤碼對應的錯誤資訊** 函數功能:get a system error message(strerror) or prints a user - supplied error message(_strerror). 傳回系統的錯誤資訊(就是程式出錯時,用這個函數傳回錯誤的原因資訊)

錯誤碼-- - 所對應的錯誤資訊:

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

實際在使用的時候,錯誤碼并非由我們來控制的,而是<code>接收系統傳回的錯誤資訊</code>

實際使用舉例:

打開檔案

示例:找不到檔案

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

大寫字母轉小寫

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

在之前的學習中,我們知道字元串拷貝可以使用strcpy函數,但是,<code>當我們拷貝的資料不是字元串的時候,比如說int類型、double類型,還能使用strcpy函數嗎?</code>strcpy函數在拷貝的時候是以\0為字元串拷貝的結束标志,那麼在拷貝其它類型資料的時候,拷貝該結束的時候不一定存在\0。是以使用strcpy函數肯定是行不通的。

那怎麼辦呢?

實際上<code>我們可以使用memcpy函數-- - 記憶體拷貝函數,用來拷貝任意類型資料。</code>

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

拷貝前:

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

拷貝後:

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

算法分析 + 圖解:

memcpy函數可以拷貝任意類型的資料,為什麼呢? 首先我們思考一下,不同類型的函數參數實際在使用時所對應的記憶體狀态是什麼情況?比如說char類型的資料,如果要拷貝的話,是不是應該按照char類型的長度(1)為機關一個位元組一個位元組來拷貝。int類型的資料,如果要拷貝的話,是不是也應該按照int類型的長度(4)為機關4個位元組4個位元組來拷貝….如果是double類型呢,8個位元組為機關?那結構體呢? 顯然,如果我們按照這種方式思考就陷入的經驗陷阱中,實際上,如果我們跳出來考慮,無論任何類型的資料,都是1個位元組的整數倍(1倍到n倍,n為大于等于1的正整數),如果我們不考慮資料的類型,均按照一個位元組一個位元組來拷貝,最終不管什麼類型的資料都可以成功被拷貝。(這時候,有的同學可能會考慮,既然可以一個位元組一個位元組來拷貝,為什麼不按照1個bit一個bit來拷貝呢?回答:1.沒必要,按照位元組為機關拷貝已經可以滿足我們的需求的,如果要按照更小的機關bit來拷貝隻會導緻程式執行的次數無端增加。2.操作不友善,以位元組為機關拷貝可以通過将指針強制類型轉換成char * 來操作,那麼以bit為機關呢?該怎麼操作,是不是很麻煩!)
【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
函數介紹:memcpy void memcpy(void dest, const void* src, size_t count); 函數名:memcpy 參數1:destination, 類型:char ,表示記憶體拷貝的目的位置 參數2:source,類型:char ,表示記憶體拷貝的起始位置 參數3:count,類型:size_t,表示拷貝記憶體位元組的個數 *函數傳回類型: void, 實際上就是傳回destination(目的地)的起始位置** 函數功能:記憶體拷貝
(1)函數memcpy從source的位置開始向後複制num個位元組的資料到destination的記憶體位置。 (2)這個函數在遇到’\0’的時候并不會停下來。 (3)如果source和destination有任何的重疊,複制的結果都是未定義的。

模拟實作函數:

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
注意: mencpy函數應該拷貝不重疊的記憶體 ,memmove函數可以拷貝重疊的記憶體 <code>c語言規定menmcy隻要實作了不重疊的情況拷貝就可以了</code>,而<code>vs中的memmcy中實作了既可以拷貝不重疊,又可以拷貝重疊。</code> <code>c語言規定重疊拷貝的情況交給memmove處理就可以了。</code>

假設我們有一個整型數組 1 2 3 4 5 6 7 8 9 10 ,如果我們想要将前5個數字拷貝到第3 - 8個位置上,也就是:

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

如果我們通過my_memcpy可以做到嗎?試驗以下就知道了:

執行前:

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

執行後:

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

得到的結果是:1 2 1 2 1 2 1 8 9 10,并不是我們想要的 1 2 1 2 3 4 5 8 9 10

為什麼呢?

從我們剛剛模拟實作memcpy中方法中,我們知道memcpy在進行拷貝的時候,是按照從前往後的方式進行的,如果這個地方按照從前往後的方式進行拷貝,那麼拷貝一開始的時候,就會出現後面需要被拷貝的資料被覆寫掉,比如說3,一開始将1放到3這個位置,3就被覆寫掉了,後面如果要拷貝3,從這個位置取出資料的時候,實際上取出的是1。 既然從前往後的拷貝方式不行,那麼從後往前拷貝呢?
【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

分析後,可以發現從後向前的拷貝方式是可以的,不會出現後面需要被拷貝的資料提前被覆寫的情況。

但是,如果我們拷貝 3 4 5 6 7 到 1 2 3 4 5的位置上,那麼從前往後的拷貝方式還行得通嗎?

是不是發現從後向前拷貝會出現資料提前被覆寫的情況。是以這時候我們需要進行分情況讨論:

情況一:如果dest在src的右邊,如果按照從後往前的方式,就會出現資料提前被覆寫,是以隻能按照從前往後的方式拷貝
【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
情況二:如果dest在src的左邊且dest不超過src + num(拷貝資料的個數,也就是圖中紫色方框的橫向長度),如果按照從前往後的方式,就會出現資料提前被覆寫,是以隻能按照從後往前的方式拷貝
【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
情況三:如果dest &gt; src + num(拷貝資料的個數,也就是圖中紫色方框的橫向長度),那麼無論按照從後向前,還是從前向後的方式,均不會出現資料提前被覆寫的情況,是以兩個方式均可以。
【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

為了友善我們實際程式設計,我們可以将情況二、情況三合并起來,這樣就得到:

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
函數介紹:memmove void memmove(void dest, const void src, size_t count); 函數名:memmove 參數1:destination, 類型:char ,表示記憶體移動的目的位置 參數2:source,類型:char ,表示記憶體移動的起始位置 參數3:count,類型:size_t,表示移動記憶體位元組的個數 函數傳回類型: void, 實際上就是傳回destination(目的地)的起始位置 函數功能:記憶體移動
(1)和memcpy的差别就是memmove函數處理的源記憶體塊和目标記憶體塊是可以重疊的。 (2)如果源空間和目标空間出現重疊,就得使用memmove函數處理。

模拟實作memmove函數

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
int memcmp(const void buf1, const void buf2, size_t count); (1)比較從ptr1和ptr2指針開始的num個位元組 (2)傳回值如下 :
【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
用:sets buffers to a specified character.(将緩沖區設定為指定的字元) void memset(void dest, int c, size_t count);

相關資訊:

【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
以位元組為機關設定記憶體
【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數
【C語言進階】—— 字元操作函數+記憶體操作函數詳解 (吐血爆肝 !!!)⏳ 前言 ⏳⚽本章重點⛳一、求字元串長度函數✊二、長度不受限制的字元串函數✋三、長度不限制的字元串函數⚾四、字元串查找⛳五、誤資訊報告函數⌚六、字元操作✨七、記憶體操作函數

繼續閱讀