日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

细谈C语言中的strcpy,strncpy,memcpy,memmove,memset函数

發布時間:2025/3/21 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 细谈C语言中的strcpy,strncpy,memcpy,memmove,memset函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一.函數介紹:
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 *dest, char *src, int n);?
用法:#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下通過測試的。

總結

以上是生活随笔為你收集整理的细谈C语言中的strcpy,strncpy,memcpy,memmove,memset函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。