一、与内存管理相关的函数(续)(编号另起)
1、restrict 说明符
restrict的意思是限制。用在声明指针变量上,含义是某内存区块只有当前指针一种访问方式,其它指针不能读写该块内存。这种指针称为"限制指针"。
使用方法:int * restrict ptr = malloc(sizeof(int));
说明:我这里经过反复试验,restrict编译器不能识别,后将restrict改成__restrict(加双下划线)编译正常,但 restrict 在程序编写、编译、运行过程中应报错而未报错;从网上查了原因讲是VS造成的。有解决办法的朋友请私信指教,不胜感激。
2、memcpy()函数的使用
功能:将一块内存(内容)拷贝到另一块内存。
使用格式:memcpy(参1,参2,参3);
参1 目标内存区指针
参2 源内存区指针
参3 拷贝字节数(size_t类型即正整型)
返回值:返回目标内存区指针
说明:
a. memcpy定义在<string.h>中,编译器如不能识别这个函数,请包含string.h。
b. 目标区指针、源区指针可以是任意类型(包含void* 类型),但目标区大小不能小于拷贝字节数,拷贝字节数不能大于源区字节数,否则会内存溢出。不同类型所占字节数不同、同类型不同编译器所占字节可能不同,故拷贝字节数还是通过 sizeof 计算为好。
c. 返回值返回的指针与pDest指针指向相同,故没有必要接收这个指针;如接收后使用可能还会导致运行异常。
d. memcpy可以替代strcpy进行字符串拷贝,速度会快些,但它不检查字符串尾的\0,拷贝长度需要自己考虑。
e. 如要将一段内存原样复制到另一段内存中,由于memcpy是按字节操作的,所以可以不管原来的数据类型,统一对目标区内存指针、源区指针定义成char* 类型(逐字节进行),就可以完成原样复制。这种办法可以用来复制文件,不需要关心文件自身的格式。
f. 复制内存区域的字节数,如是赋值字符串,应注意 "\0" 要计算进去。
3、memmove()函数的使用
功能:将一段内存数据复制(移动)到另一段内存。与memcpy的主要区别是:它允许目标区域与源区域有重叠,重叠区域原有内容会被更改。
使用格式:memmove(参1,参2,参3);
参1 目标内存区(字符数组)指针
参2 源内存区指针
参3 复制(移动)字节数(size_t类型即正整型)
返回值:返回目标地址的指针。
说明:
a. memmove函数定义在<string.h>,使用VS2022仅包含 <stdio.h> 运行正常。
b. 参1目标指针实际也是原始数据指针,应使用数组方式声明,以指针方式声明的VS2022运行错误,其它编译器情况不详。
4、memcmp()函数的使用
功能:比较两个内存区域
使用格式:memcmp(参1,参2);
参1 指向第一区域指针
参2 指向第二区域指针
参3 参加比较的字节数
返回值:参1 == 参2 返回0;
参1 > 参2 返回 1;
参1 < 参2 返回 - 1
说明:
a. memcmp也是定义在<string.h>中,具体情况同上。
b. 对于字符串比较,如果参3的值超过字符串实际长度,"\0"也会参加比较
c. 参1、参2即可以是数组方式声明的,也可以是指针方式声明的。
二、举例程序:
cpp
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
//a. restrict限定符
int* __restrict ptr = malloc(sizeof(int));
if (ptr == NULL)return 0;
*ptr = 3;
int* p = ptr;
*p = 5;
printf("%i %i\n", *p, *ptr); //restrict未起作用
//b. memcpy函数
char* pSource = "abcdefghijklmnopqrstuvwxyz";
int* pDest = malloc(sizeof(char) * 27);//26个字母加"\0"结束符
if (pDest == NULL)return 0;
memcpy(pDest, pSource, sizeof(char) * 27);//完成拷贝,"\0"也在拷贝范围
printf("%s\n", (char*)pDest); //显示拷贝结果
//c. memmove函数
char SN[] = "1111223344556677889900";//字符串中多了两个"2"
/*
分析:如果将"1111"中去掉两个"1",只需将第第三个"1"开始至结尾的部分,重新复制
回SN即可,因为memmove允许源区与目标区内存重合。所以源区指针起始位置应指向字符串
第三个"1",即SN+2;目标区指针还是SN。关于移动字节数,由于char型一个字符就是一个字节,
所以可以用strlen(SN)减去两个准备去掉的再加上一个看不见的"\0"即可。
*/
char* pDestSN = SN;
char* pSourceSN = &SN[2];
size_t n = strlen(SN) - 2 + 1;
memmove(pDestSN, pSourceSN, n);
printf("%s\n", SN); //SN中的字符串已被改变
//d. memcmp()函数
char* str1 = "天津市南开区";
char* str2 = "天津市和平区";
int myInt1[] = { 1,2,3,4,5 };
int myInt2[] = { 6,7,8,9,10 };
int ret = memcmp(str1, str2, 6);
printf("比较三个汉字返回值:%i\n", ret); //返回值是0(前三个汉字相同)
ret = memcmp(str1, str2, 12);
printf("比较六个汉字返回值:%i\n", ret); //返回值是1("南n"排在"和h"后边)
ret = memcmp(myInt1, myInt2, sizeof(myInt1));
printf("myInt1与myint2比较返回值:%i", ret); //返回值是-1
getchar();
return 0;
}