目录
前言
一、memcpy()函数
二、memmove()函数
三、memset函数
四、memcmp()函数
总结
前言
在C语言中内存是我们用来存储数据的地址,今天我们来讲一下C语言中常用的内存函数。
一、memcpy()函数
memcpy()函数与我们之前讲的strcpy()函数类似,只不过memcpy()不单单可以用与字符串的复制,可以复制内存中的各种数据类型。函数语法定义:
void * memcpy ( void * destination, const void * source, size_t num );
•
函数
memcpy
从
source
的位置开始向后复制n
um
个字节的数据到
destination
指向的内存位置。
•
这个函数在遇到
'\0'
的时候并不会停下来。
•
如果source和destination有任何的重叠,复制的结果都是
未定义
的。
#include <stdio.h>
#include <string.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
memcpy(arr2, arr1, 20);//20为复制的字节总大小
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
虽然memcpy函数也可以实现重叠,但是对于重叠的内存,我们都是交给memmove函数来处理。
函数模拟实现:
void* memcpy(void* dst, const void* src, size_t count)
{
void* ret = dst;
assert(dst);
assert(src);
/*
* copy from lower addresses to higher addresses
*/
while (count--) {
*(char*)dst = *(char*)src;
dst = (char*)dst + 1;
src = (char*)src + 1;
}
return(ret);
}
由于不知道输入的数据类型,我们都是一个字节一个字节开始传输的,所以对地址继续强制类型转换为char *。
二、memmove()函数
memmove函数与上面memcpy函数类似,只不过处理的是重叠的内存。函数语法定义:
void * memmove ( void * destination, const void * source, size_t num );
•
和
memcpy
的差别就是
memmove
函数处理的源内存块和目标内存块是可以重叠的。
•
如果源空间和目标空间出现重叠,就得使用
memmove
函数处理。
#include <stdio.h>
#include <string.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
memmove(arr1 + 2, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
函数的的模拟实现:
有2种情况:
dest在sourc之后
所以我们需要从后往前复制,比如5->7 4->6 3->5 2->4 1->3,这样交换就不会数据丢失。
dest在source之前:
这时我们就要从前往后复制了,比如3->1,4->2,5->3,6->4,7->5,这样就不会覆盖之前的元素了。
void* 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);
}
三、memset函数
memset()函数的作用时给设置内存的,将内存中的值以字节为单位设置成想要的内容。
函数语法定义:
void * memset ( void * ptr, int value, size_t num );
#include<stdio.h>
#include<string.h>
int main()
{
char str[] = "hello world";
memset(str, 'x', 6);
printf(str);
return 0;
}
注意:由于
memset是每个字节每个字节进行设置的,所以对于整型元素的设置,可能达不到我们想要的效果。
#include<stdio.h>
int main()
{
int a[10] = {0};
memset(a,1,10 );
int i = 0;
for (i = 0; i < 10; i++) {
printf("%d ", a[i]);
}
return 0;
}
输出:
我们想把整型数组元素都设置为1,但是结果却不是我们想要的。因为memset函数是每个字节设置的,在数组中的元素在内存中为:
我们发现memset函数是每个字节都设置为1,所以不是我们想要的。
四、memcmp()函数
memcmp函数比较内存中数据大小,函数语法定义:
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
•
比
较从
ptr1
和
ptr2
指针指向的位置开始,向后的
num
个字节
•
返回值如下:
函数模拟实现:
int my_memcmp(const void* ptr1, const void* ptr2, size_t num){
assert(ptr1&& ptr2);
char* p1 = ptr1;
char* p2 = ptr2;
size_t count = num;
while (*p1==*p2)
{
if (num == count) {
break;
}
if (*p1 == '\0');
return 0;
p1++;
p2++;
count++;
}
return *p1 -*p2;
}
总结
上述文章讲了一些与内存有关的函数,希望对你有所帮助。