泛型编程,memcpy(),memmove(),memset()

void *p: 通用指针 , 也称泛型指针 , 没有类型的指针 , 仅仅记录地址的开头 , 不能算术运算 p+1, 不能
*p,malloc 的返回值就是 void *;

1.memcpy()函数

void *memcpy(
  void *dest,
  const void *src,
  size_t count
);//内存拷贝函数

1.1说明

内存拷贝函数

1.2参数

  • dest:目标地址
  • sec:源地址
  • count:拷贝的字节数

1.3举例

int main() {
    //整型
	int a = 10;
	int b;
	memcpy(&b, &a, sizeof(int));
	printf("%d", b);
  
    //字符串
	char str1[] = "hello";
	char str2[10] = "";
	memcpy(str2, str1, strlen(str1) + 1);
	printf("%s", str2);

    //数组
	double arr[] = { 1.2,2.3 };
	double brr[3];
	memcpy(brr, arr,sizeof(arr));
    return 0;
}

2.memmove()函数

void *memmove(
   void *dest,
   const void *src,
   size_t count 
);

说明:与memcpy()类似,最开始用于解决移动数据时的内存重叠问题,但现在memcpy()函数也可以解决这个问题,所以此函数现在不常用。

int main() {

	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove(&arr[3], &arr[0], 7 * sizeof(int));//把前面三个数据后移三格
	memmove(&arr[0], &arr[3], 7 * sizeof(int));//把前面三个数据前移三格
	memcpy(&arr[3], &arr[0], 7 * sizeof(int));//也可以就解决内存重叠

	return 0;
}

3.memset()函数

void *memset(
   void *dest,
   int c,
   size_t count 
);

3.1说明

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

3.2参数

  • dest:指向要填充的内存块。
  • c:要被设置的值。
  • count:要被设置为该值的字符数。

3.3举例

int main() {
	int arr[10];
	memset(arr,0,sizeof(arr));//常用
	memset(arr, 1, sizeof(arr));//把每个字节置1,不要这样使用

	return 0;
}

此函数最常见的用途为将目标内存块清零。

注意:memset赋值的时候是按字节赋值,是将参数化成二进制之后填入一个字节。上述代码第4行是将内存块中每个字节置为1。而不是最终转化为十进制的1。1的二进制为0000 0001,整型变量有四个字节,即数组中每个值变为00000001 00000001 00000001 00000001。

总结:

(1) 如果dest指向char型地址,c可为任意字符值;
(2) 如果dest指向非char型,如int型地址,要想赋值正确,c的值只能是-1或0,因为-1和0转化成二进制后每一位都是一样的。

4.自定义函数

以交换数据为例。
void Swap_char(char* p1, char* p2)
{
  char tmp = *p1;
  *p1 = *p2;
  *p2 = tmp;
}

void Swap_short(short* p1, short* p2)
{
  short tmp = *p1;
  *p1 = *p2;
  *p2 = tmp;
}

void Swap_int(int* p1, int* p2)
{
  int tmp = *p1;
  *p1 = *p2;
  *p2 = tmp;
}

int main()
{
  char a = 'x';
  char b = 'y';
  short c = 10;
  short d = 20;
  int e = 500;
  int f = 600;
  printf("%c,%c\n", a, b);
  Swap_char(&a,&b);
  printf("%c,%c\n",a,b);
  printf("%d,%d\n", c, d);
  Swap_short(&c,&d);
  printf("%d,%d\n",c,d);
  printf("%d,%d\n", e, f);
  Swap_int(&e,&f);
  printf("%d,%d\n",e,f);
  return 0;
}
从上面的代码能发现 , 交换的过程是一样的 , 不一样的只有数据类型。
下面的函数能针对所有的数据类型进行数据交换:
//size:字节数
void Swap(void* vp1, void* vp2,int size)
{
  void* tmp = malloc(size);
  memcpy(tmp, vp1, size);
  memcpy(vp1,vp2,size);
  memcpy(vp2,tmp,size);
  free(tmp);
}

int main()
{
  char a = 'x';
  char b = 'y';
  short c = 10;
  short d = 20;
  int e = 500;
  int f = 600;
  printf("%c,%c\n", a, b);
  Swap(&a,&b,sizeof(char));
  printf("%c,%c\n",a,b);
  printf("%d,%d\n", c, d);
  Swap(&c,&d,sizeof(short));
  printf("%d,%d\n",c,d);
  printf("%d,%d\n", e, f);
  Swap(&e,&f,sizeof(int));
  printf("%d,%d\n",e,f);
  return 0;
}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值