Skip to content

Latest commit

 

History

History
422 lines (369 loc) · 11.1 KB

基础库函数的实现.md

File metadata and controls

422 lines (369 loc) · 11.1 KB

基础库函数的实现

函数目录

函数实现

#if USE_MY_FUN
    size_t strlen(const char *s) {
        assert(s != nullptr);
        size_t count = 0;
        while (*s++ != '\0') {
            ++count;
        }
        return count;
    }
#endif

    TEST(StdFun, strlen) {
        EXPECT_EQ(0, strlen(""));
        EXPECT_EQ(1, strlen("1"));
        EXPECT_EQ(9, strlen("123456789"));
    }
#if USE_MY_FUN
    char * strcpy(char *s1, const char *s2) {
        assert(s1 != nullptr && s2 != nullptr);
        char *s = s1;
        while ((*s++ = *s2++) != 0);
        return (s1);
    }
#endif

    TEST(StdFun, strcpy) {
        char dst[10] = "987654321";

        EXPECT_STREQ("123456789", strcpy(dst, "123456789"));
        EXPECT_STREQ("abcde", strcpy(dst, "abcde"));
        EXPECT_STREQ("", strcpy(dst, ""));
    }
#if USE_MY_FUN
    char *strncpy(char *s1, const char *s2, size_t n)
    {
        assert(s1 != nullptr && s2 != nullptr);
        char *s = s1;
        // 不能写成 while (n-- > 0 && *s2 != '\0')方式,因为当n = 0时会出现异常
        while (n > 0 && *s2 != '\0') {
            *s++ = *s2++;
            --n;
        }
        while (n-- > 0) {
            *s++ = '\0';
        }
        return (s1);
    }
#endif

    TEST(StdFun, strncpy) {
        char dst[10] = "";

        for (int i = 0; i < 10; ++i) dst[i] = 0;
        EXPECT_STREQ("123456789", strncpy(dst, "123456789", 10));
        for (int i = 0; i < 10; ++i) dst[i] = 0;
        EXPECT_STREQ("12345", strncpy(dst, "123456789", 5));
        for (int i = 0; i < 10; ++i) dst[i] = 0;
        EXPECT_STREQ("", strncpy(dst, "123456789", 0));
        for (int i = 0; i < 10; ++i) dst[i] = 0;
        EXPECT_STREQ("", strncpy(dst, "", 0));
        for (int i = 0; i < 10; ++i) dst[i] = 0;
        EXPECT_STREQ("", strncpy(dst, "", 1));
    }
#if USE_MY_FUN
    int strcmp(const char *s1, const char *s2) {
        assert(s1 != nullptr && s2 != nullptr);
        while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2) {
            ++s1;
            ++s2; // 必须放在循环体内,否则会出错
        }
        // 需要先转换为unsigned char类型之后才进行减运算
        return (*(unsigned char *)s1 - *(unsigned char *)s2);
    }
#endif

    TEST(StdFun, strcmp) {
        EXPECT_EQ(0, strcmp("", ""));
        EXPECT_EQ(0, strcmp("a", "a"));
        EXPECT_EQ(0, strcmp("abbbbb", "abbbbb"));
        EXPECT_EQ(5, strcmp("6", "1"));
        EXPECT_EQ(5, strcmp("1234567", "1234562"));
        EXPECT_EQ(-5, strcmp("1", "6"));
        EXPECT_EQ(-5, strcmp("1234562", "1234567"));
    }
#if USE_MY_FUN
    int strncmp(const char *s1, const char *s2, size_t n)
    {
        assert(s1 != nullptr && s2 != nullptr);
        while (n > 0 && *s1 != '\0' && *s2 != '\0' && *s1 == *s2) {
            ++s1;
            ++s2;
            --n;
        }
        // 注意n = 0的时候应该横返回0, 而且必须放在while的后边
        if (n == 0) return 0;
        return (*(unsigned char *)s1 - *(unsigned char *)s2);
    }
#endif

    TEST(StdFun, strncmp) {
        EXPECT_EQ(0, strncmp("", "", 0));
        EXPECT_EQ(0, strncmp("", "1", 0));
        EXPECT_EQ(0, strncmp("a", "a", 1));
        EXPECT_EQ(0, strncmp("a", "a", 2));
        EXPECT_EQ(0, strncmp("abbbbb", "abbbbb", 20));
        EXPECT_EQ(0, strncmp("abbbbb", "abbbbb", 5));
        EXPECT_EQ(5, strncmp("6", "1", 1));
        EXPECT_EQ(-5, strncmp("1", "6", 1));
        EXPECT_EQ(5, strncmp("1234567", "1234562", 10));
        EXPECT_EQ(-5, strncmp("1234562", "1234567", 10));
        EXPECT_EQ(0, strncmp("1234567", "1234562", 6));
    }
#if USE_MY_FUN
    char *strcat(char *dst, const char *src) {
        assert(dst != nullptr && src != nullptr);
        char *tmp = dst;
        while (*dst != '\0') {
            ++dst;
        }
        while ((*dst++ = *src++) != '\0');
        return tmp;
    }
#endif

    TEST(StdFun, strcat) {
        char dst[10] = "1234";
        EXPECT_STREQ("1234", strcat(dst, ""));
        EXPECT_STREQ("123456", strcat(dst, "56"));
        EXPECT_STREQ("123456789", strcat(dst, "789"));
    }
#if USE_MY_FUN
    // 注意声明中ch为int型的
    char *strchr(const char *str, int ch) {
        assert(str != nullptr);

        while (*str != '\0' && *str != ch) {
            ++str;
        }
        return (*str == '\0') ? nullptr :(char *)str;
    }
#endif

    TEST(StdFun, strchr) {
        EXPECT_TRUE(nullptr == strchr("", 0));
        EXPECT_TRUE(nullptr == strchr("123456789", 0));
        EXPECT_TRUE(nullptr == strchr("123456789", 'a'));
        EXPECT_EQ('1', *strchr("123456789", '1'));
        EXPECT_EQ('2', *strchr("123456789", '2'));
        EXPECT_EQ('8', *strchr("123456789", '8'));
        EXPECT_EQ('9', *strchr("123456789", '9'));
    }
#if USE_MY_FUN
    char *strstr(const char *str1, const char *str2) {
        assert(str1 != nullptr && str2 != nullptr);

        // 需要注意str2为“”和str1为“”的情况
        if (str2[0] == '\0') return (char *)str1;

        int n = 0;
        while (*str1 != '\0') {
            for (n = 0; *(str1 + n) == *(str2 + n); ++n) {
                if (*(str2 +n + 1) == '\0') {
                    return (char *)str1;
                }
            }
            ++str1;
        }
        return nullptr;
    }
#endif

    TEST(StdFun, strstr) {
        EXPECT_EQ('\0', *strstr("", ""));
        EXPECT_EQ('1', *strstr("1", ""));
        EXPECT_EQ('1', *strstr("123456", "12"));
        EXPECT_EQ('4', *strstr("123456", "456"));
        EXPECT_EQ('6', *strstr("123456", "6"));
    }
#if USE_MY_FUN
    int memcmp(const void *s1, const void *s2, size_t n) {
        assert(s1 != nullptr && s2 != nullptr);
        const unsigned char *_s1 = (unsigned char *)s1;
        const unsigned char *_s2 = (unsigned char *)s2;
        while (n > 0 && *_s1 == *_s2) {
            ++_s1;
            ++_s2;
            --n;
        }
        if (n == 0) return 0;
        return (*_s1 - *_s2);
    }
#endif

    TEST(StdFun, memcmp) {
        EXPECT_EQ(0, memcmp("", "", 0));
        EXPECT_EQ(0, memcmp("", "1", 0));
        EXPECT_EQ(0, memcmp("a", "a", 1));
        EXPECT_EQ(0, memcmp("a", "a", 2));
        EXPECT_EQ(0, memcmp("abbbbb", "abbbbb", 20));
        EXPECT_EQ(0, memcmp("abbbbb", "abbbbb", 5));
        EXPECT_EQ(5, memcmp("6", "1", 1));
        EXPECT_EQ(-5, memcmp("1", "6", 1));
        EXPECT_EQ(5, memcmp("1234567", "1234562", 10));
        EXPECT_EQ(-5, memcmp("1234562", "1234567", 10));
        EXPECT_EQ(0, memcmp("1234567", "1234562", 6));
    }
#if USE_MY_FUN
    void *memset(void *s, int c, size_t n) {
        assert(s != nullptr);
        unsigned char *ptr = (unsigned char *)s;
        while (n-- > 0) {
            *ptr++ = (unsigned char)c;
        }

        return (s);
    }
#endif
#if USE_MY_FUN
    void *memcpy(void *dst, const void *src, size_t n) {
        assert(dst != nullptr && src != nullptr);
        unsigned char *_dst = (unsigned char *)dst;
        const unsigned char *_src = (unsigned char *)src;
        while (n-- > 0) {
            *_dst++ = *_src++;
        }
        return (dst);
    }
#endif
#if USE_MY_FUN
    void *memmove(void *dst, const void *src, size_t n) {
        assert(dst != nullptr && src != nullptr);
        unsigned char *_dst = (unsigned char *)dst;
        const unsigned char *_src = (unsigned char *)src;
        if (dst < src){
            while (n-- > 0) {
                *_dst++ = *_src++;
            }
        } else if (dst > src) {
            _dst += n;
            _src += n;
            while (n-- > 0) {
                *(--_dst) = *(--_src);
            }
        }
        return (dst);
    }
#endif
#if USE_MY_FUN
    void *memchr(const void* src, int c, size_t n) {
        assert(src != nullptr);
        const unsigned char *_src = (unsigned char *)src;
        if (n > 0 && *_src != (unsigned char)c) {
            --n;
            ++_src;
        }
        return (void *)(n == 0 ? nullptr : _src);
    }
#endif
#if USE_MY_FUN
    void itoa(int i, char *a) {
        assert(a != nullptr);
        char *p = a;
        if (i < 0) {
            *p++ = '-';
            i = 0 - i;
        }

        int tmp = 1;
        while (i / tmp / 10 != 0) {
            tmp *= 10;
        }

        while (tmp != 0) {
            *p++ = i / tmp + '0';
            i %= tmp;
            tmp /= 10;
        }
        *p = '\0';
    }
#endif

    TEST(StdFun, itoa) {
        char a[100];

        itoa(0, a);
        EXPECT_STREQ("0", a);
        itoa(5, a);
        EXPECT_STREQ("5", a);
        itoa(123456, a);
        EXPECT_STREQ("123456", a);
        itoa(-123456, a);
        EXPECT_STREQ("-123456", a);
        itoa((int)0x7fffffff, a);
        EXPECT_STREQ("2147483647", a);
        itoa((int)0x80000001, a);
        EXPECT_STREQ("-2147483647", a);
    }
#if USE_MY_FUN
    int atoi(char *a) {
        bool isNegative = false;
        int result = 0;
        while (*a == ' ' || *a == '\t') {
            ++a;
        }

        if (*a == '-' || *a == '+') {
            isNegative = (*a++ == '-');
        }

        while (*a <= '9' && *a >= '0') {
            result *= 10;
            result += (*a++ - '0');
        }

        return (isNegative ? (0 - result) : result);
    }
#endif

    TEST(StdFun, atoi) {
        EXPECT_EQ(0, atoi("0"));
        EXPECT_EQ(5, atoi("5"));
        EXPECT_EQ(12345, atoi("12345"));
        EXPECT_EQ(-12345, atoi("-12345"));
        EXPECT_EQ(12345, atoi("  12345"));
        EXPECT_EQ(-12345, atoi("  -12345"));
        EXPECT_EQ((int)0x7fffffff, atoi("2147483647"));
        EXPECT_EQ((int)0x80000001, atoi("-2147483647"));
    }