C语言内存函数的使用及其模拟实现

目录
  • 前言
    • memcpy
    • memcmp
    • memmove
    • memset
  • 总结

前言

在C语言中,我们除了会经常用到与字符相关的函数,我们还会使用到与内存相关的库函数。今天我们就来学习几个常见的内存函数吧!

memcpy

void * memcpy ( void * destination, const void * source, size_t num );

这是一个内存复制函数,该函数会从source的位置开始向后复制num个字节的数据到destination的内存位置。

这个函数在遇到 ‘\0' 的时候并不会停下来。

用法如下:

#include <stdio.h>
#include <string.h>
int main()
{
	char arr1[] = "Pierre de Fermat";
	char arr2[40];
	memcpy(arr2, arr1, strlen(arr1) + 1);
	printf("%s\n", arr2);
	return 0;
}

上述代码的arr2的输出结果为arr1中的内容。

我们要注意,在目标空间中,要保证有足够的空间放得下要拷贝的内容,以免造成越界。

模拟实现如下:

//memcpy的模拟实现
#include<stdio.h>
#include<string.h>
#include<assert.h>
//不会考虑内存重叠的情况
void* my_memcpy(void* dest, const void* source, size_t nums) {
	//先记录下dest的初始位置,便于后续返回
	void* ret = dest;
	//判断传入的两个指针是否为空
	assert(dest, source);
	//利用循环来控制拷贝字节的个数
	while (nums--) {
		//由于传入的是void*类型的指针,所以在使用前要强制转换为char*
		*(char*)dest = *(char*)source;
		dest = ((char*)dest) + 1;
		source = ((char*)source) + 1;
	}
	return ret;
}

memcmp

int memcmp ( const void * ptr1,const void * ptr2,size_t num );

这个函数是用来比较指定字节数的内存空间是否相同。

返回值如下:

上图来自于这里

当ptr1的内容小于ptr2的内容,就返回一个小于零的数,当ptr1的内容大于ptr2的内容,就返回一个大于零的数,相等则返回零。

由于用法比较简单,就不进行演示啦!

模拟实现如下:

#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_memcmp(const void* p1, const void* p2, size_t num) {
	//判断传入的两个指针是否为空
	assert(p1 && p2);
	//利用循环依次比较
	int i = 0;
	for (i = 0; i < num; i++) {
		if (*((char*)p1 + i) > (*(char*)p2 + i)) {
			return 1;
		}
		else if(*((char*)p1 + i) < (*(char*)p2 + i)){
			return -1;
		}
	}
	return 0;
}

memmove

void * memmove ( void * destination, const void * source, size_t num );

上面我们已经学习过memcpy 函数的使用了,但是,如果我们的源空间和目标空间有重复的部分,那么memcpy这个函数就会出现错误,为了避免出错,我们就来学习一下memmove这个函数吧!

int main() {
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove(arr+2, arr, 16);
	printf("%s\n", arr);
	return 0;
}

上面的代码执行后,arr会变成{3,4,5,6,5,6,7,8,9,10}

这个函数的模拟实现要分情况讨论

1.如果dest在source前面,那么就有可能会出现有一部分内存重叠的情况,我们就需要在source中,先拷贝前面的数据在拷贝后面的数据,即从前往后拷贝。

2.如果dest在source后面,两个指针相减的数值小于要移动的字节数,那么也会有内存重叠的情况,那么此时,我们就需要先拷贝后面的数据,在拷贝前面的数据,即从后向前拷贝。

3.如果dest与source之间的差值大于要拷贝的字节数,那么此时就属于是两块不重叠的内存之间的拷贝,此时即使是用memcpy也不会有问题。

综上,我们可以已dest在source前后作为分界线。

如果dest在source前面,那么我们就从前往后拷贝,如果dest在source后面,那么我们就从后往前拷贝。

具体代码实现如下:

#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memmove(void* dest, void* source, size_t num) {
	assert(dest &&  source);
	//记录初始dest的位置,方便后续返回
	void* ret = dest;
	//如果dest在source的前面,那么我们可以从前往后拷贝,防止数据被覆盖
	if (dest < source) {
		while (num--) {
			*(char*)dest = *(char*)source;
			dest = (char*)dest + 1;
			source = (char*)source + 1;
		}
	}
	else {
		while (num--) {
			//下面的num在第一次进入循环的时候已经减过1了
			*((char*)dest + num)= *((char*)source + num);
		}
	}
	return ret;
}

memset

void * memset ( void * ptr, char value, size_t num );

这个函数一般用于初始化一段内存。

我们只需要传入内存空间的地址,需要初始化的字符,还有需要初始化的字节数即可。

由于这个函数的用法也比较简单,所以我们也不进行用法演示啦!

模拟实现如下:

#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memset(void* dest, char ch, size_t num) {
	void* ret = dest;
	assert(dest);
	while (num--) {
		*(char*)dest = ch;
		((char*)dest)++;
	}
	return ret;
}

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • C语言字符函数、内存函数功能及实现代码

    C语言字符函数.内存函数 功能及实现 strlen函数(求字符串长度)注意点模拟实现 strcpy函数(字符串拷贝函数)注意点模拟实现 strcat函数(字符串衔接函数)注意点模拟实现 strcmp函数注意点模拟实现 strstr函数模拟实现 strtok函数使用 strerror函数使用 memcpy函数注意点模拟实现 memmove函数注意点模拟实现 memset函数注意点 strlen函数(求字符串长度) 统计字符串长度直到\0为止 注意点 1.属于<string.h>库 2.参数为字符

  • C语言内存操作函数详解

    目录 头文件:#include<memory.h> 2.memmove 3.memcmp 4.memset 总结 头文件:#include<memory.h> 1.memcpy 作用:内存拷贝 函数原型: void *memcpy( void *dest, const void *src, size_t count ); 使用: 使用格式:memcpy(目的地,原,想操作内存大小(单位字节)) 把 "参数2" 起始的 "参数3" 个字节 内容

  • C语言动态内存函数详解

    目录 动态开辟空间的原因 1.malloc函数 2.free函数 3.calloc函数 4.realloc函数 总结 动态开辟空间的原因 静态开辟空间是固定的,数组在申明的时候必须指定数组的长度,在编译的时候分配内存,但是我们在实际情况中对于内存空间的需求,不仅仅是上述的情况,有时候我们需要的空间只有在运行之后才能知道,所以需要开辟一个动态内存空间,满足更多需求. 1.malloc函数 void* malloc (size_t size); malloc函数是向内存申请一块连续的空间,并返回指向

  • C语言动态内存分配函数的实现

    在C中我们开辟内存空间有两种方式 : 1.静态开辟内存 :例如: int a;int b[10]; 这种开辟内存空间的特点是 所开辟的内存是在栈中开辟的固定大小的 ,如a是4字节 ,数组b是40字节 ,并且数组在申明时必须指定其长度 , 如果是全局数组的话,内存是在编译时分配好的,如果是局部变量数组的话,运行时在栈上静态分配内存.不管是全局数组还是局部数组,它们都有一个特点,那就是数组大小是确定的,是代码中写死的.那如果我们想在程序运行时才确定一个数组的大小 , 前两种在栈上分配内存的方法显然是

  • C语言内存函数的使用及其模拟实现

    目录 前言 memcpy memcmp memmove memset 总结 前言 在C语言中,我们除了会经常用到与字符相关的函数,我们还会使用到与内存相关的库函数.今天我们就来学习几个常见的内存函数吧! memcpy void * memcpy ( void * destination, const void * source, size_t num ); 这是一个内存复制函数,该函数会从source的位置开始向后复制num个字节的数据到destination的内存位置. 这个函数在遇到 '\0

  • C语言内存函数 memcpy,memmove ,memcmp

    目录 一.memcpy函数 1.用法 2.模拟实现memcpy函数 二.memmove函数 1.用法 2.模拟实现memmove函数 三.memcmp函数 1.用法 2.模拟实现memcmp函数 一.memcpy函数 1.用法 memcpy表示内存函数,用法跟strcpy差不多, 都是作为拷贝函数存在strcpy只能用于字符串函数,而memcpy函数可以使用任意类型在使用任意类型时,肯定用到的参数是voidvoid* memcpy(const void *dest,const void *src

  • C语言深入详解四大内存函数的使用

    目录 1.memcpy 2.memmove 3.memcmp 4.memset 1.memcpy 与字符串函数 strcpy 类似,也是进行拷贝.但是需要注意的是,strcpy 是针对字符串进行拷贝,而 memcpy 是针对内存进行拷贝. 如何理解呢?strcpy 进行拷贝的时候,只能一个字节一个字节的拷贝,但要实现 整型.浮点型等数据类型拷贝的时候,就不得不用到 memcpy 了. 我们观察 strcpy 的函数声明: char * strcpy ( char * destination, c

  • C语言详解如何应用模拟字符串和内存函数

    目录 1.strlen 求字符串长度 使用案例: 1.计数法 2.不创建临时变量计数器-递归 3.指针-指针的方式 2.长度不受限制的字符串函数 1.strcpy 使用案例: 模拟实现: 2.strcat 使用案例: 模拟实现: 3.strcmp-比较字符串首字母的大小 使用案例: 模拟实现: 3.长度受限制的字符串函数  1.strncpy 使用案例: 2.strncat  使用案例: 3.strncmp 使用案例: 4.strstr-找子串  使用案例: 模拟实现: 5.strtok 用法:

  • C语言模拟内存函数分析之mencpy与memmove

    目录 前言 模拟实现简单的内存函数 1.memcpy-内存拷贝函数(应该拷贝不重叠的内存) 2.memmove-内存拷贝函数(可以拷贝重叠的内存) 总结 前言 内存是CPU与外存进行沟通的桥梁. 在冯·诺依曼计算机结构中,存储器是计算机的存储部件,是信息存储的核心,用来存放程序和数据. 存储器分为内存(内存储器.主存储器)和外存(外存储器.辅助存储器). CPU能够直接访问的存储器是内存.外存用于帮助主存记忆更多的信息,外存内的信息必须调入内存后,才能被CPU所使用.因此,内存是CPU与外存进行

  • C语言字符串函数,字符函数,内存函数使用及模拟实现

    目录 求字符串长度 strlen 长度不受限制的字符串函数 strcpy strcat strcmp 长度受限制的字符串函数 strncpy strncat strncmp 字符串查找函数 strstr strtok strerror 字符函数 字符分类函数 字符转换函数 内存操作函数 memcpy memmove memcmp memset 求字符串长度 strlen 函数功能 字符串长度,求一个字符串中字符的个数(不包含’\0’). 函数参数: size_t strlen( const ch

  • C语言进阶教程之字符串&内存函数

    目录 前言: 一.求字符串长度 strlen strlen函数的模拟实现 二.长度不受限制的字符串函数 strcpy strcpy函数的模拟实现 strcat strcat函数的模拟实现 strcmp strcmp函数的模拟实现 三.长度受限制的字符串函数 strncpy strncpy函数的模拟实现 strncat strncat函数的模拟实现 strncmp strncmp函数的模拟实现 四.字符串查找 strstr strstr函数的模拟实现 strtok strtok函数的模拟实现 五.

  • 一篇文章带你了解C语言的一些重要字符串与内存函数

    目录 一.字符串函数 1. 求字符串长度的strlen 2.比较字符串大小的strcmp 3.复制字符串的strcpy 4.追加字符串的strcat 5.查找字符串函数的strstr 二.内存函数 1.复制 memcpy,memmove 2.比较 memcmp 总结 一.字符串函数 1. 求字符串长度的strlen size_t strlen ( const char * str ); 字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '

  • c语言重要的字符串与内存函数

    目录 一.字符串函数 1. 求字符串长度的strlen 2.比较字符串大小的strcmp 3.复制字符串的strcpy 4.追加字符串的strcat 5.查找字符串函数的strstr 二.内存函数 1.复制 memcpy,memmove 2.比较 memcmp 一.字符串函数 1. 求字符串长度的strlen size_t strlen ( const char * str ); 字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0'

随机推荐