小功能实现

memcpy memmove区别和实现

memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中。

但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开销。

memmove的处理措施:

(1)当源内存的首地址等于目标内存的首地址时,不进行任何拷贝

(2)当源内存的首地址大于目标内存的首地址时,实行正向拷贝

(3)当源内存的首地址小于目标内存的首地址时,实行反向拷贝

-- memcpy实现

?
1
2
3
4
5
6
7
8
void * memcpy ( void * dest, const  void * src, size_t  n)
{
     char *      d = ( char *) dest;
     const  char *  s = ( const  char *) src;
     while (n-–)
        *d++ = *s++;
     return  dest;
}

 

-- memmove实现

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void * memmove ( void * dest, const  void * src, size_t  n)
{
     char *     d  = ( char *) dest;
     const  char *  s = ( const  char *) src;
  
     if  (s>d)
     {
          // start at beginning of s
          while  (n--)
             *d++ = *s++;
     }
     else  if  (s<d)
     {
         // start at end of s
         d = d+n-1;
         s = s+n-1;
  
         while  (n--)
            *d-- = *s--;
     }
     return  dest;
}

 示意图:

(1)内存低端 <-----s-----> <-----d-----> 内存高端 start at end of s
(2)内存低端 <-----s--<==>--d----->      内存高端 start at end of s
(3)内存低端 <-----sd----->              内存高端 do nothing
(4)内存低端 <-----d--<==>--s----->      内存高端 start at beginning of s
(5)内存低端 <-----d-----> <-----s-----> 内存高端 start at beginning of s

strcat源码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/***
*char *strcat(dst, src) - concatenate (append) one string to another
 在C里面,0为假,非0为真。对于while( *cp++ = *src++ )来说,什么时候结束循环就要看*cp++ = *src++表达式的值什么时候为0,赋值表达式的值为=运算符左值的值,当*src遇到字符串结束符'\0'的时候,'\0'被赋予*cp,这同时也是上述赋值表达式的值,这时候表达式的值为假,循环结束。
*******************************************************************************/
char  * __cdecl strcat  (   char  * dst,   const  char  * src   )
{
         char  * cp = dst;
         while ( *cp )
                 cp++;                   /* find end of dst */
         while ( *cp++ = *src++ ) ;       /* Copy src to end of dst */
         return ( dst );                  /* return dst */
}
在vs2008中
char str1[5]="ab"; char str2[]="hahah"; strcat(str1,str2); cout<<str1<<" "<<strlen(str1);
结果为 abhahah 7
说明str1是作为指针处理的,没有给出出错提示。


strcpy源码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/***
*char *strcpy(dst, src) - copy one string over another,
*后面的字符串将覆盖前面的
*
*******************************************************************************/
 
char  * __cdecl strcpy ( char  * dst, const  char  * src)
{
         char  * cp = dst;
         while ( *cp++ = *src++ )
                 ;               /* Copy src over dst */
         return ( dst );
}
在vs2008中
char str1[5]="ab"; char str2[]="hahahaha"; strcpy(str1,str2); cout<<str1<<" "<<strlen(str1);
结果为hahahaha 8
说明str1是作为指针的,没有给出出错提示。

    ·当src到达 '\0’时,*cp被赋值为'\0’,整个表达式的值即为'\0’,对应的ASC码值为0    =>while退出



strcmp源码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/***
*strcmp - compare two strings, returning less than, equal to, or greater than
*Exit:
*       returns -1 if src <  dst
*       returns  0 if src == dst
*       returns +1 if src >  dst
*******************************************************************************/
 
int  __cdecl strcmp  (   const  char  * src,    const  char  * dst)
{
         int  ret = 0 ;
 
         while ( ! (ret = *(unsigned char  *)src - *(unsigned char  *)dst) && *dst) //直到src和dst当前数值不相等或dst为\0时退出while
                 ++src, ++dst;
 
         if  ( ret < 0 )
                 ret = -1 ;
         else  if  ( ret > 0 )
                 ret = 1 ;
         return ( ret );
}


strncmp源码
int strncmp ( char * s1, char * s2, size_t n) 用法:#include <string.h> 功能: 比较字符串s1和s2的前n个字符. 返回结果:如果前n字节完全相等,返回值就=0;在前n字节比较过程中,如果出现s1[n]与s2[n]不等,则返回(s1[n]-s2[n]) 源码实现: int strncmp ( char * s1, char * s2, size_t n) {   if ( !n )//n为无符号整形变量;如果n为0,则返回0    return(0);   //在接下来的while函数中   //第一个循环条件:--n,如果比较到前n个字符则退出循环   //第二个循环条件:*s1,如果s1指向的字符串末尾退出循环   //第二个循环条件:*s1 == *s2,如果两字符比较不等则退出循环   while (--n && *s1 && *s1 == *s2)   {      s1++;//S1指针自加1,指向下一个字符      s2++;//S2指针自加1,指向下一个字符   }   return( *s1 - *s2 );//返回比较结果 }


strstr源码

extern char *strstr(char *s1, char *s2)

用法:#include <string.h> 功能: 找出s2字符串在s1字符串中第一次出现的位置(不包括s2的串结束符) 返回结果:返回该位置的指针,如找不到,返回空指针。 源码实现:

char *strstr( const char *s1, const char *s2 ) {    int len2;

       len2= strlen(s2);

       if(len2 ==0)

              return (char *)s1;

       for ( ; *s1; ++s1 )     {         if ( *s1 == *s2 && strncmp( s1, s2, len2 )==0 )  //这里多加一个判断*s1 == *s2         return (char *)s1;     } return NULL; }

itoa源码
char* _itoa(int value, char* string, int radix)
{
char tmp[33];
char* tp = tmp;
int i;
unsigned v;
int sign;
char* sp;
if (radix > 36 || radix <= 1)
return 0;
sign = (radix == 10 && value < 0);
if (sign)
v = -value;
else
v = (unsigned)value;
while (v || tp == tmp) //转化操作
{
i = v % radix;
v = v / radix;
if (i < 10)
*tp++ = i+'0';
else
*tp++ = i + 'a' - 10;
}
if (string == 0)
string = (char*)malloc((tp-tmp)+sign+1);
sp = string;
if (sign)
*sp++ = '-';
while (tp > tmp)
*sp++ = *--tp;
*sp = 0;
return string;
}


atoi源码
link:剑指offer p250
long long core(char *str,bool minus);
int _atoi(char *str)
{
long long num=0;
long long sum=0;
if(str!=NULL &&str!='\0')
{
bool minus = false;
if(*str=='+')
str++;
else if(*str=='-')
{
minus=true;
str++;
}
sum=core(str,minus);
}
return (int)sum;
}
long long core(char *str,bool minus)
{
long long num=0;
while(*str!='\0')
{
if(*str >='0' && *str <='9')
{
num=num*10+(*str-'0');
if((!minus && num>0x7fffffff )|| (minus &&(0-num)<(signed int)0x80000000))
{
num=0;
break;
}
str++;
}
else
{
num=0;
break;
}
}
return num;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值