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的函数原型:
功能:从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函数中的两个参数在内存中的位置是不能发生重叠的.
什么意思?举个例子:
既然memcpy函数有缺陷,是时候让我们的女主:memmove函数出来解决问题了!
3. memmove函数介绍🚩
memmove的函数原型:
功能:从source的起始位置复制num个字节到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照常打印)
3.1 memmove的缺陷🏁
memmove函数无法使用某些机器所提供的特殊字节-字符串处理指令来实现
👍 👍 👍
导致的结果:memmove会比memcpy的效率低一些
👍 👍 👍
如果源和目标参数真的可能存在重叠,就应该使用memmove!
4. memset函数介绍🚩
memset的函数原型:
功能:把从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; }
结果和我们预期的一样:
(将前三个字节的内容改成 ’ - ’ )
注意,这里内存操作函数中参数num的单位都是字节,如果你想要修改一个整型数组的前n个值,别忘了用n乘以整型的长度!
5. memcmp函数介绍🚩
memcmp的函数原型:
功能: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的函数原型:
功能:
从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; }
结果也符合我们的预期:
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
最后,看完这一节的内容后
下次遇见字符串拷贝