仿写字符串函数

作为指针的练习,这里我们自己实现C语言字符串库函数的简化版本,不过,对于实际的开发,我们要优先使用库函数。

mystrlen

首先,我们实现字符串长度获取函数:

int mystrlen(const char *str)
{
    // 断言传递的指针肯定不是NULL
    assert(str != NULL);

    int len = 0;

    // 当前字符串不是结束符'\0'时成立
    while (*str)
    {
        len++;  // 长度+1
        str++;  // 指针+1,指向下一个字符
    }

    return len;
}

这里有几个需要说明的地方:

const关键字: const指示str的内容不能在函数内被修改,即字符串是只读的;对于不在函数内部修改的数据,加上const可以更清晰的表述我们的意图。

assert宏: 使用assert宏,可以断言宏内的表达式肯定成立;assert仅在Debug模式下有效,方便我们在开发阶段尽早发现问题。

我们使用assert(str != NULL)保证调用mystrlen时,传递的指针不能为空;否则在Debug模式下运行程序时,程序将会中断,即触发了断言。

glimix.com

mystrcpy

接下来是仿strcpy函数,这里有三个注意的地方

char* mystrcpy(char *dst, const char *src)
{
    assert(dst != NULL);
    assert(src != NULL);

    // 因为要保证返回的指针指向字符串的开头,所以使用tmp创建dst的拷贝
    char *head = dst;

    // 未到达字符串结束符时成立
    while (*src != '\0')
    {
        *dst = *src;    // 执行拷贝操作,将src的内容拷贝到tmp中
        dst++;          // 移动目标指针指向下次的拷贝位置
        src++;          // 移动源指针指向下个被拷贝字符
    }

    *tmp = '\0';        // 添加字符串结束标记

    return head;
}

mystrcmp

最后是字符串比较函数,函数内部不会修改指针的内容,所以两个参数都以const修饰;这里我们使用一条assert语句,保证两个条件都必须成立。

int mystrcmp(const char *str1, const char *str2)
{
    assert(str1 != NULL && str2 != NULL);

    // 在任何一个字符串未结束前,比较字符串相等的部分
    while (*str1 == *str2 && (*str1 || *str2))
    {
        str1++;
        str2++;
    }

    // 此时,要么两个字符串相等;要么就是碰到第一个不相等的字符。
    // 相减得到两个字符的差值
    int result = *str1 - *str2;

    // 当结果大于0时返回1;否则;当结果小于0时返回-1,相等时返回0。
    return (result > 0 ? 1 : (result < 0 ? -1 : 0));
}

最后编写main()函数,将所有这些驱动起来。

int main()
{
    char text[] = "hello";
    //printf("%d\n", mystrlen(NULL));
    printf("%d\n", mystrlen(text));
    printf("%d\n", mystrlen("glimix.com"));

    char message[64];
    printf("%s\n", mystrcpy(message, "glimix.com - C tutorials"));
    printf("%s\n", mystrcpy(message, text));

    printf("%d\n", mystrcmp("ab", "ab"));
    printf("%d\n", mystrcmp("aB", "ab"));
    printf("%d\n", mystrcmp("ab", "Ab"));

    return 0;
}

glimix.com

陕ICP备2025078817号-1 陕公网安备61011202001108号