【内存操作函数】字符串函数不敢干的事,我干!

简介: 【内存操作函数】字符串函数不敢干的事,我干!

1. 前言🚩


我最近在刷题的时候全然不知的写出了一个bug代码,它大概意思是这样的:


int a[]={1,2,3};
int b[]={0,0,0};
strcpy(a,b);


我想将b数组拷贝到a数组去,我第一时间想到了strcpy函数。


但是显然strcpy是操作字符串的

那么我们有没有什么办法能够像strcpy函数一样操作整型呢?

天空一声巨响,我们的内存操作函数闪亮登场!今天的主角有三个:


男主小帅:memcpy函数 😎

女主小美:memmove函数 😎

猛男丧彪:memset函数 😎

还附送两个配角:


友情出演: memcmp函数 ✔

群众演员: memchr函数 ✔

2. memcpy介绍🚩


memcpy的函数原型:

cfa90e9f927a4266886e55a6f27c25cb.png

功能:从source的起始位置复制num个字节到destination的内存起始位置


用法示例:


#include<stdio.h>
#include<string.h>
int main()
{
  int a[5] = { 1,2,3,4,5 };
  int b[3] = { 33,22,11 };
  memcpy(a, b, sizeof(int) * 3);//将数组b往后12个字节(3个整型)的内容拷贝到数组a
  for (int i = 0; i < 5; i++)
  {
  printf("%d ", a[i]);
  }
  return 0;
}



值得注意的是:memcpy函数返回void* 类型指针,并且接受变量的类型也是void *,如果你想了解void * 这个变量,可以跳转 C语言void*详解


2.1 memcpy的缺点🏁

memcpy函数中的两个参数在内存中的位置是不能发生重叠的.


什么意思?举个例子:


29b86fc944f049b99c313d78fc7271a6.png

既然memcpy函数有缺陷,是时候让我们的女主:memmove函数出来解决问题了!


3. memmove函数介绍🚩


memmove的函数原型:


功能:从source的起始位置复制numaea401f26cae4d9b9a1e681a1e7f058b.png个字节到destination的内存起始位置


memmove和memcpy函数的功能是一样的,只不过memmove函数的source和destination指向的空间可以重叠


用法示例:


#include<stdio.h>
#include<string.h>
int main()
{
  int a[9] = { 1,2,3,4,5,6,7,8,9 };
  memmove(a, a + 5, 16);
  for (int i = 0; i < 9; i++)
  {
  printf("%d ", a[i]);
  }
  return 0;
}


这个结果符合我们的预期:

(覆盖了前面的1234后,后面的56789照常打印)


5f9634f709ba4ff6b5601bb3ced4841c.png

3.1 memmove的缺陷🏁

memmove函数无法使用某些机器所提供的特殊字节-字符串处理指令来实现

👍 👍 👍

导致的结果:memmove会比memcpy的效率低一些

👍 👍 👍

如果源和目标参数真的可能存在重叠,就应该使用memmove!

4. memset函数介绍🚩


memset的函数原型:

cf4eb39c6b4b4e78b98b5eb432ff996f.png


功能:把从ptr开始的num个字节的值都设置为value


用法示例:


#include<stdio.h>
#include<string.h>
int main()
{
  char a[6] = { 'a','b','c','d','e','f'};
  memset(a, '-', 3);
  for (int i = 0; i < 6; i++)
  {
  printf("%c ", a[i]);
  }
  return 0;
}


结果和我们预期的一样:

(将前三个字节的内容改成 ’ - ’ )



457d0972a08341f1b92ff499cc9e29a7.png

注意,这里内存操作函数中参数num的单位都是字节,如果你想要修改一个整型数组的前n个值,别忘了用n乘以整型的长度!


5. memcmp函数介绍🚩

memcmp的函数原型:

0f2489980d1c4a52b53648ead7dcf778.png


功能:memcmp对两段内存ptr1和ptr2的内容进行比较,共比较num个字节


用法示例:

#include <stdio.h>
#include <string.h>
int main ()
{
  char buffer1[] = "DWgaOtP12df0";
  char buffer2[] = "DWGAOTP12DF0";
  int n = memcmp( buffer1, buffer2, sizeof(char)*5);
  return 0;
}


memcmp的返回类型和strcmp一样:


负数代表ptr1小于ptr2.👀

正数代表ptr1大于ptr2.👀

0代表它们两个相同👀

值得注意的是:这些值是按照无符号字符逐字节比较,所以它用于比较不是单字节数据如整数,浮点数时可能给出不可预料的结果.


6. memchr函数介绍🚩

memchr的函数原型:

627fa7abf46241a7a377f2d4c894e246.png


功能:


从ptr开始,查找value第一次出现的位置

共查找num个字节.

如果找到,返回一个指向该位置的指针

如果没找到,返回NULL.

用法示例:


#include<stdio.h>
#include<string.h>
int main()
{
  char a[6] = { 'a','b','c','d','e','f'};
  char* p = memchr(a, 'd', sizeof(char) * 6);//在数组a中查找字符d第一次出现的位置
  for (int i = 0; i < 3; i++)//这里返回一个指针指向字符d,并将这个指针赋值给p
  {
  printf("%c ", p[i]);
  }
  return 0;
}


结果也符合我们的预期:


3a76a5a442514fecb089ddb6904d51bf.png


7. 总结及拓展🚩

总的来说这一板块还是没有难度的,所有的内存操作函数需要包含的头文件是:string.h.关于内存操作函数我们就完结撒花啦!


函数原型出处:C\C++字典:cplusplus


下面我给大家拓展一些字符操作函数:

(在做题时可以节省时间)

比如:


判断字符是否为0~9的数字

判断字符是不是字母

判断是否为大写字母(小写)

等等…

函数 满足下面条件就返回真
isspace 空白字符:空格’ ‘,换页’\f’,换行’\n’,回车’\r’,制表符’\t’
isdigit 十进制数字: 0 ~ 9
islower 小写字母: a ~ z
isupper 大写字母: A ~ Z
isalpha 字母 : a ~ z 或 A ~ Z
isalnum 字母或者数字: a ~ z,A ~ Z,0 ~ 9
ispunct 标点符号,任何不属于数字或字母的图形
————————————————

两个转换函数:


大写字母转小写字母: tolower

小写字母转大写字母: toupper

如:


char x = tolower('A');//变量x存储的是字符 'a'

1

最后,看完这一节的内容后

下次遇见字符串拷贝


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