一、memmove函数实现
memmove函数是将一段内存区域的数据拷贝到另一个内存区域,函数的原型如下:
void *memmove(void *dest, const void *source, size_t num);
其中,dest
是指目标内存地址,source
是指源内存地址,num
是需要拷贝的字节数。
该函数在实现上与memcpy
函数类似,不同之处在于当源地址和目标地址有重叠部分时,memmove
函数仍能正确拷贝数据,而memcpy
函数则不能。
memmove
函数的实现可以分为以下几个步骤:
- 判断源地址和目标地址是否有重叠,如果有重叠,则从后往前拷贝,否则从前往后拷贝。
- 拷贝数据,一般使用指针进行拷贝,提高效率。
- 返回目标地址。
二、memmove函数运用
由于memmove
函数能够正确处理源地址和目标地址有重叠的情况,因此在对内存进行数据拷贝的时候,如果有可能出现重叠,应该优先考虑使用memmove
函数。
memmove
函数也可以用来完成一些特定的任务,如字符串的移动、删除、插入等。下面是一个使用memmove
函数实现字符串删除的例子:
#include <stdio.h>
#include <string.h>
void deleteCharacter(char *str, char ch) {
int len = strlen(str);
int i, j;
for(i = 0, j = 0; i < len; i++) {
if(str[i] != ch) {
str[j++] = str[i];
}
}
str[j] = '\0';
}
int main() {
char str[100] = "hello world";
deleteCharacter(str, 'l');
printf("%s\n", str);
return 0;
}
上面的代码中,deleteCharacter
函数用来删除字符串中的指定字符,函数中使用了memmove
函数来处理删除后的字符串的内存内容。
三、memmove函数用法
memmove
函数的使用方式十分简单,只需要传入目标地址、源地址和需要拷贝的字节数即可。下面是一个使用memmove
函数复制一个数组的例子:
#include <stdio.h>
#include <string.h>
int main() {
int arr1[] = {1, 2, 3, 4, 5};
int arr2[5];
memmove(arr2, arr1, sizeof(arr1));
for(int i = 0; i < 5; i++) {
printf("%d ", arr2[i]);
}
return 0;
}
上面的代码中,使用memmove
函数将arr1
数组中的内容复制到arr2
数组中,然后打印arr2
数组的内容。
四、trimmean函数
trimmean
函数是一个能够计算平均值的函数,但是该函数会忽略数据集中最大和最小的一部分数据,只考虑数据集中的中间部分。在某些统计学应用中,trimmean
函数比简单平均值更有意义,可以用memmove
函数来实现该函数的功能。
下面是一个使用memmove
函数实现trimmean
函数的例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
double trimmean(double *data, int size, double trimPercent) {
int trimSize = size * trimPercent;
double sum = 0.0;
double temp[size];
memcpy(temp, data, size * sizeof(double));
qsort(temp, size, sizeof(double), compare);
memmove(temp, temp + trimSize / 2, (size - trimSize) * sizeof(double));
memmove(temp + (size - trimSize) / 2, temp + size - trimSize / 2, trimSize * sizeof(double));
for(int i = 0; i < size - trimSize; i++) {
sum += temp[i];
}
return sum / (double)(size - trimSize);
}
int compare(const void *a, const void *b) {
return (*(double *)a > *(double *)b) - (*(double *)a < *(double *)b);
}
int main() {
double data[] = {2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0};
double trimPercent = 0.3;
int size = sizeof(data) / sizeof(double);
printf("trimmean = %lf\n", trimmean(data, size, trimPercent));
return 0;
}
上面的代码中,trimmean
函数使用memmove
函数将被排除掉的数据从数组中删除,然后再计算平均值。
五、memmove函数头文件
memmove
函数的头文件是<string.h>
,需要在代码中包含该头文件才能正常使用memmove
函数。
下面是一个使用memmove
函数的头文件的例子:
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "hello memmove";
memmove(str + 6, str, 5);
printf("%s\n", str);
return 0;
}
上面的代码中,使用了<string.h>
头文件中的memmove
函数,将字符串中的一部分移动到了另一个位置。
六、memmove函数memcpy
memcpy
函数与memmove
函数类似,但是memcpy
函数不能处理源地址和目标地址有重叠的情况。下面是一个使用memcpy
函数实现字符串复制的例子:
#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "hello world";
char str2[100];
memcpy(str2, str1, strlen(str1) + 1);
printf("%s\n", str2);
return 0;
}
上面的代码中,使用memcpy
函数将一个字符串复制到了另一个数组中。
七、memset函数
memset
函数可以将一个给定的内存地址的前n
个字节设置为某个指定的值。其函数原型如下:
void *memset(void *dest, int val, size_t num);
其中,dest
是要操作的内存地址,val
是要设置的值,num
是要设置的字节数。
下面是一个使用memset
函数将数组中的元素赋值为0的例子:
#include <stdio.h>
#include <string.h>
int main() {
int arr[] = {1, 2, 3, 4, 5};
memset(arr, 0, sizeof(arr));
for(int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
return 0;
}
上面的代码中,使用memset
函数将整形数组arr
中的元素全部赋值为0。