Hello大家好!很高兴我们又见面了。
给生活添点passion,开始今天的编程之路!
今天我们来讲C语言中的内存函数。
目录
1、memcpy内存复制
2、memmove可重叠内存拷贝
3、memset设置字符
4、memcmp比较
1、memcpy内存复制
memcpy就是内存复制函数,作用类似于我们的strcpy,但是能实现的功能更多一些。
使用:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<string.h>
int main()
{char p[5] = "asd";char p1[5] = "***";memcpy(p,p1,2);printf("%s", p);return 0;
}
运行结果:
我们向函数中传入三个参数,前两个为地址,最后一个为复制的字节数。第一个地址为目的地,所以把第二个地址的前两个字节复制到第一个地址的前两个字节处。
memcpy的模拟实现:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<string.h>
void* My_memcpy(void* a, const void* b, size_t num)
{void* ret = a;while (num){*(char*)a = *(char*)b;(char*)a= (char*)a+1;(char*)b = (char*)b + 1;num--;}
}
int main()
{char p[5] = "asd";char p1[5] = "***";My_memcpy(p,p1,2);printf("%s", p);return 0;
}
还记得吗void*类型是不能进行函数加减操作的,所以我们要把它转化为(char*)类型,这样才能进行一个字节的前移。
2、memmove可重叠内存拷贝
memmove和memcpy最大区别就是memmove的两个指针可以重叠
使用:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<string.h>
int main()
{char p[10] = "aaabbb";memmove(p+3,p,3);printf("%s", p);return 0;
}
运行结果:
上面我们把p的前三个字符复制给了后三个字符。有兴趣的试试,这个操作memcpy能不能实现呢?
模拟实现:
首先我们先分析一下为什么重叠之后memcpy不行:
方框为被复制的变量,圆角方框为目的地,现在我们传线路1,然后传线路2,再传线路3,那么这时候问题就来了,线路3的起始地已经被复制为了1,那么这时候我们是想把3复制过去的,这样肯定是达不到我们想要的结果的。
那么如果这样重叠我们该怎么做呢?我们尝试从后往前复制,这样就不会有问题了:
同理,如果这样重叠:
我们就不能从后往前复制了,只能从前往后复制。
除了以上两种情况,还有这两种情况,是怎么复制都行的:
那么现在我们是不是可以用if判断是那种情况,把特殊的(可以是从后往前,也可以是从前往后)那一种孤立出来呢?
代码实现:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<string.h>
void* My_memmove(void* a, const void* b, size_t num)
{void* ret = a;if ((char*)a < (char*)b){while (num){*(char*)a = *(char*)b;(char*)a = (char*)a + 1;(char*)b = (char*)b + 1;num--;}}else{while (num){*((char*)a+num-1) = *((char*)b+num-1);num--;}}
}
int main()
{char p[10] = "aaabbb";My_memmove(p,p+3,3);printf("%s", p);return 0;
}
我们在这if else分别包含两种情况,这样就把往前复制和往后复制区分开来了。
3、memset设置字符
memset是用来设置内存的,将内存中的字节以单位设置成想要的内容。
函数使用:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<string.h>
int main()
{char p[10] = "aaabbb";memset(p,'*',3);printf("%s", p);return 0;
}
输出结果:
模拟实现:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<string.h>
void My_memcpy(void* a, int b, size_t num)
{while (num){*(char*)a = (char)b;(char*)a= (char*)a+1;num--;}
}
int main()
{char p[5] = "asdf";My_memcpy(p,'*', 2);printf("%s", p);return 0;
}
在写这里的时候突然想到了一个问题:如果我们写成char p[5]=“asdfg”能不能正常打印呢?
答案是不行。因为我们在设置字符串是,字符串结尾自带一个‘\0’,他也占了一个字节。
4、memcmp比较
比较两个指针开始,向后的n个字节。
返回值大于0,则第一个指针指向字符串大,等于0相等,小于0则第二个指针指向字符串大。
使用:
#include <stdio.h>
#include <string.h>int main()
{char buffer1[] = "asdz";char buffer2[] = "asdfff";int n;n = memcmp(buffer1, buffer2, sizeof(buffer1));if (n > 0) printf("'%s' is greater than '%s'.\n", buffer1, buffer2);else if (n < 0) printf("'%s' is less than '%s'.\n", buffer1, buffer2);else printf("'%s' is the same as '%s'.\n", buffer1, buffer2);return 0;
}
运行结果:
在这里就不给大家演示memcmp的模拟效果啦~
这里可能有人会说,哎你这博主怎么这样,分享知识怎么都不分享全?
我觉得,学习编程最高效的方式就是上手练习。相信你学到这,已经具备了自己编写模拟memcmp函数的能力了,更何况,memcmp和strcmp又是如此的相似,所以为什么不自己动手试试呢~
好了,今天的知识就分享到这,欢迎订阅我们的专栏:编程之路,后续我会继续更新更多c/c++/算法知识!