在这里插入图片描述

一、c语言内存函数

1.1 memcpy函数

1.1.1 定义格式

memcpy函数的定义格式就是如下:
在这里插入图片描述

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

使用时必须包含头文件<memory.h>或者<string.h>。

函数参数列表中src 顾名思义就是源头从src中复制count个字节的数据到dest中。

1.1.2 与字符串拷贝strcpy函数区别

主要有以下两点不同:

  • 这个函数与字符串拷贝strcpy函数除了void*可以包含任意类型以外。

  • 这个函数遇到’\0’并不会结束,它一定会拷贝count个字节数据。接下来根据描述模拟实现一下。

1.1.3 模拟实现

对 memcpy函数模拟实现代码如下:

void* my_memcpy(void* dest, const void* src, size_t count)
{
	assert(dest && src);
	void* ret = dest;
	while (count--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}

1.1.4 缺点

根据这个实现我们可以看出如果src和dest有任何重叠区域,复制的结果都是未定义的。
那如何解决这个问题就有请下一个函数memmove出场。

1.2 memmove函数

1.2.1 定义格式

memmove函数的定义格式就是如下:

在这里插入图片描述

void* memmove(void* dest, const void* src, size_t count);

使用必须包含头文件<string.h>。

其中参数与memcpy一样,参数列表中src 顾名思义就是源头从src中复制count个字节的数据到dest中。

但是它可以处理src和dest内存重叠的情况。接下来模拟实现一下。

1.2.2 模拟实现

对 memmove函数模拟实现代码如下:

void* my_memmove(void* dest, const void* src, size_t count)
{
	void* ret = dest;
	if ((char*)dest > (char*)src)
	{
		(char*)src = (char*)src + (count - 1);
		(char*)dest = (char*)dest + (count - 1);
		while (count--)
		{
			*(char*)dest = *(char*)src;
			(char*)dest = (char*)dest - 1;
			(char*)src = (char*)src - 1;
		}
	}
	else
	{
		while (count--)
		{
			*(char*)dest = *(char*)src;
			(char*)dest = (char*)dest + 1;
			(char*)src = (char*)src + 1;
		}
	}
	return ret;
 }

可以看出memmove好像将memcpy包括了,memcpy可以处理的memmove都可以处理。

1.3 memset函数

memset函数的定义格式就是如下:
在这里插入图片描述

void* memset(void* dest, int c, size_t count);

这个函数的功能就是dest中count字节的内容设置为想要的数c.

1.4 memcmp函数

1.4.1 定义格式

memcmp函数的定义格式就是如下:
在这里插入图片描述

int memcmp(const void* buf1, const void* buf2, size_t count);

内存比较函数功能就是从buf1和buf2指针指向的位置开始比较count个字节。

buf1小返回小于0的数,buf2大返回大于0的数,如果比较到最后都没有比较出来返回0。

二、大小端字节序

乍一听以为是什么很了不起的东西,其实就是数据以二进制存储进内存到底是从高地址处先存还是低地址先存。

2.1大小端字节序的区别

大小端字节序的区别如下:

  • 大端存储:高地址存低地址数据,低地址存高地址数据。
  • 小端存储:高地址存高地址数据,低地址存低地址数据。

在这里插入图片描述表现在图中就是这样。那我们就可以编写程序判断当前环境是什么字节序。

#include<stdio.h>
int judge_system()
{
	int a = 1;
	return *((char*)&a);
}
int main()
{
	printf("%d ", judge_system() );
	return 0;
}

根据存储不同取出来第一个字节如果是小端就会返回1,大端返回0。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐