当前位置: 首页 > article >正文

C语言----内存函数

内存函数主要用于动态分配和管理内存,它直接从指针的方位上进行操作,可以实现字节单位的操作。

其包含的头文件都是:string.h

memcpy

copy block of memory的缩写----拷贝内存块

格式:

void *memcpy(void *dest, const void *src, size_t num);

作用:与strcpy类似,但是从内存的角度从source的位置开始向后复制num个字节的数据到destination指向的内存位置。

要求:

• 这个函数在遇到 '\0' 的时候并不会停下来。也就是说如果在数据中间插入 ‘\0’ 是不会停下复制进程的。

• 如果source和destination有任何的重叠,复制的结果都是未定义的。

• 鉴于拷贝的类型不一,使用*void来表示任意类型。

• num的单位是字节

实例:

int main()
{
	char arr1[20] = "hello world";
	char arr2[20] ;
	memcpy(arr2, arr1,strlen(arr1)+1);//需要复制的字节数为arr1的长度加上字符串结束符'\0'
	printf("%s", arr2);
	return 0;
}

 

int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = { 0 };
	//将arr1中的4 5 6 7 8,拷贝到arr2中
	memcpy(arr2, arr1+3, 5 * sizeof(int));//可以拷贝数组中的任意数据
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

模拟实现:

void* my_memcpy(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	while (num--)//根据所要复制的字节数进行递减直到复制完成
	{
		assert(dest && src);
		*(char*)dest = *(char*)src;
		dest = (char*)dest+1;
		src = (char*)src + 1;
	}
	return (ret);
}

memmove

move block of memory的缩写----内存体转移

格式

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

作用与要求

和memcpy的差别就是memmove函数处理的源内存块和⽬标内存块是可以重叠的。 如果源空间和⽬标空间出现重叠,就得使⽤memmove函数处理。由于该特性,实际上memmove比memcpy更加实用,兼容性也更强。

实例:

int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove(arr1 + 2, arr1, 20);//20个字节就是五个整型,在这里arr1+2也就是从3开始拷贝1,2,3,4,5五个数字
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}//打印出的结果是1,2,1,2,3,4,5,8,9,10(因为arr1的空间只够放下十个整型,并且mommove是允许重叠内存空间的)

模拟实现:

void* my_memmove(void* dest, const void* src, size_t n) 
{
    unsigned char* d = (unsigned char*)dest;
    const unsigned char* s = (const unsigned char*)src;

    if (s < d && s + n > d) 
    {
        // 如果源地址在目标地址之前且重叠
        for (size_t i = n; i > 0; i--) 
        {
            d[i - 1] = s[i - 1];
        }
    } 
    else 
    {
        // 普通情况下的复制
        for (size_t i = 0; i < n; i++) 
        {
            d[i] = s[i];
        }
    }

    return dest;
}

memset

set block of memory的缩写----填充设置内存块

格式

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

作用:memset是⽤来设置内存的,将内存中的值以字节为单位设置成想要的内容。同时在重叠内存空间时实现覆盖原内容。

要求:

• 使用memset函数时需要谨慎,确保不会意外覆盖原有的数据。

实例:

int main() 
{
  char str[] = "almost every programmer should know memset!";
  memset(str, '-', 6);
  printf(str)
  return 0;
}//结果是 ------ every programmer should know memset!
//也就是说将almost覆盖

模拟实现:

void* my_memset(void* ptr, int value, size_t num) 
{
    unsigned char* p = (unsigned char*)ptr;
    for (size_t i = 0; i < num; i++) 
    {
        p[i] = (unsigned char)value;
    }
    return ptr;
}

memcmp

compare block of memory的缩写----比较内存块

作用:与strcmp类似,⽐较从ptr1和ptr2指针指向的位置开始,向后的num个字节,参照下表:

注意:同strcmp不同的是,memcmp可以比较内存区域的大小,具体参照下方实例。

实例:

int main()
{
	char ned1[] = "dsdsdssdds1";
	char ned2[] = "dsdsdssdds2";
	int n;
	n = memcmp(ned1, ned2, 44);
	printf("%d", n);
	return 0;
}

模拟实现:

int my_memcmp(const void* ptr1, const void* ptr2, size_t num)
{//比较内存区域大小
    const unsigned char* p1 = (const unsigned char*)ptr1;
    const unsigned char* p2 = (const unsigned char*)ptr2;
    for (size_t i = 0; i < num; i++) 
    {
        if (p1[i] < p2[i]) return -1;
        if (p1[i] > p2[i]) return 1;
    }

    return 0;
}


http://www.kler.cn/news/233448.html

相关文章:

  • 【蓝桥杯选拔赛真题64】python数字塔 第十五届青少年组蓝桥杯python 选拔赛比赛真题解析
  • 基于微信江西南昌某汽修店保养预约小程序系统设计与实现 研究背景和意义、国内外现状
  • 探索设计模式的魅力:代理模式揭秘-软件世界的“幕后黑手”
  • 【flutter】报错 cmdline-tools component is missing
  • 跟着pink老师前端入门教程-day23
  • k8s的Deployment部署策略线上踩坑
  • 论文精读的markdown模板——以及用obsidian阅读网页资料做笔记
  • 4核8g服务器能支持多少人访问?2024新版测评
  • 简单的Udp服务器
  • 人类的控制不同于机器的控制
  • MySQL篇之回表查询
  • SegmentAnything官网demo使用vue+python实现
  • LLaMA 2 和 QianWen-14B
  • 制作耳机壳的UV树脂和塑料材质相比劣势有哪些?
  • Amazon Dynamo学习总结
  • mac电脑快捷指令实现拼图
  • django中实现数据迁移
  • 数据结构(C语言)代码实现(八)——顺序栈实现数值转换行编辑程序括号分配汉诺塔
  • 深度学习(13)--PyTorch搭建神经网络进行气温预测
  • 如何在 Mac 上恢复永久删除的文件:有效方法
  • STM32F1 - 标准外设库_规范
  • Python包管理:如何将本地目录变为可引用的模块
  • OLAP技术的发展及趋势简述
  • React18原理: 渲染与更新时的重点关注事项
  • Java基础常见面试题总结-并发(一)
  • 深入理解WebSocket协议:实现实时通信的利器
  • 【GO语言卵细胞级别教程】03.条件与循环语句
  • 【MySQL】数据库基础 -- 详解
  • vue-cli引入本地json数据:封装为js文件,无需请求直接读取
  • c++学习:命名空间