memcpy
函数原型:
函数功能:memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。函数返回值指向dest的指针。不考虑内存重叠
- #include<stdio.h>
- #include<assert.h>
- #include<string.h>
- void* Memcpy(void* dst, const void* src, size_t size)
- {
- assert(dst);
- assert(src);
- char* pdst = (char*)dst;
- const char* psrc = (const char*)src;
-
- while (size--)
- {
- *pdst++ = *psrc++;
- }
-
- return dst;
- }
- int main()
- {
- char dst[20];
- memset(dst, '\0', sizeof(dst));
- char src[] = "hello";
- printf("%s\n", Memcpy(dst, src, strlen(src)));
- return 0;
- }
memcpy函数的优化
- #include<stdio.h>
- #include<assert.h>
- #include<string.h>
- void* Memcpy(void* dst, const void* src, size_t size)
- {
- int len = size / 4;
- int mod = size % 4;
- int* pdst = (int *)dst;
- const int* psrc = (const int*)src;
-
- if (mod == 0)
- {
- return dst;
- }
- while (len--)
- {
- *pdst++ = *psrc++;
- }
- char* p = (char*)dst;
- p += len*sizeof(int);
- const char* q = (const char*)src;
- q += len*sizeof(int);
- while (mod--)
- {
- *p++ = *q++;
- }
- return dst;
- }
- int main()
- {
- char dst[20];
- memset(dst, '\0', sizeof(dst));
- const char* src = "hello";
- printf("%s\n", Memcpy(dst, src, strlen(src)));
- return 0;
- }
memmove
函数原型:
函数功能:memmove用于从src拷贝count个字符到dest,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中。但复制后src内容会被更改。但是当目标区域与源区域没有重叠则和memcpy函数功能相同。
- #include<stdio.h>
- #include<assert.h>
- #include<string.h>
- void* Memmove(void* dst, const void* src, size_t size)
- {
- assert(dst);
- assert(src);
- char* pdst = (char*)dst;
- const char* psrc = (const char*)src;
- if (pdst > psrc + size || pdst < psrc)
- {
- while (size--)
- {
- *pdst++ = *psrc++;
- }
- }
- else
- {
- pdst = pdst + size-1;
- psrc = psrc + size-1;
- while (size--)
- {
- *pdst-- = *psrc--;
- }
- }
- return dst;
- }
- int main()
- {
- char dst[20];
- memset(dst, '\0', sizeof(dst));
- char src[] = "hello";
- printf("%s\n", Memmove(dst, src, strlen(src)));
- return 0;
- }
memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中。
但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开销。
memmove的处理措施:
(1)当源内存的首地址大于目标内存的首地址时,实行正向拷贝
(2)当源内存的首地址小于目标内存的首地址时,实行反向拷贝
memset
函数原型:
函数功能:将s所指向的某一块内存中的前n个 字节的内容全部设置为ch指定的ASCII值, 第一个值为指定的内存地址,块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作, 其返回值为指向s的指针。
- #include<stdio.h>
- #include<assert.h>
- void* Memset(void* str, char c, size_t size)
- {
- assert(str);
- char* s = (char*)str;
- while (size--)
- {
- *s++ = c;
- }
- return str;
- }
- int main()
- {
- char s[] = "hello world";
- printf("%s\n", s);
- Memset(s, '0', strlen(s));
- printf("%s\n", s);
- return 0;
- }
strcpy strncpy
函数原型:
函数功能:strcpy把从src地址开始且含有'\0'结束符的字符串复制到以dest开始的地址空间。返回指向dest的指针。src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
strncpy把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回dest。
- #include<stdio.h>
- #include<assert.h>
- #include<string.h>
- char* Strcpy(char* dst,const char*src)
- {
- assert(dst);
- assert(src);
- char* pdst = dst;
- while (*src)
- {
- *dst++ = *src++;
- }
- return pdst;
- }
- int main()
- {
- const char src[] = "hello,hello bit";
- char dst[] = "";
- printf("%s\n", Strcpy(src, dst));
- return 0;
- }
strcpy和memcpy主要有以下3方面的区别。
2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy
- #include<stdio.h>
- #include<assert.h>
- char* Strncpy(char* dst, const char* src, size_t size)
- {
- assert(dst);
- assert(src);
- char* pdst = dst;
- while (size--)
- {
- *dst++ = *src++;
- }
- return pdst;
- }
- int main()
- {
- char dst[20];
- memset(dst, '\0', sizeof(dst));
- const char* src = "hello";
- printf("%s\n", Strncpy(dst, src, strlen(src)));
- return 0;
- }