标准C库一一memchr、memcmp、memcpy、memset详解

前言

在字符串处理中经常要用到memchr、memcmp、memcpy、memmove、memset等函数来处理字符串。并且它们都是标准C库,在string.h头文件中有定义。string.h头文件提供了一些分析和操控字符串的函数。其中一些函数以更通用的方式处理内存。memchr用于字符串查找,memcmp用于比较内存中缓冲区的大小,memcpy和memmove的作用是拷贝一定长度内存的内容,memset用于缓冲区的填充工作。

memchr 查找内存内容

函数原型

void* memchr(const void* buf,int ch,size_t count)

描述:
从buf所指内存区的前count个字节查找字符ch,当第一次遇到字符ch时停止查找。如果成功,返回指向字符ch的指针;否则返回null

my_memchr

void *my_memchr(const void *ptr,int value,int num)
{
	if (NULL == ptr)
		return ;
	char *ps = (char *)ptr;
	while (num --)
	{
		if (*ps != (char) value)
			ps ++; 
		else
			return ps;
	}

	return NULL;
}

上面的my_memchr是自己实现的,这个函数的行为就好像它按顺序读取字符,并在找到匹配字符时立即停止:如果ptr指向的数组小于value,但是在数组中找到了匹配,则行为定义良好。

下面的实例演示了 memchr() 函数的用法。

#include 
#include //memchr

void *my_memchr(const void *ptr,int value,int num)
{
	if (NULL == ptr)
		return ;
	char *ps = (char *)ptr;
	while (num --)
	{
		if (*ps != (char) value)
			ps ++; 
		else
			return ps;
	}

	return NULL;
}


int main(int argc, char const *argv[])
{
	
	char *pch;
	char str[] = "Example string";
	pch = (char *)memchr(str,'p',strlen(str));
	if (pch != NULL)
		printf("memchr  'p' found at position %d,search character found %s\n",pch-str+1,pch);
	else
		printf (" not found\n");

	pch = (char *)my_memchr(str,'p',strlen(str));
	if (pch != NULL)
		printf("my_memchr  'p' found at position %d,search character found %s\n",pch-str+1,pch);
	else
		printf (" not found\n");


	return 0;
}

输出结果:

在这里插入图片描述
可以找到字符串的位置,以及找到的字符串。

memcmp 内存比较

函数原型:

int memcmp(const void* buf1,const void* buf2,unsigned int count)

描述:

比较buf1和buf2的前count个字节。

返回值:
当buf1

当buf1==buf2时,返回值=0

当buf1>buf2时,返回值>0

memcmp函数原型实现:

int my_memcpy(const void *s1,const void *s2,size_t count)
{
	int ret = 0;
	const unsigned char *p1= (const unsigned char *)s1;
	const unsigned char *p2 = (const unsigned char *)s2;

	for (; count > 0; p1++, p2++, count--)
		if ((ret = *p1 - *p2) != 0)
			break;

	return ret;
}

下面的实例演示了 memcmp() 函数的用法:

#include 
#include  //memcmp
#include 

int my_memcpy(const void *s1,const void *s2,size_t count)
{
	int ret = 0;
	const unsigned char *p1= (const unsigned char *)s1;
	const unsigned char *p2 = (const unsigned char *)s2;

	for (; count > 0; p1++, p2++, count--)
		if ((ret = *p1 - *p2) != 0)
			break;

	return ret;
}


int main(int argc, char const *argv[])
{
	

	 char buffer1[] = "abcdOtP12df0";
	 char buffer2[] = "ADCDOTP12DF0";

	 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);

	printf("===============================\n" );
	 n=my_memcpy ( 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);


	return 0;
}



输出结果:
在这里插入图片描述

memcpy 拷贝内存内容

原型:

void * memcpy ( void * destination, const void * source, size_t num );

描述:

将num字节的值从源指向的位置直接复制到目标指向的内存块。如果两个位置出现重叠,其行为未定义。

返回值:
返回目的地

memcpy函数原型实现

void *my_memcpy(void *dest,const void* src, size_t count)
{
	char *pdest = (char *)dest;
	char *psrc = (char *)src;

	while (count --)
		*pdest = *psrc;
	return pdest;		
}

下面的实例演示了 memcpy() 函数的用法:

#include 
#include //memcpy

struct {
  char name[40];
  int age;
} person, person_copy;


void *my_memcpy(void *dest,const void* src, size_t count)
{
	char *pdest = (char *)dest;
	char *psrc = (char *)src;

	while (count --)
		*pdest = *psrc;
	return pdest;		
}


int main(int argc, char const *argv[])
{
  char myname[] = "Pierre de Fermat";

  //使用memcpy复制字符串
  memcpy ( person.name, myname, strlen(myname)+1 ); //memcpy会完成的复制n个字节,不会遇到字符串结束'\0'而结束
  person.age = 46;

  //使用memcpy复制结构:
  memcpy ( &person_copy, &person, sizeof(person) );

  printf ("person_copy: %s, %d \n", person_copy.name, person_copy.age );

  printf("========================\n");

    //使用my_memcpy复制字符串
  my_memcpy ( person.name, myname, strlen(myname)+1 );
  person.age = 46;

  //使用my_memcpy复制结构:
  my_memcpy ( &person_copy, &person, sizeof(person) );

  printf ("my_memcpy -> person_copy: %s, %d \n", person_copy.name, person_copy.age );

  return 0;
}


输出结果:
标准C库一一memchr、memcmp、memcpy、memset详解_第1张图片

memset 设置内存内容

函数原型:

void * memset ( void * ptr, int value, size_t num );

描述:

将ptr所指向的某一块内存中的前num个字节全部设置成value制定的ASCII值,块的大小由第三个参数制定,这个函数通常为新申请的内存做初始化工作。

返回值
返回ptr。

memset函数原型实现:

void *my_memset ( void * ptr, int value, size_t num )
{

     const unsigned char uc = value;
     unsigned char *tptr = ptr;
     for(;0 < num; ++tptr,--num)
         *tptr = uc;
     return ptr;
}

下面的实例演示了 memset() 函数的用法:


#include 
#include //memset

void *my_memset ( void * ptr, int value, size_t num )
{

     const unsigned char uc = value;
     unsigned char *tptr = ptr;
     for(;0 < num; ++tptr,--num)
         *tptr = uc;
     return ptr;
}

int main(int argc, char const *argv[])
{
	
    char str[] = "almost every programmer should know memset!";
    memset (str,'-',6);
    puts (str);

    printf("===================\n");
    my_memset (str,'-',6);
    puts (str);

	return 0;
}

输出结果:
标准C库一一memchr、memcmp、memcpy、memset详解_第2张图片

标准C库一一memchr、memcmp、memcpy、memset详解_第3张图片

扫二维码关注微信公众号,获取技术干货

你可能感兴趣的:(C/C++)