c 语言---部分标准库函数及源码

部分标准库函数及源码

- 数据和宏定义

#define NULL ((void *)0)

#define TOLOWER(c)  ((((c) > 'A') && ((c) < 'Z')) ? ((c) - 'A' + 'a') : (c))

typedef unsigned int size_t;
  • 1、memcpy:从存储区 src 复制 n 个字符到存储区 dest
void *func_memcpy(void *dst, const void *src, size_t cnt)
{
    void *ret = dst;

    while(cnt--)
    {
        *(char *)dst = *(char *)src;
        dst = (char *)dst + 1;
        src = (char *)src + 1;
    }
    
    return ret;
}
  • 2、memchr:在buff 所指向的字符串的前 n个字节中搜索第一次出现字符 chr
void *func_memchr(const void *buff, int chr, size_t cnt)
{
    while(cnt && *(unsigned char *)buff != (unsigned char)chr)
    {
        buff = (unsigned char *)buff + 1;
        cnt--;
    }

    return (cnt > 0 ? (void *)buff : NULL);
}
  • 3、memcmp:把 buff1和 buff2的前 n 个字节进行比较
int func_memcmp(const void *buff1, const void *buff2, size_t cnt)
{
    if(cnt == 0)
    {
        return 0;
    }

    while(cnt-- && *(char *)buff1 == *(char *)buff2)
    {
        buff1 = (char *)buff1 + 1;
        buff2 = (char *)buff2 + 1;
    }

    return (*((unsigned char *)buff1) - *((unsigned char *)buff2));
}
  • 4、memmove:另一个用于从 src 复制 n 个字符到 dest 的函数
/*如果目标区域和源区域有重叠的话,memmove() 能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,
复制后源区域的内容会被更改。如果目标区域与源区域没有重叠,则和 memcpy() 函数功能相同*/
void *func_memmove(void *dst, const void *src, size_t cnt)
{
    void *ret = dst;

    if(dst <= src || (char *)dst >= (char *)src + cnt)
    {
        while(cnt--)
        {
            *(char *)dst = *(char *)src;
            dst = (char *)dst + 1;
            src = (char *)src + 1;
        }
    }
    else
    {
        /*地址存在重叠*/
        dst = (char *)dst + cnt - 1;
        src = (char *)src + cnt - 1;

        while(cnt--)
        {
            *(char *)dst = *(char *)src;
            dst = (char *)dst - 1;
            src = (char *)src - 1;
        }
    }

    return ret;
}
  • 5、strcat:把 src 所指向的字符串追加到 dest 所指向的字符串的结尾
char *func_strcat(void *dst, const char *src)
{
    void *cp = dst;

    while(*cp)
    {
        cp++;
    }

    while(*src)
    {
        *cp++ = *src++;
    }

    return dst;
}
  • 6、strchr:在string 所指向的字符串中搜索第一次出现字符 chr的位置
char *func_strchr(void *string, int chr)
{
    while(*string && *string != (char)chr)
    {
        string++;
    }

    return ((*string == (char)chr) ? (char *)string : NULL;
}
  • 7、strcpy:把 src 所指向的字符串复制到 dest
char *func_strcpy(char *dst, const char *src)
{
    char *cp = dst;

    while(*cp++ = *src++)
    {
        ;
    }

    return dst;
}
  • 8、strlen:计算字符串 string 的长度,直到空结束字符,但不包括空结束字符
size_t func_strlen(char *string)
{
    int length = 0;

    while(*string++ != '\0')
    {
        length++;
    }

    return length;
}
  • 9、strstr:在字符串 str1中查找第一次出现字符串 str2的位置
char *func_strstr(const char *str1, const char *str2)
{
    char *cp = str1;
    char *s1;
    char *s2;

    if(!*str2)
    {
        return str1;
    }

    while(*cp)
    {
        s1 = cp;
        s2 = str2;
        while(*s1 && *s2 && !(*s1 - *s2))
        {
            s1++;
            s2++;
        }

        if(!*s2)
        {
            return cp;
        }
        
        cp++;
    }

    return NULL;
}
  • 10、strtok:分解字符串 string,control为分隔符
char *func_strtok(char *string, const char *control)
{
    char *str;
    const char *ctrl = control;
    
    char map[32]; /*256个字符隐射到32个8bit的数组,一位可以代表一个字符*/
    int cnt;

    static char *nexttoken;

    for(cnt = 0; cnt < 32; cnt++)
    {
        map[cnt] = 0;
    }

    do /*间隔符存储到map数组,可以是多个间隔符*/
    {
        /* *ctrl>>3 表示map中8个一组,8个字符同时隐射在map中一个位置,如 A:65 B:66等都隐射在map[8]中*/
        /* *ctrl&7 表示取除8的余数,每一位代表一个字母,所以0x01左移对应的n位*/
        map[*ctrl >> 3] |= (0x01<<(*ctrl & 7));
    }while(*ctrl++);

    if(NULL != string)
    {
        str = string;
    }
    else
    {
        str = nexttoken; /*如果string=null,从上次分隔后的位置开始*/
    }

    while((map[*str >> 3] & (0x01 << (*str & 7))) && *str)
    {
        str++;
    }/*不是分隔符直接跳出循环*/

    string = str;

    while(*str)
    {
        if(map[*str >> 3] & (0x01 << (*str & 7)))
        {
            *str++ = '\0'; /*检测到是分隔符,直接替换为'\0'*/
            break;
        }
        
        str++;
    }

    nexttoken = str; /*保存指向分隔符后面的一个位置*/

    if(string == str)
    {
        return NULL; /*没有检索到,返回null*/
    }
    else
    {
        return string;
    }
}
  • 11、memccpy:从src所指内存区域复制n个字节到dest所指内存区域,遇到字符ch则停止复制
void *func_memccpy(void *dest, const void *src, int ch, unsigned int cnt)
{
    while(cnt && (*((char *)dest = (char *)dest + 1) - 1) = 
                        (*((char *)src = (char *)src + 1) - 1) != (char)ch )
    {
        cnt--;
    }

    /*while 中条件相当于
        if(src != ch)
        {
            dest = src;
            dest = dest + 1;
            src = src + 1;
        }

      为什么要-1,可以理解从dest首位置开始
    */

    return (cnt ? dest : NULL);
}

  • 12、memicmp:比较内存区域buf1和buf2的前n个字节,不区分大小写
int func_memicmp(const void *str1, const void *str2, unsigned int cnt)
{
    int string1;
    int string2;
    
    while(cnt--)
    {
        if((*(unsigned char *)str1 == *(unsigned char *)str2)
            || if((string1 = TOLOWER(*(unsigned char *)str1)) 
                    == (string2 = TOLOWER(*(unsigned char *)str2))))
        {
            str1 = (char *)str1 + 1;
            str2 = (char *)str2 + 1;
        }
        else
        {
            break;
        }
    }

    return string1 - string2;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值