C语言常用字符串函数模拟实现与原理详解
C语言中的字符串处理依赖于<string.h>头文件。本文将逐一解析strlen、strcat、strcpy、strcmp及strstr的核心逻辑,并提供从零开始的模拟实现代码,展示如何利用指针遍历与内存操作完成相同的任务。
strlen:计算字符串长度
strlen用于获取字符串的有效字符数量(不包含结尾的'\0')。其返回类型为size_t,属于无符号整型。
| 功能 | 计算字符串长度 |
| 头文件 | #include <string.h> |
| 原型 | size_t strlen( const char* str) |
| 返回值 | 字符串的长度(size_t类型) |
第1步:实现strlen模拟
目的:通过指针移动统计非'\0'字符个数。
操作:使用断言确保指针有效,循环递增计数直到遇到结束符。
// strlen 的模拟实现
#include<stdio.h>
#include<assert.h>
size_t my_strlen(const char* str)
{
assert(str);
int count = 0;
while (*str != '\0')
{
str++;
count++;
}
return count;
}
strcat:字符串追加
strcat将源字符串src拼接到目标字符串dest的末尾。拼接时,会覆盖dest原有的结束符'\0',并保留新字符串的结束符。要求dest空间必须足够容纳拼接后的内容。
| 功能 | 追加子字符串到目标字符串后 |
| 头文件 | #include <string.h> |
| 原型 | char* strcat(char* dest,const char* src) |
| 返回值 | 目标字符串的首地址 |
第1步:实现strcat模拟
注意:原代码中assert(str1, str2);写法有误(宏只取第一个值),正确做法应为assert(str1 && str2);。
入口:找到dest的尾部,然后复制src。
动作:先让dest指针移动到'\0'处,再将src内容逐个赋值给dest。
// strcat 模拟实现
#include<stdio.h>
#include<assert.h>
char* my_strcat(char* str1, const char *str2)
{
// 修正:两个指针都必须合法
assert(str1 && str2);
char* tmp = str1;
// 1. 找出str1中的 '\0'
while (*str1)
{
str1++;
}
// 2. 在str1上追加(包含复制 '\0')
while (*str1++ = *str2++)
{
;
}
return tmp;
}
int main()
{
char arr1[20] = "hello";
char arr2[] = " world";
printf("%s", my_strcat(arr1, arr2));
return 0;
}
strcpy:字符串拷贝
strcpy将源字符串完整地拷贝到目标地址。它会连同源字符串最后的'\0'一起拷贝过去。目标地址必须有足够的剩余空间,否则会发生缓冲区溢出。
| 功能 | 将参数src字符串拷贝至参数dest所指的地址 |
| 头文件 | #include <string.h> |
| 原型 | char* strcpy(char* dest,char* src) |
| 返回值 | 目标字符串的首地址 |
第1步:实现strcpy模拟
目的:逐字节拷贝源字符串到目标缓冲区。
风险:如果源串比目标数组长,会破坏栈内存。
// 模拟实现 strcpy
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char *str2, char *str1)
{
assert(str1 && str2);
char* tmp = str2;
// 拷贝直到遇见 '\0' 并完成最后一次拷贝
while (*str1)
{
*str2++ = *str1++;
}
*str2 = '\0'; // 显式添加结束符,确保健壮性
return tmp;
}
int main()
{
char arr1[20] = "abcdef";
char arr2[20] = "xxxxxxxxxxxxx";
my_strcpy(arr2, arr1);
printf("%s", arr2);
return 0;
}
strcmp:字符串比较
strcmp按字典序比较两个字符串。从左到右逐个比较字符的ASCII值,直到出现不同字符或遇到'\0'。
| 功能 | 比较两字符串的大小 |
| 头文件 | #include <string.h> |
| 原型 | int strcmp (const char* str1,const char* str2) |
| 返回值 |
str1 > str2:返回值 > 0 str1 < str2:返回值 < 0 str1 == str2:返回值 = 0 |
第1步:实现strcmp模拟
目的:找到第一个不同的字符并计算差值。
操作:循环判断相等,不等则返回*str1 - *str2。
// strcmp 模拟实现
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)
{
if (*str1 == '\0') return 0; // 同时结束表示相等
str1++;
str2++;
}
return *str1 - *str2;
}
int main()
{
char arr1[] = "abc";
char arr2[] = "abcd";
printf("%d", my_strcmp(arr1, arr2));
return 0;
}
strstr:查找子串
strstr用于在一个字符串中寻找另一个子字符串首次出现的位置。若未找到则返回NULL。
| 功能 | 在目标字符串中查找子字符串 |
| 头文件 | #include <string.h> |
| 原型 | char* strstr(const char* str, const char* substr) |
| 返回值 | 目标字符串中匹配的子串首地址,若无则返回NULL |
第1步:实现strstr模拟
目的:通过两层循环进行模式匹配。
操作:外层cur指向主串位置,内层s1、s2用于比对子串。
参数:需要处理子串为空的情况。
// 模拟实现 strstr 函数
#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* str, const char* substr)
{
assert(str && substr);
// 排除 substr 为空的情况
if (*substr == '\0')
{
return (char*)str;
}
const char* s1;
const char* s2;
const char* cur = str;
while (*cur)
{
s1 = cur;
s2 = substr;
// 逐字符比较
while (*s1 && *s2 && (*s1 == *s2))
{
s1++;
s2++;
}
// 如果子串已经走完,说明找到了
if (*s2 == '\0')
return (char*)cur;
cur++;
}
return NULL;
}
int main()
{
char arr1[] = "abbbcdef";
char arr2[] = "bbc";
printf("%s", my_strstr(arr1, arr2));
return 0;
}
以上就是C语言字符串函数的详细内容,更多关于C语言 字符串函数内容请搜索本站以前的文章或继续浏览下面的相关文章!本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













