memcpy,memmove,memset函數福彩3D平臺搭建用法及實現
1、memcpy
函數原型:extern void memcpy(void dest, const void *src, size_t count);
用法:#include<string.h>
功能:由src所指內存區域復制count個字節到dest所指內存區域。
說明:src和dest所指內存區域不能重疊,函數返回指向dest的指針。
註意:和strcpy相比,memcpy不是遇到’/0’就結束,而是一定會拷貝完n個字節。
函數實現代碼:
void memcpy(void dest, const void *src, size_t count)
assert(dest!=NULL&&src!=NULL);
char *tmp = dest;
const char *s = src;
while (count--)
*tmp++ = *s++;
return dest;
}
2、memset
函數原型:extern void memset(void s, int c, size_t n)
功能:將已開辟內存空間s的首n個字節的值設為值c。將s中的前n個字符替換為c,並返回s。
memset常用於內存空間的初始化。
memset的深刻內涵:用來對一段內科空間全部設置為某個字符,一般用在對定義的字符串進行初始化為:memset(a, ‘/0’, sizeof(a));
函數實現代碼:
void memset(void buffer, int c, int count)
{
char buffer_p=(char)buffer;
assert(buffer != NULL);
while(count-->0)
*buffer_p++=(char)c;
return buffer;
}
3、memmove
void memmove(void s, const void *ct, size_t n)
與memcpy類似,所不同的是,當對象重疊時,該函數仍能正確執行,具體的實現代碼在下面有詳細解釋。
4、strncpy
函數原型:extern char strncpy(char
用法:#include <string.h>
功能:把src所指由NULL結束的字符串的前n個字節復制到dest所指的數組中。
說明:
如果src的前n個字節不含NULL字符,則結果不會以NULL字符結束。
如果src的長度小於n個字節,則以NULL填充dest直到復制完n個字節。
src和dest所指內存區域不可以重疊且dest必須有足夠的空間來容納src的字符串。
返回指向dest的指針(該指向dest的最後一個元素)
實現代碼:
char strncpy(char dest,const char src,size_t count)
{
char tmp = dest;
while (count-- && (dest++ = src++) != ‘/0‘)
/ nothing /;
return tmp;
}
5、strcpy:
函數原型:extern char strcpy(char dest,char *src);
頭文件:string.h
功能:把src所指由NULL結束的字符串復制到dest所指的數組中。
說明:src和dest所指內存區域不可以重疊且dest必須有足夠的空間來容納src的字符串。 返回指向dest的指針。如果src的結尾不是‘/0‘的話,那麽系統會在src的結尾處自動加一個‘/0‘。例如:
#include <stdio.h>
#include <string.h>
void main()
{
char array1[5]={‘1‘,‘2‘,‘3‘,‘4‘,‘5‘};
char array2[5]={‘a‘,‘b‘,‘c‘};
strcpy(array1,array2);
printf("%s/n",array1);
}
輸出結果:abc
函數實現代碼:
char strcpy(char strDest, const char strSrc)
{
assert((strDest!=NULL) && (strSrc !=NULL));
char address = strDest;
while( (strDest++ = strSrc++) != ‘/0‘)
NULL ;
return address ;
}
二.下面重點來講解memcpy和memmove的區別:
這兩個函數的函數原型(除了名字)是一樣的:
void memcpy(void dst, const void src, size_t count):
void memmove(void dst, const void src, size_t count);
它們都是從src所指向的內存中復制count個字節到dst所指內存中,並返回dst的值。當源內存區域和目標內存區域無交叉時,兩者的結果都是一樣的。但有交叉時不一樣。源內存和目標內存交叉的情況有以下兩種:(左邊為低地址)
即:dst<=src 且 dst+count>src
即:src<dst且src+count>dst
下面將針對這兩種情況來討論。針對第一種交叉情況情況,dst<src且dst+count>src,memcpy和memmove的結果是一樣的。請看下面的例子講解:
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
memcpy(a, a+4, sizeof(int)6);和memmove(a, a+4, sizeof(int)6);結果是:
4567896789
針對第二種情況,src<dst且src+count>dst,memcpy和memmove的結果是不一樣的。請看下面的例子:
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
memcpy(a+4, a, sizeof(int)*6)
memmove(a+4, a, sizeof(int)*6)
下面是這兩個函數的具體實現:
void memcpyMy(void dst, const void *src, size_t count)
{
void *address = dst;
while (count)
{
*(char *)address = *(char *)src;
address = (char *)address + 1;
src = (char *)src + 1;
count --;
}
return dst;
}
void memmoveMy(void dst, const void *src, size_t count)
{
void *address = dst;
if (dst <= src || (char*)dst >= (char *)src + count)
{
while (count --)
{
*(char *)address = *(char *)src;
address = (char *)address + 1;
src = (char *)src + 1;
}
}
else
{
address = (char *)address + count - 1;
src = (char *)src + count - 1;
while (count --)
{
*(char *)address = *(char *)src;
address = (char *)address - 1;
src = (char *)src - 1;
}
}
return dst;
}
以上兩段代碼是在vc6.0下通過測試的。
memcpy,memmove,memset函數福彩3D平臺搭建用法及實現