仿写字符串函数
作为指针的练习,这里我们自己实现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模式下运行程序时,程序将会中断,即触发了断言。

mystrcpy
接下来是仿strcpy函数,这里有三个注意的地方
- 函数返回char*,这样可以直接将拷贝的结果传递给其它函数,如:printf("%s", mystrcpy(a, b));
- 类似的拷贝函数遵循“目标在前源在后”的规则 ,即数据源在后,被拷贝目标在前。
- 我们要将源src的内容拷贝到目标dst,因此dst是可修改的,不能追加const修饰符。
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;
}

陕公网安备61011202001108号