C语言的编程之美之内存函数

目录
  • 内存函数
    • memcpy内存拷贝
      • 原格式
      • 分析
      • 内存拷贝的问题
    • memmove内存重叠拷贝
      • C语言规定
      • 原格式
      • 分析
    • memset内存设置
      • 原格式
    • memcmp内存比较
      • 原格式
  • 总结

内存函数

memcpy内存拷贝

  • 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
  • 这个函数在遇到 ‘\0' 的时候并不会停下来。
  • 如果source和destination有任何的重叠,复制的结果都是未定义的。

原格式

分析

**字面上意思只要是内存里面的东西就都可以进行拷贝,所以就打破了字符串拷贝的魔咒,什么类型都可以进行拷贝,那就不需要想来,肯定回和万能类型(通用类型指针-无类型指针)void*有关,因为当时做qsort还是印象深刻的

/*num是几个字节的意思*/
void* my_memcpy(void* dest, const void* src, size_t num)
{
	assert(dest && src);
	void* ret = dest;
	while (num--)
	{
		//和void*连用char*,分成最小然后一个一个传
		*(char*)dest = *(char*)src;
		((char*)dest)++;//void*无类型不好直接加加,就强转char*再加加
		((char*)src)++;
	}
	return ret;
}

内存拷贝的问题

1.内存相关连的话,就会拷贝错误

那你怎么解决内存相关连还不会有上面的错误,正面赋值交集的内存空间会被操作两次,就会改变原来的值,那我们怎么做呢,如果从后面来呢,前面操作两次会把后面的变了,那就先把后面的拿走赋值,不就间接的改变了原来会变的情况了吗,所以这样上面的代码就得修改了,这是朝后面拷贝的情况,如果提目是朝前面拷贝的话,是不是从后面来就有问题了,反而从前面来会比较完美,所以我们得两种情况都得考虑到

所以为了解决重叠拷贝的问题就有了memmove这个函数

2.内存不够了还要朝里面拷贝直接程序挂了

memmove内存重叠拷贝

用来处理内存重叠的情况

C语言规定

memcpy 只要处理内存不重叠的拷贝就可以

memmove 处理重叠内存拷贝

我们重写memcpy的代码是满足C语言要求的,在vs这个编译器中memcpy实际上是超额完成任务了,他的效果已经和memmove效果一样了

你会发现他们跑出来的效果 是一样的,所以上面那个测试我就是用我自己的代码测试的(已经达到C语言的标准了)

我们再精细点就是memmove的内容了

原格式

分析

/*num是几个字节的意思*/
void* my_memmove(void* dest,const void* src, size_t num)//memmove和memcpy的参数是一样的
{
	assert(dest && src);
	void* ret = dest;
	if (dest < src)
	{
		while (num--)
		{
			//sre内存从前向后拷贝
			//和void*连用char*,分成最小然后一个一个传
			*(char*)dest = *(char*)src;
			((char*)dest)++;//void*无类型不好直接加加,就强转char*再加加
			((char*)src)++;
		}
	}
	else
	{
		while (num--)
		{
			//sre内存从后向前拷贝
			//和void*连用char*,分成最小然后一个一个传
			*((char*)dest+num) = *((char*)src+num);
			//((char*)dest)++;//void*无类型不好直接加加,就强转char*再加加
			//((char*)src)++;
		}
	}
	return ret;
}

memset内存设置

将缓冲区设置为指定的字符。

原格式

memcmp内存比较

和strcmp相似,只不过一个是比较字符串,一个比较内存,由于不知道什么类型,所以后面有字节个数限制,准确的说应该和strncmp相似,因为后面都有一个个数的参数

原格式

分析

基本和字符串比较一样,就是变成了内存比较罢了

//buf1内存里的内容比buf2内存里的内容大就>0,反之<0
int my_memcmp(const void* buf1, const void* buf2, size_t count)
{
	assert(buf1 && buf2);
	while (--count && *(char*)buf1 == *(char*)buf2)//这个先减减就是细节
	{
		((char*)buf1)++;
		((char*)buf2)++;
	}
	if (*(char*)buf1 - *(char*)buf2 > 0)
		return 1;
	if (*(char*)buf1 - *(char*)buf2 < 0)
		return -1;
	return 0;
}

给你count不要乱超,因为他操作的是内存,没有字符串补\0的功能

总结

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

(0)

相关推荐

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

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

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

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

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

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

  • C语言全部内存操作函数的实现详细讲解

    memcpy内存拷贝函数 void* memcpy(void* destination, const void* source, size_t num); memcpy函数从source的位置开始向后拷贝num个字节的数据到destination的内存位置 这个函数在遇到\0的时候并不会停下来 如果source和destination有任何的重叠,复制的结果都是未定义的 使用方法: #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #in

  • C语言的编程之美之内存函数

    目录 内存函数 memcpy内存拷贝 原格式 分析 内存拷贝的问题 memmove内存重叠拷贝 C语言规定 原格式 分析 memset内存设置 原格式 memcmp内存比较 原格式 总结 内存函数 memcpy内存拷贝 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置. 这个函数在遇到 '\0' 的时候并不会停下来. 如果source和destination有任何的重叠,复制的结果都是未定义的. 原格式 分析 **字面上意思只要是内存里面的东西

  • 一篇文章带你了解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语言面向对象编程中的封装

    目录 前言 一.面向对象基本概念 什么是对象? 对象与类 面向对象的编程方式 二.C语言实现面向对象 面向对象的三大特征 面向对象之封装 简介 代码实现–基础版 代码实现-进阶版 总结 前言 面向对象是一种思维方式,基本上用什么语言都是可以实现的.C语言的编程方式一般是面向过程的,但是也是可以实现面向对象的.对象是什么?什么又是面向对象?面向对象的三大特性又怎么实现,且听我细细道来. 一.面向对象基本概念 什么是对象? 此对象非彼对象,虽然有时候此对象又可以是你脑袋中的对象,那让我们从我们误解的

  • Go语言并发编程之互斥锁Mutex和读写锁RWMutex

    目录 一.互斥锁Mutex 1.Mutex介绍 2.Mutex使用实例 二.读写锁RWMutex 1.RWMutex介绍 2.RWMutex使用实例 在并发编程中,多个Goroutine访问同一块内存资源时可能会出现竞态条件,我们需要在临界区中使用适当的同步操作来以避免竞态条件.Go 语言中提供了很多同步工具,本文将介绍互斥锁Mutex和读写锁RWMutex的使用方法. 一.互斥锁Mutex 1.Mutex介绍 Go 语言的同步工具主要由 sync 包提供,互斥锁 (Mutex) 与读写锁 (R

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

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

  • Android编程实现获取系统内存、CPU使用率及状态栏高度的方法示例

    本文实例讲述了Android编程实现获取系统内存.CPU使用率及状态栏高度的方法.分享给大家供大家参考,具体如下: DeviceInfoManage类用于获取系统的内存,CPU的信息,以及状态栏的高度 import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReade

  • Java语言面向对象编程思想之类与对象实例详解

    在初学者学Java的时候,面向对象很难让人搞懂,那么今天小编就来为大家把这个思想来为大家用极为简单的方法理解吧. 首先我们来简单的阐述面向对象的思想. 面向对象: 官方的语言很抽象,我们把官方的解释和定义抛开.想想,自己有什么,对!!我们自己有手脚眼口鼻等一系列的器官.来把自己所具有的器官就可以看作我们的属性,自己是不是可以喜怒哀乐和嬉笑怒骂,这些是不是我们的行为,那么自己的具有的属性加自己有的行为就称为一个对象. 注意!!我们自己,一个个体是一个对象,因为,你是你,我是我,我们虽然有相同的,但

  • IE JS编程需注意的内存释放问题

    1.给DOM对象添加的属性是一个对象的引用.范例:var MyObject = {};document.getElementById('myDiv').myProp = MyObject;解决方法:在window.onunload事件中写上: document.getElementById('myDiv').myProp = null; 2.DOM对象与JS对象相互引用.范例:function Encapsulator(element) {    this.elementReference =

  • Go语言Web编程实现Get和Post请求发送与解析的方法详解

    本文实例讲述了Go语言Web编程实现Get和Post请求发送与解析的方法.分享给大家供大家参考,具体如下: 这是一篇入门文章,通过一个简单的例子介绍Golang的Web编程主要用到的技术. 文章结构包括: 1. Client-Get 请求 2. Client-Post 请求 3. Server 处理 Get 和 Post 数据 在数据的封装中,我们部分采用了json,因而本文也涉及到Golang中json的编码和解码. 一.Client-Get 复制代码 代码如下: package main i

  • c语言网络编程-标准步骤(比较简单)

    c语言网络编程-标准步骤,真的很简单啊 server.c 复制代码 代码如下: #include <stdio.h>#include <stdlib.h>#include <string.h>#include <netdb.h>#include <netinet/in.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h> #d

随机推荐