最近读的代码中时常见到memcpy、memset这俩个函数,所以今天特地将这俩个函数的用法总结一下
一、memset
1、memset函数声明
memset(void *s,int ch,size_t n);
将s开始的n个字节用ch的ASCII值替代并且返回s;若要清空一个内存区,char a [20]:
memset(a,0,20);2、头文件:string.h\memory.h
3、注意:
(1)memset函数按字节对内存块进行初始化,所以不能用它将int数组初始化为0和-1之外的其他值(除非该值高字节和低字节相同)。
(2)ch接收参数的范围0-255 ,该函数只能取ch的后八位赋给你所指定的范围的每个字节,
比如int a[5]赋值memset(a,-1,sizeof(int )*5)与memset(a,511,sizeof(int )*5) 所赋值的结果是一样的都为-1;因为-1的二进制码为(11111111 11111111 11111111 11111111)而511的二进制码为(00000000 00000000 00000001 11111111)后八位都为(11111111),所以数组中每个字节,如a[0]含四个字节都被赋值为(11111111),其结果为a[0](11111111 11111111 11111111 11111111),及a[0]=-1,因此无论ch多大只有后八位二进制有效,而八位二进制的范围(0~255)YKQ改。而对字符数组操作时则取后八位赋值给字符数组,其八位值作为ASCII 码。
(3)注意n和ch的位置
(4)不要过度使用
(5)注意有时候的指针降级
例:int func(struct some *a)
{
…
memset(a,0,sizeof(a))
}
此处由于指针降级导致sizeof(a)返回的是一个指针的字节数,4字节
memset一般就用于初始化内存空间,比起for来,memset是一个比较快捷的方式
二、memcpy
1、memcpy函数声明
void *memcpy(void *dest, const void *src, size_t n);
从源src所指的起始位置开始拷贝n个字节到dest所指 的内存地址的起始位置中,返回一个指向dest的指针
2、头文件 :string.h
3、注意:
(1)source和destin所指的内存区域可能重叠,但是如果source和destin所指的内存区域重叠,那么这个函数并不能够确
保source所在重叠区域在拷贝之前不被覆盖。而使用memmove可以用来处理重叠区域。函数返回指向destin的指针
(2)如果目标数组destin本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。如果要追加数据,则每
次执行memcpy后,要将目标数组地址增加到你要追加数据的地址。
(3)src和dest都不一定是数组,任意的可读写空间均可
4、与strcpy的不同
(1)复制的内容不同,strcpy只能复制字符串,而memcpy可以复制任何内容
(2)复制方式不同,strcpy不需要指定长度,直到遇到‘\0’才会停止,容易溢出。memcpy指定长度较为安全
(3)用途不同,拷贝字符串用strcpy,复制其他的数据类型用memcpy;