C语言常用字符串库函数实现解析
本文将深入探讨C语言标准字符串库函数的底层实现机制,通过自定义my_strlen、my_strcpy、my_strcat及my_strcmp等函数的代码示例,解析内存拷贝、指针移动及空字符\0的处理细节,确保在掌握原型的同时提升代码安全性。
计算字符串长度 strlen
strlen函数用于计算给定字符串的有效字符个数,其计数过程会一直进行直到遇到结束符\0。在使用该函数时,需要注意传入的必须是有效的字符串首地址。
函数原型
size_t strlen ( const char * str );
下面是一个基础的自定义实现:
int my_strlen(char *str)
{
char* ch=str;
int count=0;
while(*ch!='\0')
{
count++;
ch++;
}
return count;
}
考虑到安全性,因为求长度的操作不会改变源字符串的内容,因此应当使用const关键字修饰输入指针,防止内部意外修改原数据。同时,由于只需要修改指针指向而非内容,我们可以用一个非const的临时指针来遍历:
int my_strlen(const char *str)
{
const char* ch=str;
int count=0;
while(*ch!='\0')
{
count++;
ch++;
}
return count;
}
字符串复制 strcpy
strcpy的功能是将源字符串(包含末尾的\0)整体拷贝到目标字符串缓冲区中。如果目标空间不足会导致严重的内存溢出错误,调用者需自行保证容量。
函数原型
char * strcpy ( char * destination, const char * source );
自定义实现:
void my_strcpy(char* dest,const char *src)
{
const char * srcCopy = src; // 备份源指针以便返回
while(*srcCopy!='\0')
{
*dest=*srcCopy;
dest++;
srcCopy++;
}
*dest='\0'; // 必须手动补上结束符
}
如上所述,这里同样对源指针加上了const修饰。需要注意的是,循环结束时必须显式给目的字符串末尾添加'\0',否则输出的结果将是乱码或不完整的字符串。
字符串拼接 strcat
strcat用于将源字符串追加到目标字符串的末尾。实现的关键在于先找到目标字符串的结尾,然后再开始合并。
函数原型
char * strcat ( char * destination, const char * source );
自定义实现:
void my_strcat(char* dest,const char *src)
{
char * ch=dest;
// 第一步:移动到dest字符串的末尾
while(*ch!='\0')
ch++;
// 第二步:将src的内容逐个赋值给dest
while(*src!='\0')
{
*ch=*src;
ch++;
src++;
}
*ch='\0'; // 拼接完成后,依然要补上结束符
}
操作逻辑是先通过循环遍历找到目的字符串的结束位置,随后再将原字符串所指的值一一赋给目的字符串后续的内存位置。重要前提是:目的字符串在内存分配时必须预留足够的空间,否则追加操作会造成越界破坏。
字符串比较 strcmp
strcmp按字典序逐个字符比较两个字符串的大小,直到发现不相等的字符或字符串结束。比较的是字符的ASCII值。
函数原型
int strcmp ( const char * str1, const char * str2 );
一个严谨的实现应当包含指针合法性检查:
#include <assert.h>
int my_strcmp(const char* str1,const char *str2)
{
assert(str1 != NULL); // 断言防止空指针崩溃
assert(str2 != NULL);
while(*str1 == *str2)
{
if(*str1 == '\0') // 两者都到达末尾
{
return 0; // 相等
}
str1++;
str2++;
}
// 退出循环说明发现不等字符
// 若 str1 > str2 返回正数,否则负数
return (*str1 - *str2);
}
上述代码的逻辑是:只要两个字符相等就继续向后移动;如果不相等且不为\0,则直接根据当前字符的差值返回结果。这种简化写法比单独的`if-else`判断更符合标准库的行为。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









