C语言核心库函数底层实现:qsort、strcpy、strcat与strcmp

月亮慢半拍
月亮慢半拍
发布时间:2026-10-13| 3人浏览过
原创

本文详细讲解如何利用C语言底层语法手动实现常用的标准库函数。涵盖基于回调函数的通用冒泡排序(qsort),以及涉及指针安全、内存拷贝与字符串比较的strcpy、strcat和strcmp源码解析与注意事项。

通用排序算法原理

C语言标准库中的 qsort 是一个泛型排序函数,其核心在于利用 void* 指针支持任意数据类型,并通过回调函数解决不同数据类型的比较问题。若需在不依赖标准库的情况下模拟实现,通常结合冒泡排序或快速排序的思想。

回调函数是指通过函数指针调用的函数。将比较逻辑以函数指针的形式传递给排序主函数,由主函数在特定条件下触发调用,从而实现逻辑与解耦。

第1步:设计通用的交换与比较接口

  • 目的:封装底层字节交换逻辑,并提供可定制的比较规则。
  • 入口:swap 函数负责按字节移动内存块,cmp 函数负责定义元素大小关系。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

// 交换两个大小为 size 字节的内存块
void swap(void* p1, void* p2, int n)
{
	for (int i = 0; i < n; ++i)
	{
		char tmp = *((char*)p1 + i);       // 强制转为 char* 逐字节操作
		*((char*)p1 + i) = *((char*)p2 + i);
		*((char*)p2 + i) = tmp;
	}
}

// 整数比较回调示例
int cmp(const void* elem1, const void* elem2)
{
	return (*((int*)elem1) - *((int*)elem2));
}

第2步:构建冒泡排序骨架

  • 参数:base(数组首地址)、count(元素个数)、size(单个元素大小)、cmp(比较函数)。
  • 动作:通过指针算术运算定位相邻元素 (char*)base + j * size,调用 cmp 判断是否需要调用 swap。
void Bubble(void* base, int count, int size, int(*cmp)(void*, void*))
{
	int i, j;
	for (i = 0; i < count - 1; i++)
	{
		for (j = 0; j < count - i - 1; j++)
		{
			// 比较相邻元素,大于则交换
			if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
				swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
		}
	}
}

第3步:验证执行结果

void PrintArray(int ar[], int n)
{
	for (int i = 0; i < n; i++)
		printf("%d ", ar[i]);
	printf("\n");
}

int main()
{
	int ar[10] = { 1, 3, 4, 6, 2, 7, 9, 8, 22, 11 };
	int sz = sizeof(ar) / sizeof(ar[0]);
	
	PrintArray(ar, sz);          // 输出原始序列
	Bubble(ar, sz, sizeof(ar[0]), cmp); // 执行排序
	PrintArray(ar, sz);          // 输出排序后序列
	return 0;
}

字符串拷贝函数 strcpy 的实现

strcpy 用于将源字符串复制到目标缓冲区。其关键在于正确处理字符串结束符 '\0' 以及确保内存的安全性。

第1步:明确实现约束与前置条件

  • 源字符串必须包含 '\0' 终止符,且该字符会被一并拷贝到目标空间。
  • 目标缓冲区的内存容量必须足够容纳源字符串的全部内容。
  • 目标内存必须是可写的(非 const)。

第2步:参数校验与指针保护

  • 动作:使用 assert 校验传入指针不为 NULL;使用临时指针 pDest 保存原始目标地址,以便最终返回起始位置。
#include<assert.h>
char* my_strcpy(char* strDestination, const char* strSource)
{
	assert(strDestination != NULL && strSource != NULL);
	
	char* pDest = strDestination;
	
	// 循环拷贝直到遇到源字符串结束符
	while (*strSource != '\0')
	{
		*pDest++ = *strSource++; // 先赋值,后指针自增
	}
	
	// 补上字符串结束符
	*pDest = '\0';
	return strDestination;
}

第3步:测试运行状态

int main()
{
	char str1[20] = "HelloABC";
	const char* str2 = "Linux"; // 建议作为 const 保护源字符串
	
	char* res = my_strcpy(str1, str2);
	// 此时 str1 内容变为 "Linux"
	printf("Result: %s\n", res);
	return 0;
}

字符串追加函数 strcat 的实现

strcat 用于将源字符串拼接到目标字符串末尾。实现时需先找到目标串的尾部,再进行覆盖拷贝。

第1步:寻找目标字符串末尾

  • 目的:确定新内容的写入起点。
  • 动作:遍历 strDestination 直到 *pDest == '\0'。

第2步:连续拷贝逻辑

char* my_strcat(char* strDestination, const char* strSource)
{
	assert(strDestination != NULL && strSource != NULL);
	char* pDest = strDestination;
	
	// 1. 移动指针至目标串尾部
	while (*pDest != '\0')
		pDest++;
	
	// 2. 将源串内容逐个拷贝至目标串后
	while (*strSource != '\0')
		*pDest++ = *strSource++;
	
	// 3. 添加新的结束符
	*pDest = '\0';
	return strDestination;
}

第3步:注意事项

务必保证 strDestination 有足够的剩余空间。如果空间不足会导致缓冲区溢出(Buffer Overflow)。测试时,如 str1[20] 初始化为 "Helloabc",追加 "Linux" 后应变为 "HelloabcLinux"。

字符串比较函数 strcmp 的实现

strcmp 按字典序逐字符比较两个字符串,根据 ASCII 码差值返回整数。

第1步:比较规则定义

  • 返回值 > 0:首个字符串大于第二个字符串。
  • 返回值 = 0:两个字符串相等。
  • 返回值 < 0:首个字符串小于第二个字符串。

第2步:指针同步递增比较

int my_strcmp(const char* string1, const char* string2)
{
	assert(string1 != NULL && string2 != NULL);
	int res = 0;
	
	// 同时遍历,只要字符相同或都为空即继续
	while (*string1 != '\0' || *string2 != '\0')
	{
		res = *string1 - *string2; // 计算 ASCII 差值
		if (res != 0)
			break;                 // 发现差异,跳出循环
		string1++;
		string2++;
	}
	
	// 规范化返回值为 1, 0 或 -1
	if (res > 0)
		res = 1;
	else if (res < 0)
		res = -1;
	
	return res;
}

第3步:验证案例

int main()
{
	const char* str1 = "Helloab";
	const char* str2 = "HelloABCab";
	
	int res = my_strcmp(str1, str2);
	// 因为 'b' > 'B' (ASCII), 结果为正数,处理后为 1
	printf("Comparison Result: %d\n", res);
	return 0;
}

以上就是C语言模拟实现qsort、strcpy、strcat和strcmp的详细内容,更多关于C语言基础函数原理的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。