作为 C 语言初学者,字符串处理和内存操作是核心重难点,今天我亲手模拟实现了 strlen / strcpy / strcat / strcmp / strncpy / strncat /strstr / memcpy / memmove 9 个经典库函数,从原理到代码逐点吃透,彻底搞懂指针操作与函数底层逻辑!

一、前言

C 语言标准库提供了大量字符串 / 内存操作函数,但知其然更要知其所以然。手动模拟实现这些函数,能深度理解指针运算、字符串结束规则、内存拷贝逻辑,同时规避新手常见 bug。

本文所有实现严格遵循标准库规范,包含边界判断、异常处理,可直接运行学习~


二、字符串操作函数实现

1. my_strlen(字符串长度计算)

核心功能:计算字符串有效字符长度,不包含\0

实现思路

  1. 断言判断指针合法性
  2. 两种经典实现:指针相减法 / 计数器法
  3. 遍历字符串直到\0,返回长度
#include<stdio.h>
#include<string.h>
#include<assert.h>

// 方法1:指针相减(效率更高)
size_t my_strlen(const char* str)
{
	assert(str);
	char* ret = (char*)str;
	while (*str)
	{
		str++;
	}
	return str - ret;
}

// 方法2:计数器法(更易理解)
size_t my_strlen(const char* str)
{
	assert(str);
	int count = 0;
	while (*str)
	{
		count++;
		str++;
	}
	return count;
}

2. my_strcpy(字符串拷贝)

核心功能:将源字符串完整拷贝到目标空间,包含\0

关键规范

  • 目标空间必须可修改、足够大
  • 源字符串必须以\0结尾
  • 拷贝会连带\0一起复制
char* my_strcpy(char* dest, const char* src)
{
	assert(dest && src);
	char* ret = dest;
	// 极简写法:拷贝字符+指针移动,遇到\0自动停止
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}

3. my_strcat(字符串追加)

核心功能:将源字符串追加到目标字符串末尾

实现步骤

  1. 找到目标字符串末尾的\0
  2. \0位置开始拷贝源字符串
  3. 自动追加结束符
char* my_strcat(char* dest, const char* src)
{
	assert(dest && src);
	char* ret = dest;
	// 找到dest末尾
	while (*dest)
	{
		dest++;
	}
	// 追加字符串
	while (*dest++ = *src++)
	{
		;
	}
	return ret;
}

4. my_strcmp(字符串比较)

核心功能:按 ASCII 值逐字符比较两个字符串

返回值规则

  • 相等 → 返回0
  • 前者大 → 返回大于 0的数
  • 后者大 → 返回小于 0的数
int my_strcmp(const char* dest, const char* src)
{
	assert(dest && src);
	// 字符相等则继续比较
	while (*dest == *src)
	{
		// 同时到达\0,说明完全相等
		if (*dest == '\0')
		{
			return 0;
		}
		dest++;
		src++;
	}
	// 返回ASCII差值
	return *dest - *src;
}

5. my_strncpy(有限长度字符串拷贝)

进阶功能:最多拷贝num个字符,不足则补\0

解决问题:避免 strcpy 无限制拷贝导致的越界风险

char* my_strncpy(char* dest, const char* src, size_t num)
{
	assert(dest && src);
	char* start = dest;
	// 拷贝有效字符
	for (int i = 0; i < num && *src != '\0'; i++)
	{
		*dest = *src;
		dest++;
		src++;
	}
	// 剩余空间补\0
	while (dest < start + num)
	{
		*dest = '\0';
		dest++;
	}
	return start;
}

6. my_strncat(有限长度字符串追加)

进阶功能:最多追加num个字符,手动添加结束符

安全可控:限制追加长度,防止缓冲区溢出

char* my_strncat(char* dest,const char* src, size_t num)
{
    assert(dest && src);
	char* start = dest;
	// 找到目标末尾
	while (*dest)
	{
		dest++;
	}
	size_t count = 0;
	// 有限追加
	while (*src != '\0' && count < num)
	{
		*dest = *src;
		dest++;
		src++;
		count++;
	}
	// 必须手动加结束符
	*dest = '\0';
	return start;
}

7. my_strstr(子串查找)

核心功能:在主串中查找子串首次出现位置

经典算法:BF 暴力匹配算法

char* my_strstr(const char* str1, const char* str2)
{
	// 空串直接返回原串
	if (*str2 == '\0')
	{
		return (char*)str1;
	}
	const char* p = str1;
	const char* s1 = NULL;
	const char* s2 = NULL;
	
	// 遍历主串
	while (*p)
	{
		s1 = p;
		s2 = str2;
		// 逐字符匹配
		while (*s1 && *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		// 子串匹配完成
		if (*s2 == '\0')
			return (char*)p;
		p++;
	}
	// 未找到
	return NULL;
}

三、内存操作函数实现

字符串函数仅适用于字符类型,memcpy / memmove可操作任意类型内存,是通用内存拷贝工具。

1. my_memcpy(基础内存拷贝)

核心功能:无类型限制内存拷贝,按字节拷贝

注意:不处理内存重叠场景

void* my_memcpy(void* dest, const void* src, size_t count)
{
    assert(dest && src);
	void* ret = dest;
	// 强转为char*,按字节拷贝
	while (count--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}

2. my_memmove(安全内存拷贝)

终极优化解决内存重叠问题,C 语言最标准的内存拷贝函数

核心逻辑

  • 目标地址 < 源地址 → 从前向后拷贝
  • 地址重叠 → 从后向前拷贝
int main()
{
	// 测试字符串函数
	char arr1[20] = "Hello World";
	char arr2[20] = { 0 };
	my_strcpy(arr2, arr1);
	printf("strcpy: %s\n", arr2);
	printf("strlen: %zu\n", my_strlen(arr1));

	// 测试内存函数
	int arr3[] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr3 + 2, arr3, 20);
	printf("memmove: ");
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr3[i]);
	}
	return 0;
}

四、核心知识点总结

1. 字符串函数共性

  • \0作为结束标志
  • 源字符串建议用const修饰,防止修改
  • 必须做指针非空断言assert

2. 内存函数核心

  • void*通用指针,适配所有数据类型
  • 强转char*实现按字节操作
  • memmove兼容所有拷贝场景,优先使用

3. 新手避坑指南

  1. ===混淆:判断相等必须用==
  2. 字符串忘加\0:导致输出乱码
  3. void * 不能直接运算:必须强转后操作
  4. 内存重叠:重叠场景必须用memmove

手动模拟库函数是 C 语言指针学习的最佳实践。从字符操作到内存操作,从基础函数到安全版本,每一行代码都在夯实底层基础。

这些函数是笔试、面试高频考点,吃透原理,无论做题还是工程开发都能游刃有余!

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐