【C进阶】内存函数

简介: 【C进阶】内存函数

 strcpy拷贝的仅仅是字符串,但是内存中的数据不仅仅是字符,所以就有了memcpy函数

1. memcpy

void *memcpy (void * destination ,const void * source , size_t num)

函数memcpy从source的位置开始向后拷贝num个字节的数据到destination的内存位置

#include<string.h>
int main()
{
  int arr1[10] = { 0 };
  int arr2[] = { 1,2,3,4,5 };
  //把arr2中的前5个整形的数据,拷贝放到arr1中
  memcpy(arr1, arr2, 20);
  return 0;
}

可以看到前5个整形都拷贝过来了


memcpy函数的模拟实现:

(1)一个字节一个字节的拷贝(dest,src转为char *

eg:如果拷贝7个字节(两个int *类型指针不能操作)

(2)(char *)dest++不能这样写,因为++的优先级高于强制类型转换

相当于先对原类型进行++,再进行进行强转

前置++(char *)dest虽然C语言中可以,但是改为c++就不能运行,所以还是正常写+1

#include<string.h>
#include<assert.h>
void* my_memcpy(void* dest, const void* src, size_t sz)
{
    void * ret=dest;
  assert(dest && src);
  while (sz--)
  {
    *(char*)dest = *(char*)src;
    dest = (char*)dest + 1;
    src = (char*)src + 1;
  }
    return ret;
}

一个数组arr={1,2,3,4,5,6,7,8,9,10},如果想在自身的基础上进行拷贝,即把1,2,3,4,5拷贝到3,4,5,6,7的位置上,想得到结果:1,2,1,2,3,4,5,8,9,10

但是得到的结果却是1 2 1 2 1 2 1 8 9 10

我们就发现不重叠内存的拷贝,可以使用memcpy,

重叠内存的拷贝,使用memmove函数

上面其实是标准规定,但是实际在VS2022这个环境中,memcpy也能实现重叠内存的拷贝

(其他平台不一定)

#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memcpy(void* dest, const void* src, size_t sz)
{
  assert(dest && src);
  while (sz--)
  {
    *(char*)dest = *(char*)src;
    dest = (char*)dest + 1;//这里不能写成(char*)dest++,强制类型转化是临时的,++的时候dest并不一定是char*类型的
    src = (char*)src + 1;
  }
}
int main()
{
  int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
  my_memcpy(arr + 2, arr, 20);
  for (int i = 0; i < 10; i++)
  {
    printf("%d ", arr[i]);
  }
  return 0;
}

2. memmove

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

参数和memcpy一样,但是memmove可以实现重叠内存的拷贝


memmove函数的模拟实现:

(这里不考虑直接开辟一个相同的空间再进行拷贝元素)

讨论:

dest<src:只能从前向后拷贝

dest>src:只能从后向前拷贝

dest和src不相干的时候:从后往前或者从前往后都可以

#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest, const void* src, size_t sz)
{
  void* ret = dest;
  assert(dest && src);
  if (dest < src)
  {
    //前->后
    while (sz--)
    {
      *(char*)dest = *(char*)src;
      dest = (char*)dest+1;
      src = (char*)src+1;
    }
  }
  else
  {
        //后->前
    while (sz--)
    {
      *((char*)dest + sz) = *((char*)src + sz);
    }
  }
  return ret;
}
int main()
{
  int arr[20] = { 1,2,3,4,5,6,7,8,9,10 };
  my_memmove(arr , arr+2, 20);
  for (int i = 0; i < 10; i++)
  {
    printf("%d ", arr[i]);
  }
  return 0;
}

3. memcmp

int memcmp ( const void * ptr1,const void *( ptr2  ,  size_t num )

类似strcmp函数,memcmp是一对字节一对字节进行比较,比较num个字节ACSII值

(1)返回值:

  • 如果返回值 < 0,则表示 str1 小于 str2
  • 如果返回值 > 0,则表示 str1 大于 str2
  • 如果返回值 = 0,则表示 str1 等于 str2
#include<stdio.h>
#include<string.h>
int main()
{
  int arr1[] = { 1,2,3,4,5,6,7 };
  //01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00
  int arr2[] = { 1,2,3,0x11223304 };
  //01 00 00 00 02 00 00 00 03 00 00 00 04 33 22 11 
  int ret = memcmp(arr1, arr2, 13);
  printf("%d\n", ret);
}

上面这个代码虽然arr1的元素多,但是比较前13个字节的大小都一样,那么ret=0


4. memset

void*memset(void*dest,intc,size_tcount)

复制字符c(一个无符号字符)到参数str所指向的字符串的前n个字符


(初始化前count个字节为c)


是以字节为单位设置内存的


eg1:将hello world中的wor改为xxx:


#include<stdio.h>
#include<string.h>
int main()
{
  char arr[] = "hell0 world";
  memset(arr + 6, 'x', 3);
  printf("%s\n", arr);
  return 0;
}

eg2: 思考这个代码将arr改为了啥?

#include<stdio.h>
#include<string.h>
int main()
{
  int arr[10] = { 0 };
  memset(arr, 1, 40);
  return 0;
}

每一个int类型的元素的每一个字节都改为了1

所以想把数组每一个元素都初始化为1,用memset函数是不可能实现的

但是可以都初始化为0


本次内容就到此啦,欢迎评论区或者私信交流,觉得笔者写的还可以,或者自己有些许收获的,麻烦铁汁们动动小手,给俺来个一键三连,万分感谢 !


目录
相关文章
|
1月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
33 3
|
27天前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
1月前
|
存储 程序员 编译器
C语言——动态内存管理与内存操作函数
C语言——动态内存管理与内存操作函数
|
1月前
|
编译器 C语言 C++
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
154 1
|
5月前
|
C语言
【C语言】:动态内存管理函数malloc,calloc,realloc和free的介绍的介绍
【C语言】:动态内存管理函数malloc,calloc,realloc和free的介绍的介绍
64 0
|
1月前
|
程序员 C语言
C语言内存函数精讲
C语言内存函数精讲
|
22天前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
19 0
|
1月前
|
C语言 C++
c语言回顾-内存操作函数
c语言回顾-内存操作函数
39 0
|
1月前
|
存储 C语言 C++
来不及哀悼了,接下来上场的是C语言内存函数memcpy,memmove,memset,memcmp
本文详细介绍了C语言中的四个内存操作函数:memcpy用于无重叠复制,memmove处理重叠内存,memset用于填充特定值,memcmp用于内存区域比较。通过实例展示了它们的用法和注意事项。
64 0
|
1月前
一刻也没有为它哀悼~接下来登场的是动态内存分配的malloc与realloc以及free函数
一刻也没有为它哀悼~接下来登场的是动态内存分配的malloc与realloc以及free函数
65 0