字符串与内存库函数的模拟实现(新手)(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语言##库函数##初学者#
全部评论

相关推荐

06-27 12:54
已编辑
门头沟学院 Java
累了,讲讲我的大学经历吧,目前在家待业。我是一个二本院校软件工程专业。最开始选专业是觉得计算机感兴趣,所以选择了他。本人学习计算机是从大二暑假结束开始的,也就是大三开始。当时每天学习,我个人认为Java以及是我生活的一部分了,就这样持续学习了一年半,来到了大四上学期末,大概是在12月中旬,我终于找的到了一家上海中厂的实习,但我发现实习生的工作很枯燥,公司分配的活也不多,大多时间也是自己在自学。就这样我秋招末才找到实习。时间来到了3月中旬,公司说我可以转正,但是转正工资只有7000,不过很稳定,不加班,双休,因为要回学校参加答辩了,同时当时也是心高气傲,认为可以找到更好的,所以放弃了转正机会,回学校准备论文。准备论文期间就也没有投递简历。然后时间来到了5月中旬,这时春招基本也结束了,然后我开始投递简历,期间只是约到了几家下场面试。工资也只有6-7k,到现在我不知道该怎么办了。已经没有当初学习的心劲了,好累呀,但是又不知道该干什么去。在家就是打游戏,boss简历投一投。每天日重一次。26秋招都说是针对26届的人,25怎么办。我好绝望。要不要参加考公、考研、央国企这些的。有没有大佬可以帮帮我。为什么感觉别人找工作都是顺其自然的事情,我感觉自己每一步都在艰难追赶。八股文背了又忘背了又忘,我每次都花很长时间去理解他,可是现在感觉八股、项目都忘完了。真的已经没有力气再去学习了。图片是我的简历,有没有大哥可以指正一下,或者说我应该走哪条路,有点不想在找工作了。
码客明:太累了就休息一下兄弟,人生不会完蛋的
如果实习可以转正,你会不...
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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