(1) Memset
原型: extern void *memset(void *buffer, int c, int count);
用法: #include <string.h>
功能: 把buffer所指內存區域的前count個字節設置成字符 c。
說明: 返回指向buffer的指針。用來對一段內存空間全部設置為某個字符
例如:
char a[10];
memset(a, '\0', sizeof(a));
memset可以方便的清空一個結構類型的變量或數組。
如:struct _test{ char s[10];
int x;
int y;
};
變量 struct _test st;
(1)一般清空st的方法如下:
st.s[0] = '\0'; st.x =0; st.y =0;
(2) 用memset方法如下:
memset(&st,0,sizeof(struct _test));
數組: struct _test st[10];
memset(st,0,sizeof(struct _test)*10); //清空方法
//memset 源碼的實現 C語言
#include <mem.h>
void* memset(void* s, int c, size_t n)
{
unsigned char* p = (unsigned char*) s;
while (n > 0)
{
*p++ = (unsigned char) c;
--n;
}
return s;
}
(2)memcpy
原型:extern void *memcpy(void*dest,void*src,unsignedintcount); 用法: #include <string.h>
功能: 由src所指內存區域復制count個字節到dest所指內存區域。
說明: src和dest所指內存區域不能重疊,函數返回指向dest的指針.可以拿它拷貝任何數據類型的對象。
例如: char a[10],b[5];
memcpy(b, a, sizeof(b)); /*注意如果用sizeof(a),會造成b的內存地址溢出*/
(3) Strcpy
原型: extern char *strcpy(char *dest,char *src);
用法: #include <string.h>
功能: 把src所指由NULL結束的字符串復制到dest所指的數組中。
說明: src和dest所指內存區域不可以重疊且dest必須有足夠的空間來容納 src的字符串.返回指向dest的指針。
例如: char a[100],b[50];
strcpy(a,b);
如用 strcpy(b,a);
要注意a中的字符串長度(第一個‘\0’之前)是否超過50位,如超過,則會造成b的內存地址溢出。
假如有如下代碼,請問輸出為多少?
#include "stdio.h"
main()
{ char dest[3];
char str[6]="Hello";
strcpy(dest,str);
printf("%s\n",dest);
}
編譯輸出如下結果:
Hello //沒有輸出亂碼,有點怪怪的為什么?
分析:
1>str中字符串的長度大於dest 的內存長度3.為什么str字符串還能完拷貝到dest 中呢?
來看看 strcpy的 源代碼實現:
char *strcpy(char *strDest,const char *strSrc)
{
assert((strDest!=NULL)&&(strSrc !=NULL)) //判斷指針是否合法,即分配內存,指向某塊確定區域
char *address = strDest; //記住目標地址的起始值
while((*strDest++ = *strSrc++)!='\0') //先拷貝,后判斷,這樣就不用在拷貝完了后,再加一句
NULL; // *strDest = '\0'; -->即加一個結束符.因為字符串結束已拷貝了.
return address; //返回目標首地址的值。
}
//從上面的代碼可以看出,strcpy函數,假定strDest的內存空間是足夠可以放下strSrc的內容的.
//也就是說使用者,在使用strcpy函數時,應使 (strDest內存空間)>= (strSrc內存空間)
// 在調用 strcpy(dest,str); 時,while((*strDest++ = *strSrc++)!='\0') 沒有判斷strDest的內存是否夠,而是將srtSrc的內容直接拷貝到strDest,當拷到'\0'就結束.
//因此在使用printf("%s\n",dest); 時 輸出遇到'\0'時停此輸出.所以會輸出: Hello
(4) 三者區別
memset 主要應用是初始化某個內存空間。
memcpy 是用於copy源空間的數據到目的空間中。
strcpy 用於字符串copy,遇到‘\0’,將結束。
如果理解了這些,就能知道它們的區別:
例如初始化某塊空間的時候,用到memcpy,那么就顯得笨拙
int m[100]
memset((void*)m,0x00,sizeof(int*100); //Ok!
memcpy((void*)m,"\0\0\0\0....",sizeof(int)*100); //Not Ok
一.函數原型
strcpy extern char *strcpy(char *dest,char *src);
#include <string.h>
功能:把src所指由NULL結束的字符串復制到dest所指的數組中
說明: src和dest所指內存區域不可以重疊且dest必須有足夠的空間來容納src的字符串。 返回指向dest的指針
memcpy extern void *memcpy(void *dest,void *src,unsigned int count);
#include <string.h>
功能:由src所指內存區域復制count個字符串到dest所指內存區域.
說明:src和dest所指內存區域不能重疊,函數返回指向dest的指針.
memset extern void *memset(void *buffer,int c,int count);
#include <string.h>
功能:把buffer所指內存區域的前count個字節設置成字符c
說明:返回指向buffer的指針.
二.區別
memset 用來對一段內存空間全部設置為某個字符,一般用於在對定義的字符串初始化為' '或者'\0';
例: char a[100]; memset(a,'\0',sizeof(a));
memcpy 是用來做內存拷貝,可以用來拷貝任何數據類型的對象,可以指定拷貝的數據長度;
例: char a[100],b[50];
memcpy(b,a,sizeof(b));
//注意:如果使用sizeof(a),會造成內存溢出
mem是一段內存,他的長度,必須自己記住.memcpy是見着什么拷貝什么。
strcpy 就只能拷貝字符串,它遇到'\0'就結束拷貝;
例:char a[100],b[50]; strcpy(a,b);
如用strcpy(b,a)要注意a中的字符串長度(第一個'\0'之前) 是否超過50,如果超過,則會造成b的 內存溢出.
它是不會拷貝'\0'的,所以一般還有加一個語句: *a='\0';
三.使用技巧
memset 可以方便的清空一個數據結構的變量或數組.
如: struct sample_struct {
char csName[16];
int iSeq;
int iType;
};
對於變量
struct sample_struct stTest;
一般情況下,初始化stTest的方法:
stTest.csName[0]='\0';
stTest.iSeq=0;
stTest.iType=0;
而用memset:
memset(&stTest,0,sizeof(struct sample_struct));
如果是數組:
struct sample_struct TEST[100];
memset(TEST,0,sizeof(struct sample_struct)*100);