当前位置:网站首页>C语言-内存操作函数
C语言-内存操作函数
2022-08-11 05:30:00 【CHAKMING1】
目录
一、内存函数详解
1.memcpy函数
为什么会有memcpy函数呢,这个函数与strcpy有什么区别,首先strcpy是字符串操作函数,那么我们如果想对整型、浮点型以及我们自己自定义的数据类型要如何操作,这时候就可以使用memcpy函数。
void * memcpy ( void * destination, const void * source, size_t num );
上面是函数的格式,void*类型是可以返回任意类型的指针。
destination:是接受要复制的内容的一个指针,同样是void*类型的
source:是要复制过去的来源指针,这里加上const是因为防止source被修改
num:复制的字节数,size_t是一个无符号类型
这个函数本质上是可以接受任何的指针类型,所以使用了void*来当作一个“万能”的作用,再通过类型转换,而转换成实际我们想要的指针类型。
void* my_memcpy(void* dest, const void* src, size_t num)
{
assert(dest && src); // 进行断言,需要包含头文件assert.h
void* ret = dest; // 定义一个ret接受dest,防止dest直接被修改无法返回
while (num--)
{
// 实际我们在传输过程中,无论是任何的数据类型,我们都是一个字节一个字节传
// 因为需要转换成char*类型,这样每次指针移动都是移动一位
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
以上就是memcpy函数的内部实现,那么下面这段代码是否有问题?
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
my_memcpy(arr + 2, arr, sizeof(int)*5);
for (int i = 0; i < 10; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
我们预想的结果可能是1,2,1,2,3,4,5,8,9,10,但实际并不是这样的。
实际输出的效果是这样,因为这个函数是没办法对有重复的内存区域进行复制的,因为我们在复制过程中,到第三位的时候,这个值以及被改掉了,所以之后的数一直复制的都是1,2,这就导致了这个值不是我们想要的。但实际,用库函数中的memcpy不会发生这种情况,因为编译器已经预料到我们会这样操作,所以现在有些编译器中memcpy函数也可以对这种情况进行操作,但是不建议这么做。
所以为了解决重叠拷贝的问题就有了memmove这个函数
2.memmove函数
memmove函数是在memcpy函数的基础上,可以对有重复包含的内存区域进行复制,得到我们想要的结果。
void * memmove ( void * destination, const void * source, size_t num );
这是memmove函数的格式,与memcpy函数一致,这里不做详细解释。
那么,这个函数是如何实现的?
void *my_memmove(void *dest, const void *src, size_t count)
{
assert(dest && src);
void *ret = dest;
// dest 为低地址,就从前向后拷贝
if (dest < src)
{
while (count)
{
*(char *)dest = *(char *)src;
dest = (char *)dest + 1;
src = (char *)src + 1;
count--;
}
}
// dest 为高地址,就从后向前拷贝
else
{
while (count--)
{
*((char *)dest + count) = *((char *)src + count);
}
}
return ret;
}
本质上,这个函数其实内部进行复制的过程与memcpy函数一致,但有一个不同的地方在于,如果说目标地址要比源头地址高,我们就从后向前进行拷贝,如果是目标地址比源头地址低,则还是按照memcpy函数的拷贝方式。
这样,我们就能得到想要的结果。
3.memcmp函数
这个函数是一个内存比较函数,比较两个指针开始的num字节大小,返回值与strcmp一致。
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
比较ptr1和ptr2指针开始的num个字节,返回值是int类型,返回值如下:
从第一个字节开始比较,如果ptr1大于ptr2,则直接返回一个大于0的数,ptr1等于ptr2,则继续往后比较,这时候num--,直到num等于0,两个指针还是相等,则返回一个0,ptr1小于ptr2,则直接返回一个小于0的数字。
int my_memcmp(const void* ptr1, const void* ptr2, size_t count)
{
assert(ptr1 && ptr2);
// 因为在while循环就进行了比较,所以要先--
while (--count && *(char*)ptr1 == *(char*)ptr2) // 这里是遇到不同后,退出
{
((char*)ptr1)++;
((char*)ptr2)++;
}
return *(char*)ptr1 - *(char*)ptr2; // 直接返回两个指针对应的值的差值
}
4.memset函数
void * memset ( void * ptr, int value, size_t num );
这是一个内存设置函数,ptr是需要被设置的指针,value是设置的值,num是从开始地址的num个字节,设置为value值。
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "almost every programmer should know memset!";
memset (str,'-',6);
puts (str);
return 0;
}
输出结果:------ every programmer should know memset
边栏推荐
- nepctf Nyan Cat 彩虹猫
- 智能风控中台设计与落地
- 本地缓存cookie的使用
- 系统性能及并发数的一些计算公式
- He Kaiming's new work ViTDET: target detection field, subverting the concept of layered backbone
- The whole process of Tinker access --- configuration
- SearchGuard configuration
- 开源之夏 2022 火热来袭 | 欢迎报名 OpenMLDB 社区项目~
- swagger错误:WARN i.s.m.p.AbstractSerializableParameter - [getExample,421] - Illegal DefaultValue null
- The Summer of Open Source 2022 is coming | Welcome to sign up for the OpenMLDB community project~
猜你喜欢
OpenMLDB Pulsar Connector: Efficiently connect real-time data to feature engineering
Scene-driven feature calculation method OpenMLDB, efficient implementation of "calculate first use"
微信小程序启动页的实现
Visual studio2019 configuration uses pthread
Open Source Machine Learning Database OpenMLDB Contributor Program Fully Launched
论文解读:GAN与检测网络多任务/SOD-MTGAN: Small Object Detection via Multi-Task Generative Adversarial Network
厂商推送平台-华为接入
父子节点数据格式不一致的树状列表实现
js 学习进阶(事件高级 pink老师教学笔记)
JS小技巧,让你编码效率杠杠的,快乐摸鱼
随机推荐
Vscode远程连接服务器终端zsh+Oh-my-zsh + Powerlevel10 + Autosuggestions + Autojump + Syntax-highlighting
第六届蓝帽杯 EscapeShellcode
【无标题】
Day 69
Use c language to implement tic-tac-toe chess (with source code, you can run it directly)
JS案例练习(pink老师经典案例)
OpenMLDB + Jupyter Notebook:快速搭建机器学习应用
Vscode remote connection server terminal zsh+Oh-my-zsh + Powerlevel10 + Autosuggestions + Autojump + Syntax-highlighting
开发公众号授权遇到的redirect_uri参数错误
OpenMLDB Pulsar Connector: Efficiently connect real-time data to feature engineering
微信小程序云开发项目wx-store代码详解
Day 76
JS case exercise (classic case of teacher pink)
jdbc接口文档参考,jdbc接口方法逻辑探究
Matplotlib找不到字体,打印乱码
js 学习进阶(Dom部分 pink老师教学笔记)
虚拟机更改IP地址
Use the adb command to manage applications
连接数据库时出现WARN: Establishing SSL connection without server‘s identity verification is not recommended.
Day 70