C语言字符串函数与递归函数详解
一、字符串函数族字符串函数族是C语言标准库中用于处理字符串的一系列函数定义在string.h头文件中。这些函数提供了字符串复制、连接、比较、查找等基本操作是C语言编程中不可或缺的工具。1.1 strcpy - 字符串复制函数函数原型#include string.h char *strcpy(char *dest, const char *src);功能说明将源字符串src包括结束符\0复制到目标字符串dest目标缓冲区必须有足够的空间容纳源字符串如果源字符串和目标字符串内存重叠行为未定义参数说明char *dest目标字符串的首地址const char *src源字符串的首地址返回值目标字符串的首地址使用示例#include stdio.h #include string.h int main() { char source[20] Hello, World!; char destination[20]; // 复制字符串 strcpy(destination, source); printf(复制后的字符串: %s\n, destination); // 从指定位置开始复制 char str1[20] 1234567890; char str2[20] ABCD; strcpy(str1 3, str2 1); // 从str1[3]开始复制str2[1]之后的内容 printf(部分复制结果: %s\n, str1); // 输出: 123BCD7890 return 0; }注意事项必须确保目标缓冲区足够大否则会导致缓冲区溢出建议使用strncpy函数指定最大复制长度以提高安全性1.2 strlen - 字符串长度计算函数原型#include string.h size_t strlen(const char *s);功能说明计算字符串的实际长度不包括结束符\0从指定地址开始直到遇到第一个\0为止参数说明const char *s要计算长度的字符串首地址返回值字符串的实际长度size_t类型使用示例#include stdio.h #include string.h int main() { char str1[] Hello; char str2[] Programming; char str3[] ; printf(%s 的长度: %zu\n, str1, strlen(str1)); // 输出: 5 printf(%s 的长度: %zu\n, str2, strlen(str2)); // 输出: 11 printf(空字符串的长度: %zu\n, strlen(str3)); // 输出: 0 // 注意strlen计算的是实际字符数不包括\0 char str4[100] Test; printf(数组大小: %zu, 字符串长度: %zu\n, sizeof(str4), strlen(str4)); // 输出: 数组大小: 100, 字符串长度: 4 return 0; }重要特性时间复杂度为 O(n)需要遍历整个字符串如果字符串没有以\0结尾会导致未定义行为1.3 strcat - 字符串拼接函数原型#include string.h char *strcat(char *dest, const char *src);功能说明将源字符串src追加到目标字符串dest的末尾目标字符串必须有足够的空间容纳拼接后的结果源字符串的\0会被覆盖并在新字符串末尾添加新的\0参数说明char *dest目标字符串首地址const char *src源字符串首地址返回值目标字符串的首地址使用示例#include stdio.h #include string.h int main() { char str1[50] Hello, ; char str2[] World!; char str3[] Welcome to C Programming; // 基本拼接 strcat(str1, str2); printf(第一次拼接: %s\n, str1); // 输出: Hello, World! // 连续拼接 strcat(str1, str3); printf(第二次拼接: %s\n, str1); // 输出: Hello, World! Welcome to C Programming // 注意缓冲区大小 char buffer[20] Start; char append[] This is a very long string that might cause overflow; // 危险可能缓冲区溢出 // strcat(buffer, append); // 不安全的用法 return 0; }安全建议使用前确保目标缓冲区有足够空间考虑使用strncat函数指定最大追加长度计算目标缓冲区剩余空间sizeof(dest) - strlen(dest) - 11.4 strcmp - 字符串比较函数原型#include string.h int strcmp(const char *s1, const char *s2);功能说明按字典顺序比较两个字符串从第一个字符开始逐个比较ASCII码值遇到不相等的字符或遇到\0时停止比较参数说明const char *s1第一个要比较的字符串const char *s2第二个要比较的字符串返回值返回值含义说明 0s1 s2第一个不相等的字符在s1中的ASCII值较小 0s1 s2两个字符串完全相同 0s1 s2第一个不相等的字符在s1中的ASCII值较大使用示例#include stdio.h #include string.h int main() { char str1[] apple; char str2[] banana; char str3[] apple; char str4[] Apple; // 注意A的ASCII码(65)小于a(97) // 比较不同字符串 int result1 strcmp(str1, str2); printf(%s 与 %s 比较: %d\n, str1, str2, result1); // 输出负数 // 比较相同字符串 int result2 strcmp(str1, str3); printf(%s 与 %s 比较: %d\n, str1, str3, result2); // 输出0 // 大小写敏感比较 int result3 strcmp(str1, str4); printf(%s 与 %s 比较: %d\n, str1, str4, result3); // 输出正数 // 实际应用字符串排序或查找 char *fruits[] {banana, apple, cherry, date}; int n 4; // 简单比较示例 for(int i 0; i n; i) { for(int j i 1; j n; j) { if(strcmp(fruits[i], fruits[j]) 0) { printf(%s 在 %s 之后\n, fruits[i], fruits[j]); } } } return 0; }注意事项区分大小写A(65) 和a(97) 不同需要不区分大小写的比较时使用strcasecmpPOSIX标准或自行转换大小写1.5 strncmp - 限定长度字符串比较函数原型#include string.h int strncmp(const char *s1, const char *s2, size_t n);功能说明比较两个字符串的前n个字符只比较指定数量的字符即使字符串更长如果在前n个字符内遇到\0比较也会停止参数说明const char *s1第一个要比较的字符串const char *s2第二个要比较的字符串size_t n要比较的最大字符数返回值与strcmp相同但只基于前n个字符使用示例#include stdio.h #include string.h int main() { char str1[] HelloWorld; char str2[] HelloThere; char str3[] Hello; // 比较前5个字符 int result1 strncmp(str1, str2, 5); printf(比较前5个字符: %d (应为0因为都是Hello)\n, result1); // 比较前8个字符 int result2 strncmp(str1, str2, 8); printf(比较前8个字符: %d (应为正数W T)\n, result2); // 比较整个字符串 int result3 strncmp(str1, str3, 10); printf(比较10个字符: %d (应为正数str1更长)\n, result3); // 实际应用检查前缀 char filename[] document.txt; char prefix[] doc; if(strncmp(filename, prefix, strlen(prefix)) 0) { printf(文件 %s 以 %s 开头\n, filename, prefix); } return 0; }优势更安全可以避免比较过长的字符串更灵活可以只比较字符串的一部分性能更好当只需要比较前缀时二、递归函数递归是编程中一种重要的技术它通过函数调用自身来解决问题。递归可以将复杂问题分解为相似的子问题从而简化代码结构。2.1 递归函数概念什么是递归函数递归函数是指在函数体中直接或间接调用自身的函数。递归的核心思想是分而治之将一个大问题分解为规模更小的相似问题。递归的两个关键要素递归基Base Case最简单的情况可以直接得到结果不需要继续递归递归步骤Recursive Step将原问题分解为更小的相似问题并通过递归调用解决递归的两种形式直接递归函数直接调用自身int factorial(int n) { if (n 0) return 1; // 递归基 return n * factorial(n - 1); // 递归步骤 }间接递归函数A调用函数B函数B又调用函数A形成循环调用// 函数A调用函数B void functionA(int n) { if (n 0) return; printf(A: %d\n, n); functionB(n - 1); // 调用函数B } // 函数B调用函数A void functionB(int n) { if (n 0) return; printf(B: %d\n, n); functionA(n - 1); // 调用函数A }2.2 5的阶乘实例详解阶乘定义n! n × (n-1) × (n-2) × ... × 2 × 1其中0! 1递归实现#include stdio.h // 递归计算阶乘 int factorial(int n) { // 递归基0的阶乘是1 if (n 0) { return 1; } // 递归步骤n! n × (n-1)! else { return n * factorial(n - 1); } } int main() { int n 5; int result factorial(n); printf(%d的阶乘是: %d\n, n, result); // 输出: 5的阶乘是: 120 // 测试更多阶乘值 printf(0! %d\n, factorial(0)); // 输出: 0! 1 printf(1! %d\n, factorial(1)); // 输出: 1! 1 printf(3! %d\n, factorial(3)); // 输出: 3! 6 printf(7! %d\n,

相关新闻