字符串与内存库函数的模拟实现(新手)(C语言)

**运行通过编译器(VS2022) **

注意1:只有部分对除整形以外的类型乃至结构体做过测试

注意2:如果还有其他的字符串与内存操作函数,欢迎补充

注意3:因为本人不清楚专业命名,所以所有函数都以自己的理解代称

所用到的库函数以及宏:

#define _CRT_SECURE_NO_WARNING
#define cahr char

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

此处因为本人因输入习惯常将char打成cahr,所以专门定义了一个宏

*一、字节替换函数memset() *

void _cdecl my_memset(void* arr, cahr ch, size_t num)
{
	assert(arr);
	for (int i = 0; i < num; i++)
		*((char*)arr + i) = ch;
}

1、assert(arr)相当于assert(arr != NULL) (下面有类似用法)

2、选择使用for循环而非while循环的原因为vs2022如果使用++(char*)arr会报出“表达式必须是可修改的左值”错误,因此没有直接对地址进行操作(下面有类似问题)

其他版本的编译器可能没有类似问题。

*二、字节比较函数memcmp() *

int _cdecl my_memcmp(const void* dest, const void* src, size_t num)
{
	assert(dest && src);
	for (int i = 0; i < num; i++)
		if (*((char*)dest + i) > *((char*)src + i))
			return 1;
		else if (*((char*)dest + i) < *((char*)src + i))
			return -1;
		else;
	return 0;
}

循环提前结束代表不等,否则相等

*三、内存重叠拷贝函数memmove() *

void* _cdecl my_memmove(void* dest, const void* src, size_t num)
{
	assert(dest && src);
	void* ret = dest;
	if (dest < src)
	//从前向后拷贝
		for (int i = 0; i < num; i++)
			*((char*)dest + i) = *((char*)src + i);
	else
	//从后向前拷贝
		for (int i = num - 1; i >= 0; i--)
			*((char*)dest + i) = *((char*)src + i);
	return ret;
}

其实就是更具不同情况使用memcpy()函数,本质大差不离,多了一层if

*四、内存拷贝函数memcpy() *

void* _cdecl my_memcpy(void* dest, const void* src, size_t num)
{
	assert(dest && src);
	void* ret = dest;
	for (int i = 0; i < num; i++)
		*((char*)dest + i) = *((char*)src + i);
	return ret;
}

*五、是否被包含判断函数strstr() *

char* _cdecl my_strstr(const char* dest, const char* src)
//只是比较而不改变内容,所以用const增加常属性
{
	assert(dest && src);
	char* ret = (char*)dest;
  //如果src只有一个\0,则直接跳出函数减少运算
	if (!*src)
		return ret;
	else
		while (*dest++ != *src && *(dest - 1))
			;
  /*此处因为当*dest == *src && *dest == '\0'时,传出的dest多进行一次++,
  所以判断对应*dest时要-1,但为了后续判断又不能改变dest的值*/
	if (!(*--dest))//同上因为dest跳出循环时多进行一次++
		return ret;
	ret = (cahr*)dest;//已定义宏
	while (*dest++ == *src++ && *dest)
			;//*dest == '\0'时跳出循环,避免死循环
	if (!(*src)) return ret;
  //防止出现dest与src是交集的情况
	else return NULL;
}

if(*src)表示判断其是否为'\0',如果是\0则返回0

*六、字符串比较函数strcmp() *

int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 && str2);
	while (*str1++ == *str2++)
		if (!(*(str1 - 1) || *(str2 - 1)))
          //等价于!(*(str1 - 1)) && !(*(str2 - 1))
			return 0;
	if (*--str1 > *--str2) 
      //此处因为str1与str2跳出循环时多进行一次++,所以要--
      return 1;
	else 
      return -1;
}

此处用到的逻辑运算: (!A && !B) == !!(!A && !B) == !(!!A || !!B) == !(A || B)

*七、字符串复制函数strcpy() *

char* my_strcpy(char* dest, const char* src)
{
	assert(dest);
	assert(src);
	char* ret = dest;
	while (*dest++ = *src++);
	return ret;
}

*八、字符串追加函数strcat() *

char* my_strcat(char* dest, const char* src)
{
	assert(dest != NULL);
	assert(src);
	//二者语法等价
	char* ret = dest;
	while (*dest++);
	dest--;
	while (*dest++ = *src++);
	return ret;
}

*九、字符串分段函数strtok() *

尚在钻研

**其他问题: **

1、#define _CRT_SECURE_NO_WARNINGS

这是因为在vs2022中一些原本C语言的函数例如scanf()会被任务存在风险,在最开始加人该语句使得程序得以运行,当然,如果不加这句话也可以运行,可以使用自带的函数,例如scanf_s(),这种写法可以保证在该编译器中得以无风险运行,但是相同代码无法保证在其他编译器中运行。

另外,不止vs2022,其他的编译器可能也存在相关问题。

2、assert()

因为无法完全保证代码的正确性,所以加入断言函数防止传入空指针

3、_cdecl

因本人最近在研究该调用,所以部分函数用到该关键词,实际上该关键词即使不输入也默认是该类型,就像是auto一样,省略时默认该类型

4、size_t 库函数中将unsighed int类型重命名为size_t

5、对void类型的强制类型转换 因为void类型算是无类型指针,所以要先转换为字节大小为1的char*类型以方便操作

缺陷

1、部分代码尤其是strstr()函数过于繁杂,远远没有达到库函数应有的标准

2、注释多处可能存在不合理,例如strstr()函数就十分影响阅读,而且,很多函数可能也缺乏注释

3、调试不充分,只有小部分函数对包括结构体变量进行过测试

#C语言##库函数##初学者#
全部评论

相关推荐

01-05 09:14
同济大学 Java
心碎一号线:我要是9✌🏻我就选保研,保研了大四再找实习,实习之后,如果觉得自己不适合互联网工作模式,还能有其他选择,如果实习后决定了走互联网,也能提升学历提高竞争力
点赞 评论 收藏
分享
2025-12-25 10:16
已编辑
合肥工业大学 后端工程师
如题,在历经了长达多月的焦急等待,楼主也算是如愿以偿收到了梦中情司的意向了,秋招也终于是落下了帷幕,虽然手中的offer不够打牌,但已经满足了。华为时间线:9.3&nbsp;笔试环节,惊险通过10.15&nbsp;线下面试,前两轮技术面手撕都比较轻松,面试官态度也很好,最后一轮主管面,向主管表达了强烈的意愿,主管很和蔼,面试体验非常棒,1125定律后入池成功11.19&nbsp;收到接口人的保温电话12.9&nbsp;接到部门hr的保温电话,介绍了一下部门负责的工作12.23&nbsp;收到华为的意向书,成为华孝子一枚~期间收到了之前实习过的公司的offer,害怕华子泡不出来就先签三方了,这下不得不毁约了,在此向前司道个歉,也感谢前司对我的认可和托举,祝业务蒸蒸日上~感谢从今年三月开始找暑期实习以来,所有朋友和家人的鼓励,我们宿舍的就业氛围相当好,大家会分享各种有用的信息以及面试中遇到刁钻的面试题,在有人收到offer的时候我们都会发自内心的高兴和祝福,在我去线下面的时候也借我穿过西服.....能在大学四年分入这么好的宿舍拥有这么这么好的舍友除了幸运我找不出其他的形容词。还要感谢我的父母,在我每一次面试前都给予鼓励,也在失败的时候安慰我,他们的托底是我前进的基石,以后有工资了要给父母买很多东西最感谢的是我的女朋友,我们从大一相识,一直坚持到大四,她是一个非常优秀也异常坚定的女生,也正是因为她的实力出众早再年初就定好了要去上海的一家外企。我为了也去上海,从暑期实习开始投了不少上海的岗位但无一例外的都被拒之门外,但这期间她从来没有嫌弃过我,反而一直鼓励我相信我,如果说父母的托底是我前进的基石,那女朋友的鼓励和信任则是我前进的动力和方向。在如今这个充满戾气和对立的社会,能找到一个一心一意彼此喜欢的人实在是很难得,我深知这种珍贵所以更会加倍珍惜也感谢自己吧,在经历了无数个失眠的夜晚和面试失败的打击下,最终还是迎来了最好的结果,记得在华为线下面的前几周我几乎回到了高三时期的作息,那真是一段充实美好的时光,好在最后的结果也没有辜负这份努力也想跟所有的牛友说:不要因为一时的失败而自怨自艾,妄自菲薄,只要坚持下去,总会有柳暗花明又一村的惊喜在等待着你,机会总是垂青于有准备的人,要相信否极泰来,相信自己。朋友,坚定地相信未来吧,相信不屈不挠的努力,相信战胜死亡的年轻,相信未来、热爱生命。
小肥罗:有这样的女朋友真是幸福
秋招白月光
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务