memcpy、memmove、memset、memchr、memcmp、strstr詳解

第一部分  綜述

memcpy、memmove、memset、memchr、memcmp都是C語言中的庫函數,在頭文件string.h中。memcpy和memmove的作用是拷貝一定長度的內存的內容,memset用于緩沖區的填充工作,memchr用于字符的查找工作,memcmp用于比較內存中緩沖區的大小。

?

第二部分?  介紹

1、memcpy和memmove

memcpy()--拷貝內存內容

表頭文件:#include<string.h>或#include<cstring>

定義函數:void *memcpy(void *dst,const void *src,size_t n)

函數說明:memcpy用來拷貝src所指的內存內容前n個字節到dst所指的內存地址上。與strcpy不同的是,memcpy會完成的復制n個字節,不會遇到字符串結束'\0'而結束(strncpy待會驗證)。

返回值:返回指向dst的指針。

附加說明:指src和dst所指的內存區域不可重疊

重疊實例:

 1 #include<iostream>
 2 #include<string.h>
 3 using namespace std;
 4 int main()
 5 {
 6     int a[10] = {0};
 7     for (int i = 0; i < 10; i++)
 8         a[i] = i;
 9     memcpy(&a[4],a,sizeof(int)*6);
10     //memmove(&a[4], a, sizeof(int) * 6);
11     for (int i = 0; i < 10; i++)
12         cout << a[i];
13     getchar();
14     return 0;
15 }

會輸出0123012301,但是vs會輸出和memmove一樣的結果0123012345,原因是對src進行了保護,不允許更改。

2、memmove()--拷貝內存內容

表頭文件:#include<string.h>或#include<cstring>

定義函數:void* memmove(void* dst,const void* src,size_t n)

函數說明:memmove()與memcpy()一樣都是用來拷貝src所指的內存前n個字節到dst所指的內存上。

不同的是,當src和dest所指的內存區域重疊時,memmove仍然可以正確的處理,不過執行效率上會比memcpy略慢。

返回值:返回值指向dst的指針。附加說明:指針src和dst所指的內存區域可以重疊。

3、memset()--設置內存內容

表頭文件:#include<memory.h> ?#include<string.h>

函數說明:memset是C的庫函數,將s所指向的某一塊內存中的前n個字節全部設置成ch制定的ASCII值,塊的大小由第三個參數制定,這個函數通常為新申請的內存做初始化工作。

定義函數:void* memset(void *s,int ch,size_t n)

函數解釋:將s中前n個字節用ch替換并返回s。

作用:在一段內存塊中填充某個給定的值,他是對較大的結構體或數組進行清零操作的一種最快方法。

返回值:指向s的指針

上面的例子可以改一下

1     int a[10] = {0};
2     memset(a,0,10);

4、memchr()--查找內存內容

表頭文件:#include<string.h>

函數說明:從buf所指內存區的前count個字節查找字符ch,當第一次遇到字符ch時停止查找。如果成功,返回指向字符ch的指針;否則返回null

定義函數:extern void* memchr(const void* buf,int ch,size_t count)

代碼實現

 1 #include<iostream>
 2 #include<string.h>
 3 using namespace std;
 4 int main()
 5 {
 6     char a[] = "nihao jingliming";
 7     void *p;
 8     p = memchr(a,'j',sizeof(a));
 9     if (p)
10         cout << "has found:" << *((char*)p) << endl;
11     else
12         cout << "not found" << endl;
13     getchar();
14     return 0;
15 }

5、memcmp()--內存比較

表頭文件:#include <string.h>

函數原型:int memcmp(const void* buf1,const void* buf2,unsigned int count)

函數描述:比較buf1和buf2的前count個字節

返回值:當buf1<buf2時,返回值<0

    當buf1==buf2時,返回值=0

    當buf1>buf2時,返回值>0

函數說明:該函數是按字節進行比較的

 1 #include<iostream>
 2 #include<string.h>
 3 using namespace std;
 4 int main()
 5 {
 6     char a[] = "nihao jingliming"; 
 7     char b[] = "nihao xiaoming";
 8     int r=memcmp(a,b,strlen(a));
 9     if (r>0)
10         cout << "a is big" << endl;
11     else if (r < 0)
12         cout << "b is big" << endl;
13     else
14         cout << "same" << endl;
15     getchar();
16     return 0;
17 }

?第三部分  實現

memcpy和memmove

linux內核版

 1 /**
 2  * memcpy - Copy one area of memory to another
 3  * @dest: Where to copy to
 4  * @src: Where to copy from
 5  * @count: The size of the area.
 6  *
 7  * You should not use this function to access IO space, use memcpy_toio()
 8  * or memcpy_fromio() instead.
 9  */
10 void * memcpy(void * dest,const void *src,size_t count)
11 {
12     char *tmp = (char *) dest, *s = (char *) src;
13     while (count--)
14         *tmp++ = *s++;
15     return dest;
16 }
 1 /* Normally compiler builtins are used, but sometimes the compiler calls out
 2    of line code. Based on asm-i386/string.h.
 3  */
 4 #define _STRING_C
 5 #include <linux/string.h>
 6 #undef memmove
 7 void *memmove(void * dest,const void *src,size_t count)
 8 {
 9     if (dest < src) { 
10         __inline_memcpy(dest,src,count);
11     } else {
12         char *p = (char *) dest + count;
13         char *s = (char *) src + count;
14         while (count--)
15             *--p = *--s;
16     }
17     return dest;
18 } 

window版

 1 void * __cdecl memcpy (void * dst, const void * src, size_t count)
 2 {
 3         void * ret = dst;
 4 
 5         /*
 6          * copy from lower addresses to higher addresses
 7          */
 8         while (count--) {
 9                 *(char *)dst = *(char *)src;
10                 dst = (char *)dst + 1;
11                 src = (char *)src + 1;
12         }
13 
14         return(ret);
15 }
 1 void * __cdecl memmove (void * dst, const void * src, size_t count)
 2 {
 3         void * ret = dst;
 4 
 5         if (dst <= src || (char *)dst >= ((char *)src + count)) {
 6                 /*
 7                  * Non-Overlapping Buffers
 8                  * copy from lower addresses to higher addresses
 9                  */
10                 while (count--) {
11                         *(char *)dst = *(char *)src;
12                         dst = (char *)dst + 1;
13                         src = (char *)src + 1;
14                 }
15         }
16         else {
17                 /*
18                  * Overlapping Buffers
19                  * copy from higher addresses to lower addresses
20                  */
21                 dst = (char *)dst + count - 1;
22                 src = (char *)src + count - 1;
23 
24                 while (count--) {
25                         *(char *)dst = *(char *)src;
26                         dst = (char *)dst - 1;
27                         src = (char *)src - 1;
28                 }
29         }
30 
31         return(ret);
32 }

windows寫的就是分析的更詳細,效率更快。

memset

1 void *(memset) (void *s,int c,size_t n)
2 {
3     const unsigned char uc = c;
4     unsigned char *su;
5     for(su = s;0 < n;++su,--n)
6         *su = uc;
7     return s;
8 }

memchr

 1 void *memchr (const void *ptr, int value, int num)
 2 {
 3 if (ptr == NULL)
 4 {
 5 perror("ptr");
 6 return NULL;
 7 }
 8 char * p = (char *)ptr;
 9 while (num--)
10 {
11 if (*p != (char)value)
12 p++;
13 else
14 return p;
15 }
16 
17 return NULL;
18 }

memcmp

 1 /*  因為類型可以為任意,所以形參應為void * 
 2  *  相等則返回0,否則不為0 
 3  */  
 4 int my_memcmp(const void *s1,const void *s2,size_t count)  
 5 {  
 6     int res = 0;  
 7     const unsigned char *p1 =(const unsigned char *)s1;//注意是unsigned char *  
 8     const unsigned char *p2 =(const unsigned char *)s2;   
 9     for(p1 ,p2;count > 0;p1++,p2++,count--)  
10         if((res =*p1 - *p2) != 0)   //不相當則結束比較  
11             break;  
12     return res;  
13 }  

?ststr實現

 1 char* strstr(const char *s1, const char *s2)  
 2 {  
 3     int n;  
 4     if (*s2)  
 5     {  
 6         while (*s1)  
 7         {  
 8             for (n=0; *(s1 + n) == *(s2 + n); n++)  
 9             {  
10                 if (!*(s2 + n + 1))  
11                     return (char *)s1;  
12             }  
13             s1++;  
14         }  
15         return NULL;  
16     }  
17     else  
18         return (char *)s1;  
19 }  

?

轉載于:https://www.cnblogs.com/jingliming/p/4737409.html

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

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

相關文章

21分鐘 MySQL 入門教程(轉載)

鏈接&#xff1a;http://www.cnblogs.com/mr-wid/archive/2013/05/09/3068229.html轉載于:https://www.cnblogs.com/hxb316/p/3966731.html

Maven倉庫詳解

轉載自&#xff1a;Maven入門指南④&#xff1a;倉庫 1 . 倉庫簡介 沒有 Maven 時&#xff0c;項目用到的 .jar 文件通常需要拷貝到 /lib 目錄&#xff0c;項目多了&#xff0c;拷貝的文件副本就多了&#xff0c;占用磁盤空間&#xff0c;且難于管理。Maven 使用一個稱之為倉庫…

c++ 從 string 到 short

string test"1234"; short *p reinterpret_cast<short*>(const_cast<char*>(test.c_str()));從 short 到 char * char *q reinterpret_cast<char*>(const_cast<short*>(p));還可以利用 memcpy 這個函數 #include <cstring>short a…

JavaScript02

JavaScript02 如果<head>標簽中包含的外部文件很多&#xff0c;那么這將直接導致頁面展示速度很慢。因為html只有當<body>元素開始之后&#xff0c;才會開始頁面展示動作&#xff0c;因此&#xff0c;最直接的解決辦法就是&#xff0c;將一部分不是頁面加載之后立刻…

.NET使用NPOI讀取Word模板并替換關鍵字并下載

NPOI 是 POI 項目的 .NET 版本。POI是一個開源的Java讀寫Excel、WORD等微軟OLE2組件文檔的項目。 使用 NPOI 你就可以在沒有安裝 Office 或者相應環境的機器上對 WORD/EXCEL 文檔進行讀寫 NPOI下載地址&#xff1a;http://npoi.codeplex.com/ 以下代碼僅供參考&#xff0c;請根…

中間件、MetaQ入門學習

目錄 1. 中間件技術 2. MetaQ中間件 3. MetaQ編程實踐 1. 中間件技術 0x1: 中間件簡介 中間件(Middleware)是提供系統軟件和應用軟件之間連接的軟件&#xff0c;以便于軟件各部件之間的溝通&#xff0c;特別是應用軟件對于系統軟件的集中的邏輯&#xff0c;在現代信息技術應用框…

MyBatis 入門到精通(二) SQL語句映射XML文件

MyBatis 真正強大之處就在這些映射語句&#xff0c;也就是它的魔力所在。對于它的強大功能&#xff0c;SQL 映射文件的配置卻非常簡單。 如果您比較SQL 映射文件配置與JDBC 代碼&#xff0c;您很快可以發現&#xff0c;使用SQL 映射文件配置可以節省95%的代碼量。MyBatis 被創建…

Monitoring the process execution and memory consumption in its lifetime

<?xml version"1.0" encoding"utf-8"?> Monitoring the process execution and memory consumption in its lifetimeMonitoring the process execution and memory consumption in its lifetime Recently, I am working on a research project whi…

設置和清除LD_LIBRARY_PATH

"" 設置 export LD_LIBRARY_PATH$LD_LIBRARY_PATH:/the/path/you/want/setexport LD_LIBRARY_PATH/the/path/you/want/set "" 查看設置 echo $LD_LIBRARY_PATH "" 清除 unset LD_LIBRARY_PATH

Jenkins中切換devtoolset

source /opt/rh/devtoolset-4/enable or source scl_source enable devtoolset-4

告訴一個遠程團隊協作的故事

Lisette Sutherland和Elinor Slomba在一起收集一些人的故事&#xff0c;這些人的業務模式須要依靠遠程團隊正確完畢工作。故事中體現出遠程團隊怎樣協作。怎樣跨越距離的障礙&#xff0c;怎樣建立信任&#xff0c;怎樣完畢任務。即將出版的《高能協作&#xff1a;遠程戰地指南》…

混沌數學之呂陳吸引子

呂陳吸引子&#xff08;Lu Chen attractor&#xff09;也稱Lu attractor 吸引子是2002年中國科學院數學與系統科學研究院研究員 呂金虎&#xff08;Jinhu Lu)&#xff0c;Suchun Zhang 和香港城市大學電子工程系講座教授陳關榮&#xff08; Guangrong Chen &#xff09;發現和分…

整數反轉

給出一個 32 位的有符號整數&#xff0c;你需要將這個整數中每位上的數字進行反轉。 示例 1: 輸入: 123 輸出: 321示例 2: 輸入: -123 輸出: -321示例 3: 輸入: 120 輸出: 21注意: 假設我們的環境只能存儲得下 32 位的有符號整數&#xff0c;則其數值范圍為 [?231, 231 ?…

C# char[]與string之間的相互轉換

string 兌換 Char[] string ss "abcdefg";char[] cc ss.ToCharArray();Char[] 轉換成string string s new string(cc);byte[] 與 string 之間的轉換 byte[] bb Encoding.UTF8.GetBytes(ss);string s Encoding.UTF8.GetString(bb);string[] 轉換成string string …

java 直接 訪問WebSphere JNDI

代碼如下: Hashtable<String, String> env new Hashtable<String, String>();env.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");env.put(Context.PROVIDER_URL, "iiop://localhost:2809");Co…

Standard C++ Episode 7

六、C的I/O流庫 C&#xff1a;fopen/fclose/fread/fwrite/fprintf/fscanf/fseek/ftell... C&#xff1a;對基本的I/O操作做了類的封裝&#xff0c;其功能沒有任何差別&#xff0c;用法和C的I/O流也非常近似。 七、格式化I/O <</>> 1 /*2 *格式化I/O練習3 */4 #in…

在Android設備與Mac電腦之間傳輸文件

不同于Windows和Linux&#xff0c;Android設備連接到Mac電腦上是看不見掛載的目錄的&#xff0c;既然看不到了Android設備的掛載目錄&#xff0c;如何在Android設備與Mac電腦之間傳輸文件呢&#xff1f; 原來Android官方提供了傳輸文件的工具&#xff01;訪問www.android.com/f…

mysql語句在node.js中的寫法

總結一下mysql語句在node.js中的各種寫法&#xff0c;參考了npm網站mysql模塊給的實例。 查詢 select //1 db.query(select * from tuanshang_users where user_id < 10,function(err,results,fields){//if(err) throw err;console.log( results );if(!!results.length){con…

jqPlot圖表插件學習之折線圖-散點圖-series屬性

一、準備工作 首先我們需要到官網下載所需的文件&#xff1a; 官網下載&#xff08;筆者選擇的是jquery.jqplot.1.0.8r1250.zip這個版本&#xff09; 然后讀者需要根據自己的情況新建一個項目并且按照如下的方式加載對應的js和css&#xff08;因為筆者在VS2012環境下新建的&…

node.js基礎:數據存儲

無服務器的數據存儲 內存存儲 var http require(http); var count 0; //服務器訪問次數存儲在內存中 http.createServer(function(req,res){res.write(hello count);res.end(); }).listen(3000);    基于文件的存儲 node.js中主要用fs文件系統模塊來管理文件的存儲。 文件…