memcpy 函数
该函数的实现如下:
void *memcpy(void *dst, const void *src, size_t n)
{
assert(dst != NULL && src != NULL && n > 0);
/*
* 在 ANSIC 标准中,不允许 void 类型指针进行算术运算;
* 在 GNU 标准中,是允许的,默认 void* 与 char * 一样;
*/
char *pdst = (char *)dst;
const char *psrc = (const char *)src;
while(n--)
{
*pdst++ = *psrc++;
}
return dst;
}
memmove 函数
该函数的实现如下:
void *memmove(void *dst, const void *src, size_t n)
{
assert(dst != NULL && src != NULL && n > 0);
/*
* 当dst与src内存不重叠;
* 则从低地址开始复制;
*/
if(dst < src)
{
char *pdst = (char *)dst;
const char *psrc = (const char *)src;
while(n--)
{
*pdst++ = *psrc++;
}
}
/*
* 若dst的地址与src地址部分重叠;
* 则从高地址开始复制;
*/
else
{
char *pdst = (char *)dst + n -1;
const char *psrc = (const char *)src +n -1;
while(n--)
{
*pdst-- = *psrc--;
}
}
return dst;
}
strcpy 函数
该函数的实现如下:
char *strcpy(char *dst, const char *src)
{
if(dst == NULL || src == NULL)
return NULL;
char *tdst = dst;
while((*tdst++ = *src++) != '/0');
return tdst;
}
strncpy 函数
该函数的实现如下:
char *strncpy(char *dst, const char *src, size_t n)
{
if(dst == NULL || src == NULL || n <= 0)
return NULL;
char *tdst = dst;
while(n-- && (*tdst++ = *src++) != '/0');
*tdst = '/0';
return tdst;
}
拷贝函数小结
strcpy 和 memcpy 主要有以下3方面的区别:
- 复制的内容不同:strcpy 只能复制字符串,而 memcpy 可以复制任意内容,例如字符数组、整型、结构体、类等;
- 复制的方法不同:strcpy 不需要指定长度,它遇到字符串结束符"/0" 便结束。memcpy 则是根据其第 3 个参数决定复制的长度;
- 用途不同:通常在复制字符串时用 strcpy,而需要复制其他类型数据时则一般用memcpy;
memmove 和 memcpy 函数的区别在于内存重叠问题,memmove 函数考虑到内存重叠问题,而memcpy 函数没考虑重叠;
memcmp 函数
该函数的实现如下:
int memcmp(const void *ptr1, const void *ptr2, size_t n)
{
assert(ptr1 != NULL && ptr2 != NULL && n > 0);
const unsigned char *tptr1 = (const unsigned char *)ptr1;
const unsigned char *tptr2 = (const unsigned char *)ptr2;
int res = 0;
for(; n > 0; tptr1++, tptr2++, n--)
{
if( (res = *tptr1 - *tptr2) != 0)
break;
}
return res;
}
strcmp 函数
该函数的实现如下:
int strcmp(const char *str1, const char *str2)
{
assert(str1 != NULL && str2 != NULL );
int res = 0;
while(1)
{
if( (res = *str1 - *str2++) != 0 || !*str1++)
{
break;
}
}
return res;
}
strncmp 函数
该函数的实现如下:
int strncmp(const char *str1, const char *str2, size_t n)
{
assert(str1 != NULL && str2 != NULL && n > 0);
int res = 0;
while(n)
{
if( (res = *str1 - *str2++) != 0 || !*str1++)
{
break;
}
n--;
}
return res;
比较函数小结
strcmp 和 memcmp 的区别:strcmp 函数比较的过程中当遇到字符串结束符'/0' 时结束比较操作,而memcmp 函数是比较两个字符串的前n 个字符,不管是否遇到字符串结束符 ‘/0’ 都要比较n 次;
memchr 函数
该函数的实现如下:
void *memchr(const void *ptr, int value, size_t n)
{
assert(ptr != NULL && n > 0);
const unsigned char *tptr = (const unsigned char *)ptr;
while(n && *tptr != value)
{
n--;
tptr++;
}
return (n ? (void *)tptr:NULL);
}
memset 函数
该函数的实现如下:
void *memset(void *ptr, int value, size_t n)
{
assert(ptr != NULL && n > 0);
char *tptr = (char *)ptr;
while(n--)
{
*tptr++ = value;
}
return ptr;
}
strlen 函数
该函数实现如下:
size_t strlen(const char *ptr)
{
const char *tptr = ptr;
while(*tptr++);
return (tptr - ptr - 1);/* 不包含末尾的空字符 */
}
程序测试
int main ()
{
/******************* memcpy ***********************/
char buffer1[] = "DWgaOtP12df0";
char buffer2[] = "DWGAOTP12DF0";
int n;
n=memcmp ( buffer1, buffer2, sizeof(buffer1) );
if (n>0) printf ("'%s' is greater than '%s'.\n",buffer1,buffer2);
else if (n<0) printf ("'%s' is less than '%s'.\n",buffer1,buffer2);
else printf ("'%s' is the same as '%s'.\n",buffer1,buffer2);
/*********** memchr ***********/
char * pch;
char str[] = "Example string";
pch = (char*) memchr (str, 'p', strlen(str));
if (pch!=NULL)
printf ("'p' found at position %d.\n", pch-str+1);
else
printf ("'p' not found.\n");
/************* memcpy **********/
char myname[] = "Pierre de Fermat";
/* using memcpy to copy string: */
memcpy ( person.name, myname, strlen(myname)+1 );
person.age = 46;
/* using memcpy to copy structure: */
memcpy ( &person_copy, &person, sizeof(person) );
printf ("person_copy: %s, %d \n", person_copy.name, person_copy.age );
/************* memmove **********/
char str2[] = "memmove can be very useful......";
memmove (str2+20,str2+15,11);
puts (str2);
/************* memset ***********/
memset (str,'-',7);
puts (str);
return 0;
}