char *strcpy(char *dest, const char *src)
把 src 所指向的字符串复制到 dest。
char *strncpy(char *dest, const char *src, size_t n)
把 src 所指向的字符串复制到 dest,最多复制 n 个字符。
void *memcpy(void *dest, const void *src, size_t n)
从 src 复制 n 个字符到 dest。
void *memmove(void *dest, const void *src, size_t n)
另一个用于从 str2 复制 n 个字符到 str1 的函数。
这个几个函数经常用,但还是对参数类型和个数混淆,所以想深究一下其中的逻辑;
具有相似性:都是定义在c标准库 -<string.h>中的内存操作相关的函数;
str–是对非空字符序列进行操作,所以函数中,指针参数都是char* ,会以字符串结束符‘\0’作为结束标志;’\0’在内存中的表示是00000000,一个字节,八位全0,数值为0;strcpy在做字符串拷贝时,内存字节数值0表示字符串结束, 没有问题。
但用在其他类型内存中,内存字节数值0并不表示结束,比如int型数组,如果int数值为0,就有4个字节数值为0,int数值为1,就有3个字节数值为0;这时拷贝就需要用memcpy,因为不知道什么时候结束,所以mem–函数指针参数是void*,都需要第三个参数(size_t n)来标记;
char* test_strcpy(char* dest,const char* src)
{
if(dest==NULL || src==NULL)
return NULL;
char* temp=dest;
while((*temp++ = *src++ )!='\0'){}
return dest;
}
void *test_memcpy(void *dest, const void *src, size_t count)
{
if(dest==NULL || src==NULL)
return NULL;
char *temp = dest;
const char *s = src;
while (count--)
*tmp++ = *s++;
return dest;
}
strncpy像是strcpy的补充版,需要拷贝字符串的一部分时用;
需要注意:
- 当strlen(src)<n时,dest 的剩余部分将用空字节填充。
- 当strlen(src)>=n时,可能需要手工写上 ‘\0’
char * test_strncpy(char *dest, const char *src, size_t count)
{
if(dest==NULL || src==NULL)
return NULL;
char* temp=dest;
while (count--)
{
if ((*tmp = *src) != 0)
src++;
tmp++;
}
return dest;
}
以上3个函数中,正确使用需要满足:
- dest 和src所指向的内存空间不可以重叠
- dest空间足够,否则会溢出的
如果dest 和src重叠,就可以用memmove。
void * test_memmove(void *s1, const void *s2, size_t n)
{
if(dest==NULL || src==NULL)
return NULL;
char *p1 = s1;
const char *p2 = s2;
if (n>0) {
if (p2 <= p1 && p2 + n > p1) {
/* overlap, copy backwards */
p1 += n;
p2 += n;
n++;
while (--n > 0) {
*--p1 = *--p2;
}
} else {
n++;
while (--n > 0) {
*p1++ = *p2++;
}
}
}
return s1;
}