1.计算字符串的长度,不要用内置函数
如果你想手动计算一个字符串的长度(即字符数组中从开头到第一个 '\0' 的字节数),可以不使用 strlen,自己写一个循环。
基础实现(按字节)
c
int my_strlen(const char* str) {
int len = 0;
while (str[len] != '\0') {
len++;
}
return len;
}
使用示例
c
#include <stdio.h>
int my_strlen(const char* str) {
int len = 0;
while (str[len] != '\0') {
len++;
}
return len;
}
int main() {
const char* s = "Hello, world!";
int length = my_strlen(s);
printf("Length: %d\n", length); // 输出 13
return 0;
}
const 是 C 语言的关键字,表示"常量"或"只读"。用在指针声明中,如 const char* src,表示指针 src 指向的字符数据是不可修改 的(即通过 src 不能改变字符串的内容)。这样做有两个作用:
-
保护数据:防止函数内部意外修改源字符串。
-
提高代码安全性:让调用者知道该函数不会改变传入的字符串。
说明
-
函数参数
const char* str指向字符串。 -
循环条件
str[len] != '\0'判断当前字符是否为结束符。 -
每次循环
len++计数,直到遇到'\0'为止。 -
返回的
len即为字符串的字节长度(不包括结尾的'\0')。
如果字符串中包含多字节字符(如中文),这个函数返回的是字节数 ,而不是字符数。如果你需要统计实际的字符个数(而非字节数),则需要根据编码规则(如 UTF-8)逐个解析字符,但通常简单的 strlen 替代品只需统计字节数即可。
如果你不希望使用任何标准库函数,以上实现完全依赖指针运算和循环,满足要求。
2.C语言字符串的拼接,不要用内置函数
在 C 语言中,实现字符串拼接(连接)且不使用任何标准库函数(如 strlen、strcat、strcpy 等),需要手动定位目标字符串的结尾,然后将源字符串的字符逐个复制过去。
以下是一个完整的示例,包含详细注释:
c
#include <stdio.h> // 仅用于输出,拼接过程未使用任何库函数
// 自定义拼接函数:将 src 拼接到 dest 的末尾
// 注意:dest 必须拥有足够的空间容纳拼接后的字符串(包括 '\0')
void my_strcat(char *dest, const char *src) {
// 1. 移动 dest 指针到其末尾(即 '\0' 的位置)
while (*dest != '\0') {
dest++; // 逐个字符前进,直到遇到空字符
}
// 2. 将 src 中的字符逐个复制到 dest 的末尾
while (*src != '\0') {
*dest = *src; // 复制当前字符
dest++; // 目标指针后移
src++; // 源指针后移
}
// 3. 在新字符串末尾添加结束符 '\0'
*dest = '\0';
}
int main() {
char buffer[50] = "Hello, "; // 预留足够空间
const char *suffix = "world!";
my_strcat(buffer, suffix);
printf("拼接结果:%s\n", buffer); // 输出:Hello, world!
return 0;
}
关键点说明
-
查找末尾 :通过循环
while (*dest != '\0') dest++;找到目标字符串的结束位置,此时dest指向'\0'。 -
字符复制:然后循环复制源字符串的每个非空字符,同时移动两个指针。
-
添加结束符 :复制完成后,手动在目标字符串末尾添加
'\0',确保其符合 C 字符串规范。 -
安全性 :调用者必须确保
dest指向的数组有足够空间容纳原有内容加上src的内容及末尾的'\0'。若空间不足,会导致缓冲区溢出。#include<stdio.h>
void my_strcat(char* dest,const char* src){
while(*dest!='\0'){
dest++;
}
while(*src!='\0'){
*dest=*src;
dest++;
src++;
}
*dest='\0';}
int main(){
char arr[50]="hello";
char* str="miaomiao";
my_strcat(arr,str);
printf("%s\n",arr);
return 0;
}
3.C语言字符串的查找,不要用内置函数
在 C 语言中实现字符串查找(例如查找子串第一次出现的位置),不使用任何标准库函数(如 strstr、strlen 等),需要手动遍历主串和子串进行匹配。下面提供一个朴素的实现方式,返回子串在主串中第一次出现的指针,若未找到则返回 NULL。c
#include <stdio.h> // 仅用于输出演示,查找过程未使用库函数
// 自定义查找函数:在 haystack 中查找 needle 第一次出现的位置
// 返回指向 haystack 中 needle 首字符的指针,如果未找到则返回 NULL
char* my_strstr(const char *haystack, const char *needle) {
// 如果 needle 为空字符串,根据标准 strstr 行为返回 haystack
if (*needle == '\0') {
return (char*)haystack;
}
const char *h = haystack; // 主串指针
const char *n; // 子串指针(内层循环用)
// 外层循环:遍历主串的每个字符作为可能的起点
while (*h != '\0') {
// 检查从 h 开始的字符串是否与 needle 匹配
n = needle;
const char *start = h; // 记录当前起点
while (*n != '\0' && *start != '\0' && *start == *n) {
start++;
n++;
}
// 如果 n 已经到达子串末尾,说明完全匹配
if (*n == '\0') {
return (char*)h; // 返回第一次出现的位置
}
// 否则,主串指针后移一个字符,继续检查
h++;
}
// 未找到匹配
return NULL;
}
int main() {
char text[] = "Hello, world! Welcome to C programming.";
char pattern[] = "world";
char *result = my_strstr(text, pattern);
if (result != NULL) {
printf("找到子串 \"%s\",起始位置:%ld\n", pattern, result - text);
printf("从该位置开始的剩余字符串:%s\n", result);
} else {
printf("未找到子串 \"%s\"\n", pattern);
}
return 0;
}
代码说明
边界处理:如果 needle 是空字符串,直接返回 haystack(模仿标准 strstr 行为)。
外层循环:用指针 h 遍历主串的每个字符,将其作为可能匹配的起点。
内层匹配:用指针 start 和 n 逐字符比较主串和子串,直到遇到不匹配或某一方结束。
匹配成功:如果内层循环结束后 n 指向了子串的结束符 '\0',说明完全匹配,返回当前的 h(起点)。
未匹配:若内层循环因不匹配而退出,则 h 后移一位继续尝试;若主串遍历完毕仍未找到,返回 NULL。
关键点
没有使用任何库函数(如 strlen、strcmp、strstr 等),仅用指针和循环完成。
时间复杂度为 O(n*m)(n 为主串长度,m 为子串长度),适用于一般场景。
如果需要更高性能,可考虑 KMP 等算法,但朴素方法清晰易懂,满足"不使用内置函数"的要求。
注意事项
函数返回的指针指向主串内部的某个位置,因此主串必须是可修改的(此处用 const char* 传入,但返回 char* 可能存在风险;若希望更安全,可以返回下标或使用非 const 版本)。实际使用时,若主串为常量字符串,不应通过返回的指针修改内容。
代码中使用了 printf 进行演示,这属于标准输入输出库,但查找逻辑本身不依赖任何字符串处理内置函数。
