C语言-重构string.c系统库函数(1)

简介: string.h里主要包含了C语言对字符串操作的相关函数,这篇文章就介绍几个比较常用的函数重新自己实现。

一、string.c里相关函数介绍

string.h里主要包含了C语言对字符串操作的相关函数,这篇文章就介绍几个比较常用的
函数重新自己实现。并且每个函数给出了2种以上的不同写法,全部采用指针方式;在学习C语言过程中,重写这些字符串处理函数可以快速提升、磨练自己的指针、数组、函数相关知识,对学习是非常有帮助的;在单片机、嵌入式开发中,也会经常需要自己实现这些函数,可能有些功能系统函数不能满足的情况下,都需要自己重新实现。

二、重写函数介绍

2.1 strcmp : 字符串比较

字符串比较函数,用来比较两个字符串是否相等,下面给出了4种写法,其中一个是strncmp函数。

int strcmp(const char *str1, const char *str2)
{
    const unsigned char *s1 = (const unsigned char *)str1;
    const unsigned char *s2 = (const unsigned char *)str2;
    int delta = 0;

    while (*s1 || *s2) {
        delta = *s2 - *s1;
        if (delta)
            return delta;
        s1++;
        s2++;
    }
    return 0;
}

int strncmp(const char *cs, const char *ct, size_t count)
{
    unsigned char c1, c2;
    while (count) {
        c1 = *cs++;
        c2 = *ct++;
        if (c1 != c2)
            return c1 < c2 ? -1 : 1;
        if (!c1)
            break;
        count--;
    }
    return 0;
}


int strcmp(const char *a, const char *b)
{
    while (*a || *b) {
        if (*a != *b)
            return 1;
        if (*a == 0 || *b == 0)
            return 1;
        a++;
        b++;
    }
    return 0;
}

int strcmp(const char *cs, const char *ct)
{
    unsigned char c1, c2;
    int res = 0;
    do {
        c1 = *cs++;
        c2 = *ct++;
        res = c1 - c2;
        if (res)
            break;
    } while (c1);
    return res;
}

2.2 strlen: 字符串长度介绍

strlen是计算字符串长度的函数,比较常用,代码也最简单,下面写了两种实现方法。

size_t strlen(const char *s)
{
    const char *sc = s;
    while (*sc != '\0')
        sc++;
    return sc - s;
}

size_t strlen(const char *s)
{
    const char *sc;
    for (sc = s; *sc != '\0'; ++sc)
    return sc - s;
}

size_t strnlen(const char *s, size_t count)
{
    const char *sc;
    for (sc = s; count-- && *sc != '\0'; ++sc)
    return sc - s;
}

2.3 strstr: 字符串查找

strstr字符串查找函数,用来查找指定的字符串在源字符串里是否存在,存在就返回地址。
这个就给出了一种写法。

char *strstr(const char *s1, const char *s2)
{
    size_t l1, l2;
    l2 = strlen(s2);
    if (!l2)
        return (char *)s1;
    l1 = strlen(s1);
    while (l1 >= l2) {
        l1--;
        if (!memcmp(s1, s2, l2))
            return (char *)s1;
        s1++;
    }
    return NULL;
}

2.4 memcmp : 内存比较

memcmp内存比较函数,用来比较两个内存地址里的数据是否相等,不局限于字符串,只要是合法内存都可以按字节比较。

int memcmp(const void *cs, const void *ct, size_t count)
{
    const unsigned char *su1 = cs, *su2 = ct, *end = su1 + count;
    int res = 0;
    while (su1 < end) {
        res = *su1++ - *su2++;
        if (res)
            break;
    }
    return res;
}


int memcmp(const void *cs, const void *ct, size_t count)
{
    const unsigned char *su1, *su2;
    int res = 0;
    for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
        if ((res = *su1 - *su2) != 0)
            break;
    return res;
}

2.5 strcpy :字符串拷贝

strcpy字符串拷贝函数,用来将目标字符串拷贝到指定的地址中。目标字符串必须是‘\0’结束。 这里写了2种函数,一个strcpy、一个strncpy。

char *strcpy(char *dest, const char *src)
{
    char *tmp = dest;
    while ((*dest++ = *src++) != '\0')
    return tmp;
}

char *strncpy(char *dest, const char *src, size_t count)
{
    char *tmp = dest;

    while (count) {
        if ((*tmp = *src) != 0)
            src++;
        tmp++;
        count--;
    }
    return dest;
}

size_t strlcpy(char *dest, const char *src, size_t size)
{
    size_t ret = strlen(src);

    if (size) {
        size_t len = (ret >= size) ? size - 1 : ret;
        memcpy(dest, src, len);
        dest[len] = '\0';
    }
    return ret;
}

2.6 内存拷贝: memcpy

内存拷贝函数,将目标内存数据拷贝导致指定内存位置,不局限于字符串。

void *memcpy(void *__dest, __const void *__src, size_t __n)
{
    int i = 0;
    unsigned char *d = (unsigned char *)__dest, *s = (unsigned char *)__src;
    for (i = __n >> 3; i > 0; i--) {
        *d++ = *s++;
        *d++ = *s++;
        *d++ = *s++;
        *d++ = *s++;
        *d++ = *s++;
        *d++ = *s++;
        *d++ = *s++;
        *d++ = *s++;
    }
    if (__n & 1 << 2) {
        *d++ = *s++;
        *d++ = *s++;
        *d++ = *s++;
        *d++ = *s++;
    }
    if (__n & 1 << 1) {
        *d++ = *s++;
        *d++ = *s++;
    }
    if (__n & 1)
        *d++ = *s++;
    return __dest;
}

void *memcpy(void *__dest, __const void *__src, size_t __n)
{
    int i;
    char *d = (char *)__dest, *s = (char *)__src;
    for (i = 0; i < __n; i++)
        d[i] = s[i];
    return __dest;
}

static inline void *memcpy(void *__dest, const void *__src, size_t __n)
{
    int i;
    const char *s = __src;
    char *d = __dest;
    for (i = 0; i < __n; i++)
        d[i] = s[i];
    return __dest;
}
目录
相关文章
|
2月前
|
存储 安全 数据管理
C语言之考勤模拟系统平台(千行代码)
C语言之考勤模拟系统平台(千行代码)
58 4
|
25天前
|
IDE 编译器 开发工具
【C语言】全面系统讲解 `#pragma` 指令:从基本用法到高级应用
在本文中,我们系统地讲解了常见的 `#pragma` 指令,包括其基本用法、编译器支持情况、示例代码以及与传统方法的对比。`#pragma` 指令是一个强大的工具,可以帮助开发者精细控制编译器的行为,优化代码性能,避免错误,并确保跨平台兼容性。然而,使用这些指令时需要特别注意编译器的支持情况,因为并非所有的 `#pragma` 指令都能在所有编译器中得到支持。
100 41
【C语言】全面系统讲解 `#pragma` 指令:从基本用法到高级应用
|
20天前
|
存储 编译器 C语言
【C语言】C语言的变量和声明系统性讲解
在C语言中,声明和定义是两个关键概念,分别用于告知编译器变量或函数的存在(声明)和实际创建及分配内存(定义)。声明可以多次出现,而定义只能有一次。声明通常位于头文件中,定义则在源文件中。通过合理组织头文件和源文件,可以提高代码的模块化和可维护性。示例包括全局变量、局部变量、函数、结构体、联合体、数组、字符串、枚举和指针的声明与定义。
46 12
|
29天前
|
存储 C语言 开发者
【C语言】字符串操作函数详解
这些字符串操作函数在C语言中提供了强大的功能,帮助开发者有效地处理字符串数据。通过对每个函数的详细讲解、示例代码和表格说明,可以更好地理解如何使用这些函数进行各种字符串操作。如果在实际编程中遇到特定的字符串处理需求,可以参考这些函数和示例,灵活运用。
58 10
|
29天前
|
存储 程序员 C语言
【C语言】文件操作函数详解
C语言提供了一组标准库函数来处理文件操作,这些函数定义在 `<stdio.h>` 头文件中。文件操作包括文件的打开、读写、关闭以及文件属性的查询等。以下是常用文件操作函数的详细讲解,包括函数原型、参数说明、返回值说明、示例代码和表格汇总。
47 9
|
29天前
|
存储 Unix Serverless
【C语言】常用函数汇总表
本文总结了C语言中常用的函数,涵盖输入/输出、字符串操作、内存管理、数学运算、时间处理、文件操作及布尔类型等多个方面。每类函数均以表格形式列出其功能和使用示例,便于快速查阅和学习。通过综合示例代码,展示了这些函数的实际应用,帮助读者更好地理解和掌握C语言的基本功能和标准库函数的使用方法。感谢阅读,希望对你有所帮助!
40 8
|
29天前
|
C语言 开发者
【C语言】数学函数详解
在C语言中,数学函数是由标准库 `math.h` 提供的。使用这些函数时,需要包含 `#include <math.h>` 头文件。以下是一些常用的数学函数的详细讲解,包括函数原型、参数说明、返回值说明以及示例代码和表格汇总。
48 6
|
29天前
|
存储 C语言
【C语言】输入/输出函数详解
在C语言中,输入/输出操作是通过标准库函数来实现的。这些函数分为两类:标准输入输出函数和文件输入输出函数。
221 6
|
29天前
|
存储 缓存 算法
【C语言】内存管理函数详细讲解
在C语言编程中,内存管理是至关重要的。动态内存分配函数允许程序在运行时请求和释放内存,这对于处理不确定大小的数据结构至关重要。以下是C语言内存管理函数的详细讲解,包括每个函数的功能、标准格式、示例代码、代码解释及其输出。
59 6
|
29天前
|
C语言 开发者
【C语言】断言函数 -《深入解析C语言调试利器 !》
断言(assert)是一种调试工具,用于在程序运行时检查某些条件是否成立。如果条件不成立,断言会触发错误,并通常会终止程序的执行。断言有助于在开发和测试阶段捕捉逻辑错误。
41 5