• 【C语言】-字符串函数和内存函数(下)



    前言

    1、strcmp函数

    1.1、strcmp函数介绍

    笔者从cplusplus.com找到关于strcmp函数的文档。
    在这里插入图片描述
    接收:两个字符串指针

    返回:整型

    作用:比较两个字符串的大小,它会根据你传进去的两个指针,同步向后偏移,一直偏移到两个字符串相同位置上的ASCII码值不同时,返回对应value。(value<0时 str1str2)
    在这里插入图片描述
    容易导致的误区:
    这个函数比较的不是两个字符串的长度。返回的value与长度无关,只与对应位置上的ASCII码值有关。

    1.2、strcmp函数的模拟实现

    我们通过对strcmp函数的模拟实现加深对strcmp函数的理解。

    //strcmp函数的模拟实现
    #include
    
    int my_strcmp(char* str1, char* str2)
    {
    	assert(str1!=NULL);
    	assert(str2!=NULL);
    	while (*str1 == *str2 &*str1!=0)
    	{
    		str1++;
    		str2++;
    	}
    	return *str1 - *str2;
    }
    int main()
    {
    	char arr1[] = "abcdefg";
    	char arr2[] = "abcg";
    	int ret = my_strcmp(arr1, arr2);
    	if (ret < 0)
    	{
    		printf("数组arr1里的字符<数组arr2里的字符");
    	}
    	else if(ret = 0)
    	{
    		printf("数组arr1里的字符=数组arr2里的字符");
    	}
    	else
    	{
    		printf("数组arr1里的字符>数组arr2里的字符");
    
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    在这里插入图片描述
    这里的模拟代码仅供参考,如果这段代码有错误或者有比这段更好的方法欢迎指出!

    1、memcpy

    1.1、memcpy介绍

    笔者从cplusplus网站找到的关于memcpy的介绍
    在这里插入图片描述
    接收:要copy的目的指针,源指针,要copy的长度

    返回:copy后的目的指针。

    作用:函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。

    需要注意的几个细节:
    1.函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
    2.这个函数在遇到 ‘\0’ 的时候并不会停下来。
    3.如果source和destination有任何的重叠,复制的结果都是未定义的。

    关于第三点:当这两个指针的前后有重叠时,这个函数就会出问题。
    在这里插入图片描述

    2.2memcpy的模拟实现

    #include
    #include
    void* my_memcpy(void* dst, void* src, int num)
    {
    	void* ret = dst;
    	assert(dst != NULL);
    	assert(src != NULL);
    	while (num--)
    	{
    		*(char*)dst = *(char*)src;
    		dst = (char*)dst + 1;
    		src = (char*)src + 1;
    	}
    	return ret;
    }
    int main()
    {
    	char arr1[] = "abcdefg";
    	char arr2[] = { 0 };
    	printf("%s",(char*)my_memcpy(arr2, arr1, 4));
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    运行结果:
    在这里插入图片描述

    笔者希望通过这个运行结果强调,这个函数只是机械得将你需要拷贝的内容拷贝到目标函数里,并不会像strcpy函数一样为目标函数后面自动添加’\0’.
    而我们知道printf以%s形式打印时,不停向后打印,知道遇到’\0’。故我们除了打印除abcd外,还会打印出一堆乱码。

    3、memmove函数

    3.1memmove函数介绍

    笔者从cplusplus网站查询到memmove函数的官方定义
    在这里插入图片描述
    接收:需要拷贝内容的目标指针,源指针,需要拷贝的长度(单位字节)

    返回:返回目标指针

    作用:拷贝源指针指向的长度为num字节的内容到目标指针里去。

    有没有感觉memmove和memcpy很相似?如果功能完全一样为什么还要创建不同的函数?别急,笔者从根本思想上为你解开疑惑。

    还记得我们之前说memcpy函数不可以拷贝目标指针和源指针有重叠空间的内容吗?memmove函数就很好解决了这个问题
    直接上图:
    在这里插入图片描述

    3.2memmove的模拟实现

    void* my_memmove(void* dst, const void* src, size_t count)
    {
    	void* ret = dst;
    	if (dst <= src || (char*)dst >= ((char*)src + count))
    	{
    		while (count--) {
    			*(char*)dst = *(char*)src;
    			dst = (char*)dst + 1;
    			src = (char*)src + 1;
    		}
    	}
    	else {
    		
    		dst = (char*)dst + count - 1;
    		src = (char*)src + count - 1;
    		while (count--) {
    			*(char*)dst = *(char*)src;
    			dst = (char*)dst - 1;
    			src = (char*)src - 1;
    		}
    	}
    	return(ret);
    }
    
    #include 
    #include 
    int main()
    {
    	char str[] = "memmove can be very useful......";
    	memmove(str + 20, str + 15, 11);
    	printf("%s", str);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    运行结果:
    在这里插入图片描述

    我们可以看到,当我们要拷贝目标指针和源指针有空间上的重叠内容的时候,仍然可以很好的拷贝出来。

  • 相关阅读:
    树的基本概念及二叉树
    C++笔记之引用折叠规则
    Nginx线程池剖析
    【JVM】字节码技术:手撕 多态执行原理
    【C语言】指针的进阶(二)—— 回调函数的讲解以及qsort函数的使用方式
    GEE错误——Line 2: ee.Image(...).filterBounds is not a function
    蚂蚁金服Java研发岗二面:说说HashMap 中的容量与扩容实现
    WeakHashMap 和 HashMap 的区别是什么,何时使用?
    网工记背配置命令(3)----POE配置示例
    在Windows10、Windows11系统下安装Docker
  • 原文地址:https://blog.csdn.net/flin666/article/details/127374632