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的功能

总结

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

时间: 2021-09-13

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

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

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

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

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语言字符函数、内存函数功能及实现代码

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

C语言 不使用strcat函数实现连接两个字符串功能代码

字符串连接函数:  字符串连接就是将一个字符串连接到另一个字符串的末尾,使其组合成一个新的字符串,在字符串处理函数中,strcat  函数具有字符串连接功能.下面是用C语言实现不使用是strcat 函数实现连接两个字符串的功能. 源代码: #include<stdio.h> void constring(char s[],char t[],char q[]); //函数声明 int main(void) { char s[100]; char q[100]; char t[200]; prin

Python字符编码与函数的基本使用方法

一.Python2中的字符存在的解码编码问题 如果是现在正在用Python2的人应该都知道存在字符编码问题,就举一个最简单的例子吧:Python2是无法在命令行直接打印中文的,当然他也是不会报错的,顶多是一堆你看不懂的乱码.如果想在直接显示中文,我们是可以在Python2文件头部申明字符编码的格式.如下图 这里 #-*-coding:utf-8 -*- 是用来申明下面的代码是用什么编码来解释: 1.1.Python2中的解码和编码: 在编码和解码的世界中,我们得需要找一个大家都知道的文字.也可以

C语言模拟实现atoi函数的实例详解

C语言模拟实现atoi函数的实例详解 atoi函数,主要功能是将一个字符串转变为整数,例如将"12345"–>12345.但在实现过程中,我们难免会因为考虑不够全面而漏掉比较重要的几点,今天就总结一下实现atoi函数需要注意的地方. 1.指针为NULL 2.字符串为空字符串 3.空白字符 4.正号与负号问题 5.溢出问题 6.异常字符处理 接下来看代码:(具体几种问题处理都在代码的注释中说明) #define _CRT_SECURE_NO_WARNINGS 1 #include

C语言 指针变量作为函数参数详解

在C语言中,函数的参数不仅可以是整数.小数.字符等具体的数据,还可以是指向它们的指针.用指针变量作函数参数可以将函数外部的地址传递到函数内部,使得在函数内部可以操作函数外部的数据,并且这些数据不会随着函数的结束而被销毁. 像数组.字符串.动态分配的内存等都是一系列数据的集合,没有办法通过一个参数全部传入函数内部,只能传递它们的指针,在函数内部通过指针来影响这些数据集合. 有的时候,对于整数.小数.字符等基本类型数据的操作也必须要借助指针,一个典型的例子就是交换两个变量的值. 有些初学者可能会使用

Go语言的变量、函数、Socks5代理服务器示例详解

Go语言中变量的声明和JavaScript很像,使用var关键字,变量的声明.定义有好几种形式 1. 变量和常量 // 声明并初始化一个变量 var m int = 10 // 声明初始化多个变量 var i, j, k = 1, 2, 3 // 多个变量的声明(注意小括号的使用) var( no int name string ) // 声明时不指明类型,通过初始化值来推导 var b = true // bool型 // := 隐含声明变量并赋值 str := "mimvp.com"

常用Javascript函数与原型功能收藏(必看篇)

如下所示: // 重复字符串 String.prototype.repeat = function(n) { return new Array(n+1).join(this); } // 替换全部 String.prototype.replaceAll = function(str1, str2) { return this.replace(new RegExp(str1, "gm"), str2); } // 清除空格 String.prototype.trim = function

C语言实现字符串操作函数的实例

C语言实现字符串操作函数的实例 在编写程序的过程中,我们经常使用到一些字符串函数,例如求字符串长度,拷贝字符串--,这些函数都在C标准库中存在,我们可以直接使用.但我们还需要掌握这些函数的实现方法,今天来看看一些常用的字符串操作函数的实现方法. 1.strlen strlen是用来求字符串长度的函数,字符串长度就是它所包含的字符个数. 今天给大家介绍三种实现strlen函数的方法 (1)定义一个计数器count //方式一:定义一个计数器 size_t my_strlen(const char

浅谈C语言之字符串处理函数

下面介绍8种基本的常用的字符串处理函数,在数值数组中也常常用到(部分函数).所有的C语言编译系统中一般都提供这些函数. 1.puts函数--输出字符串的函数 一般的形式为puts(字符串组) 作用:将一个字符串输出到终端.如,char一个string,并赋予初值.调用puts(string);进行字符串的输出. 2.gets函数--输入字符串的函数 一般的形式:gets(字符数组) 作用:从终端输入一个字符串到字符数组,并且得到一个函数值成为字符数组的起始地址. gets(str); 键盘输入,

SQL Server实现split函数分割字符串功能及用法示例

本文实例讲述了SQL Server实现split函数分割字符串功能及用法.分享给大家供大家参考,具体如下: /* 函数名称:f_SplitToNvarchar 作用:实现split功能的函数 更新记录: 设计思路:将nvarchar类型字符结合的一个串,分隔到一张只有一列nvarchar类型的表里 */ CREATE FUNCTION [dbo].[f_SplitToNvarchar] ( @SourceSql NVARCHAR(MAX),--源分隔字符串 @StrSeprate VARCHAR

函数名称 函数功能

函数名称 函数功能Cbool(string) 转换为布尔值Cbyte(string) 转换为字节类型的值Ccur(string) 转换为货币类值Cdate(string) 转换为日前类型的值Cdbl(string) 转换为双精度值Cint(string) 转换为整数值Clng(string) 转换为长整型的值Csng(string) 转换为单精度的值Cstr(var) 转换为字符串值Str(var) 数值转换为字符串Val(string) 字符串转换为数值****** ************