库函数的模拟与实现

关于strstr strcmp memcpy memove的模拟实现

strstr

strstr的作用是返回字符子串在元字符中的位置

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

const char* Strstr(const char* str1, const char* str2) {
// 最简单粗暴的方式, 穷举/暴力枚举
assert(str1 != NULL && str2 != NULL);

if (*str2 == '\0') {
	// 此时说明 str2 是一个空字符串
	return NULL;
}

const char* black = str1;
while (*black != '\0') {
	const char* red = black;
	const char* sub = str2;
	while (*red != '\0' && *sub != '\0' && (*red == *sub)) {
		red++;
		sub++;
	}
	// 当上面的循环结束, 可能有三种情况:
	// 1. red 遇到 \0
	// 2. sub 遇到 \0
	// 3. *red 和 *sub 不相等
	if (*sub == '\0') {
		// 找到匹配的子串
		return black;
	}
	// 这个 if 和上面不能交换!!!
	// 此处的条件意味着 *sub != '\0' && *red == '\0'
	if (*red == '\0') {
		// 此时 str1 不可能包含 str2 了
		return NULL;
	}
	// 继续处理下次循环的匹配情况
	black++;
}
// 没有找到匹配的子串
return NULL;

}
int main()

{ char str1[] = “hello world world world”;
char str2[] = “world”;
char* ret = strstr(str1, str2);
printf("%p, %p\n", str1, ret);
}

strcmp

比较函数

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
int main() {
char str1[] = “hehe”;
char str2[] = “hehe”;
str1 > str2 => 大于 0 的整数
str1 < str2 => 小于 0 的整数
str1 == str2 => 0

 strcmp 被调用了两次
 一旦字符串非常大(几个G)
 这可能是个考点(改错题)
int ret = Strcmp(str1, str2);
if (ret < 0) {
	printf(" str1 < str2 \n");
} else if (ret > 0) {
	printf(" str1 > str2 \n");
} else {
	printf(" str1 == str2 \n");
}

int Strcmp(const char* str1, const char* str2) {
// 针对这个函数来说, 不太好用返回值来表示出错情况
assert(str1 != NULL && str2 != NULL);
// 依次比较两个字符串对应字符是否相等
while (*str1 != ‘\0’ && *str2 != ‘\0’) {
if (*str1 < *str2) {
return -1;
} else if (*str1 > *str2) {
return 1;
} else {
// 当前字符难分高下
// 继续再去比较下一个字符
str1++;
str2++;
}
}
// 看是哪个字符串先到达 \0 哪个字符串就更小
if (*str1 < *str2) {
return -1;
} else if (*str1 > *str2) {
return 1;
} else {
return 0;
}
}

memcpy

拷贝函数,此处拷贝的是内存

void* Memcpy(void* dest, const void* src, size_t num) {
assert(dest != NULL && src != NULL);
void* ret = dest;
for (size_t i = 0; i < num; i++) {
(char)dest = (char)src;// void * 不能解引用,必须强转成char*
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}

int main()
{

int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8};
int* p = arr + 2;
Memcpy(p, arr, 8);
for (int i = 0; i < 4; i++) {
	printf("%d\n", arr2[i]);
}

system("pause");
return 0;

}

memove

此函数和上面的有点相似,但是该函数考虑了内存重叠的情况

void* Memcpy(void* dest, const void* src, size_t num) {
assert(dest != NULL && src != NULL);
void* ret = dest;
for (size_t i = 0; i < num; i++) {
(char)dest = (char)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}

void* Memmove(void* dest, const void* src, size_t num) {
assert(dest != NULL && src != NULL);
// 先判定缓冲区内存是否重叠
char* cdest = (char*)dest;
char* csrc = (char*)src;
if (csrc < cdest && cdest < csrc + num) {
// 需要从后往前拷贝
char* pdest = cdest + num - 1; // 最后一个位置的字节
char* psrc = csrc + num - 1;
for (size_t i = 0; i < num; i++) {
*pdest = *psrc;
pdest–;
psrc–;
}
} else {
Memcpy(dest, src, num);
}
return dest;
}
int main()
{

int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8};
int* p = arr + 2;
Memove(p, arr, 8);
for (int i = 0; i < 4; i++) {
	printf("%d\n", arr2[i]);
}

system("pause");
return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值