strcmp () strcat() strcpy()源码分析学习

 

这三个库函数都熟悉用法,但是源码还没有读过,网上找了源码学习一下

来源:https://blog.csdn.net/wangningyu/article/details/4662891

  1 /************************************************************************
  2 
  3 *char *strcpy(dst, src) - copy one string over another
  4 
  5 *
  6 
  7 *Purpose:
  8 
  9 * Copies the string src into the spot specified by
 10 
 11 * dest; assumes enough room.
 12 
 13 *
 14 
 15 *Entry:
 16 
 17 * char * dst - string over which "src" is to be copied
 18 
 19 * const char * src - string to be copied over "dst"
 20 
 21 *
 22 
 23 *Exit:
 24 
 25 * The address of "dst"
 26 
 27 *
 28 
 29 *Exceptions:
 30 ************************************************************************/
 31 char* strcpy(char * dst, const char * src)
 32 {
 33     char * cp = dst;
 34     while( *cp++ = *src++ )
 35         ;                            /* Copy src over dst */
 36     return( dst );
 37 }
 38 
 39 
 40 /************************************************************************
 41 
 42 *char *strcat(dst, src) - concatenate (append) one string to another
 43 
 44 *
 45 
 46 *Purpose:
 47 
 48 * Concatenates src onto the end of dest. Assumes enough
 49 
 50 * space in dest.
 51 
 52 *
 53 
 54 *Entry:
 55 
 56 * char *dst - string to which "src" is to be appended
 57 
 58 * const char *src - string to be appended to the end of "dst"
 59 
 60 *
 61 
 62 *Exit:
 63 
 64 * The address of "dst"
 65 
 66 *
 67 
 68 *Exceptions:
 69 
 70 *
 71 ************************************************************************/
 72 char* strcat ( char * dst , const char * src )
 73 {
 74     char * cp = dst;
 75     while( *cp )
 76         cp++;                        /* find end of dst */
 77     while( *cp++ = *src++ ) ;        /* Copy src to end of dst */
 78     return( dst );                    /* return dst */
 79 }
 80 
 81 
 82 /************************************************************************
 83 
 84 *strcmp - compare two strings, returning less than, equal to, or greater than
 85 
 86 *
 87 
 88 *Purpose:
 89 
 90 * STRCMP compares two strings and returns an integer
 91 
 92 * to indicate whether the first is less than the second, the two are
 93 
 94 * equal, or whether the first is greater than the second.
 95 
 96 *
 97 
 98 * Comparison is done byte by byte on an UNSIGNED basis, which is to
 99 
100 * say that Null (0) is less than any other character (1-255).
101 
102 *
103 
104 *Entry:
105 
106 * const char * src - string for left-hand side of comparison
107 
108 * const char * dst - string for right-hand side of comparison
109 
110 *
111 
112 *Exit:
113 
114 * returns -1 if src < dst
115 
116 * returns 0 if src == dst
117 
118 * returns +1 if src > dst
119 
120 *
121 
122 *Exceptions:
123 
124 *
125 ************************************************************************/
126 int strcmp ( const char* src, const char* dst )
127 {
128     int ret = 0 ;
129     while( !(ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
130         ++src, ++dst;
131     if ( ret < 0 )
132         ret = -1 ;
133     else if ( ret > 0 )
134         ret = 1 ;
135     return( ret );
136 }

1. strcmp

int strcmp ( const char* src, const char* dst )
{
    int ret = 0 ;
    while( !(ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
        ++src, ++dst;
    if ( ret < 0 )
        ret = -1 ;
    else if ( ret > 0 )
        ret = 1 ;
    return( ret );
}

我们要看的是while循环这个语句, ! (ret = *(unsigned char *)src - *(unsigned char *)dst)意思是拿指针变量src所指向的字符值(即*src)减去指针变量dst所指向的字符值(即*dst),差值赋给ret,再取非运算,最后与*dst进行与运算;

! ret表示ret=0才继续比较。

 

为什么要把src转成unsigned char *类型?

  使用*(unsigned char *)str1而不是用*str1。这是因为传入的参数为有符号数,有符号字符值的范围是-128-127,无符号字符值的范围是0-255,而字符串的ASCII没有负值,若不转化为无符号数,在减法实现时出现错误。

例如:str的值为1,str2的值为255。

作为无符号数计算时ret=-254,结果为负值,正确。

作为有符号数计算时ret=-2,结果为正值,错误。

 

while循环中(ret=*(unsigned char *)str1 - *(unsigned char *)str2)&& *str1,最后的str1也可以换成str2,因为前面已经做了相减,无论哪个先为'\0'都会退出。

这个函数没有判断参数为NULL时的情况,所以当传入NULL时程序会崩溃。

 

2. strcat

char* 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 */
}
 while( *cp )
        cp++;
不能写成while(*cp++), 因为这样的话为*cp为0时还会+1,导致cp指向了\0的后一个。

为什么直接拷贝到strDset中,还要返回char*型呢?为了实现链表表达式
如int length = strlen( strcpy( strDest, “hello world”) );


3.strcpy
char* strcpy(char * dst, const char * src)
{
    char * cp = dst;
    while( *cp++ = *src++ )
        ;                            /* Copy src over dst */
    return( dst );
}

还有另一个strncpy,加上了长度控制count

char * __cdecl strncpy ( char * dest, constchar * source, size_t count )

{

    char *start = dest;

    while (count && (*dest++ = *source++)) /* copy string */   

        count--;

    if (count) /* pad out with zeroes */

    while (--count)

        *dest++ ='\0';

    return(start);
}        

 

 
posted @ 2019-01-20 19:57  xuqiushuo  阅读(468)  评论(0编辑  收藏  举报