将函数转换为通用 void 指针作为函数参数
Transform function to generic void pointer as function parameter
我必须将一个接收 int 数组的函数转换为一个通用函数,该函数将值与常量进行比较,returns 一个数组的值与该 const 不同,可以接收任何数组类型。为此,我使用了 void 指针,但我在获得正确输出方面遇到了一些问题,并且在数组的重新分配方面也遇到了一些问题。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ALG 0
int f2(int * e) {
return *e == ALG;
}
int * f1(int a[], size_t *size, int (*fin)(int * e)) {
size_t i = *size;
while(i--) {
if(fin(&a[i])) {
memmove(&a[i], &a[i+1], (--*size -i)*sizeof(int));
}
}
return realloc(a, *size * sizeof (int));
}
//generic type function
int * f1a(void *a, size_t *size, int (*fin)(int * e)) {
size_t i = *size;
while(i--) {
int * x = (int*) a + i;
if(fin(x)) {
memmove(a + i, a + i + 1, (--*size -i)*sizeof(*a));
}
}
return realloc(a, *size * sizeof (*a));
}
int main(void) {
int *a = malloc(8*sizeof(int));
a[0] = 2; a[1] = -3; a[2] = 1; a[3] = 0; a[4] = 4; a[5] = 7; a[6] = 0; a[7] = 6;
size_t i, size=8;
printf("%zu\n", size);
//int *res = f1(a, &size, f2); output : 2 -3 1 4 7 6
int *res = f1a(a, &size, f2);
for(i=0; i<size; i++) {
printf("%d ", res[i]);
}
return 0;
}
有人能帮帮我吗?
提前致谢!
编写可读代码。一次只做一件事。命名变量有意义。将上下文传递给用户回调函数。从 qsort
和 qsort_r
中汲取灵感。 free
记忆。处理错误。
翻译 1:1 你的函数,增加了一个 size
参数,表示一个数组元素的大小。
void *filter_generic(
void *base, size_t nmemb, size_t size,
size_t *out_nmemb,
int (*fin)(void* e, size_t size, void *cookie), void *cookie) {
for (size_t i = nmemb; i--; ) {
void *elempnt = (char*)base + (size * i);
if (fin(elempnt, size, cookie)) {
// the following is invalid and
// results in out-of-bounds access
memmove(
(char*)base + (size * i),
(char*)base + (size * (i + 1)),
size * (nmemb - i)
);
nmemb -= 1;
}
}
*out_nmemb = nmemb;
return realloc(base, size * );
}
在这种情况下,使用 two pointers 或两个索引非常简单。
#include <stdlib.h>
#include <string.h>
int intpnt_compare_to_zero(void *elem, size_t size, void *cookie) {
return *(int *)elem == 0;
}
/**
* Filters array elements depending on function.
* @param base like for qsort
* @param nmemb like for qsort
* @param size like for qsort
* @param out_nmemb return new size of the array
* @param compare comparison function
* @param cookie cookie for compare
* @return new allocate memory for array
*/
void *filter_generic(void *base, size_t nmemb, size_t size, size_t *out_nmemb,
int (*compare)(void *e, size_t size, void *cookie), void *cookie) {
void *out = base;
void *in = base;
void *const end = (char *)base + (size * nmemb);
for (; in < end; in = (char *)in + size) {
if (compare(in, size, cookie)) {
memmove(out, in, size);
out = (char *)out + size;
}
}
const size_t new_nmemb = ((char *)out - (char *)base) / size;
*out_nmemb = new_nmemb;
return realloc(base, size * new_nmemb);
}
int main(void) {
size_t size = 8;
int *a = malloc(sizeof(*a) * size);
a[0] = 2;
a[1] = -3;
a[2] = 1;
a[3] = 0;
a[4] = 4;
a[5] = 7;
a[6] = 0;
a[7] = 6;
int *res = filter_generic(a, size, sizeof(*a), &size, intpnt_compare_to_zero, NULL);
for (size_t i = 0; i < size; ++i) {
printf("%d%s", res[i], i + 1 == size ? "\n" : " ");
}
free(res);
}
代码打印 0 0
.
我必须将一个接收 int 数组的函数转换为一个通用函数,该函数将值与常量进行比较,returns 一个数组的值与该 const 不同,可以接收任何数组类型。为此,我使用了 void 指针,但我在获得正确输出方面遇到了一些问题,并且在数组的重新分配方面也遇到了一些问题。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ALG 0
int f2(int * e) {
return *e == ALG;
}
int * f1(int a[], size_t *size, int (*fin)(int * e)) {
size_t i = *size;
while(i--) {
if(fin(&a[i])) {
memmove(&a[i], &a[i+1], (--*size -i)*sizeof(int));
}
}
return realloc(a, *size * sizeof (int));
}
//generic type function
int * f1a(void *a, size_t *size, int (*fin)(int * e)) {
size_t i = *size;
while(i--) {
int * x = (int*) a + i;
if(fin(x)) {
memmove(a + i, a + i + 1, (--*size -i)*sizeof(*a));
}
}
return realloc(a, *size * sizeof (*a));
}
int main(void) {
int *a = malloc(8*sizeof(int));
a[0] = 2; a[1] = -3; a[2] = 1; a[3] = 0; a[4] = 4; a[5] = 7; a[6] = 0; a[7] = 6;
size_t i, size=8;
printf("%zu\n", size);
//int *res = f1(a, &size, f2); output : 2 -3 1 4 7 6
int *res = f1a(a, &size, f2);
for(i=0; i<size; i++) {
printf("%d ", res[i]);
}
return 0;
}
有人能帮帮我吗?
提前致谢!
编写可读代码。一次只做一件事。命名变量有意义。将上下文传递给用户回调函数。从 qsort
和 qsort_r
中汲取灵感。 free
记忆。处理错误。
翻译 1:1 你的函数,增加了一个 size
参数,表示一个数组元素的大小。
void *filter_generic(
void *base, size_t nmemb, size_t size,
size_t *out_nmemb,
int (*fin)(void* e, size_t size, void *cookie), void *cookie) {
for (size_t i = nmemb; i--; ) {
void *elempnt = (char*)base + (size * i);
if (fin(elempnt, size, cookie)) {
// the following is invalid and
// results in out-of-bounds access
memmove(
(char*)base + (size * i),
(char*)base + (size * (i + 1)),
size * (nmemb - i)
);
nmemb -= 1;
}
}
*out_nmemb = nmemb;
return realloc(base, size * );
}
在这种情况下,使用 two pointers 或两个索引非常简单。
#include <stdlib.h>
#include <string.h>
int intpnt_compare_to_zero(void *elem, size_t size, void *cookie) {
return *(int *)elem == 0;
}
/**
* Filters array elements depending on function.
* @param base like for qsort
* @param nmemb like for qsort
* @param size like for qsort
* @param out_nmemb return new size of the array
* @param compare comparison function
* @param cookie cookie for compare
* @return new allocate memory for array
*/
void *filter_generic(void *base, size_t nmemb, size_t size, size_t *out_nmemb,
int (*compare)(void *e, size_t size, void *cookie), void *cookie) {
void *out = base;
void *in = base;
void *const end = (char *)base + (size * nmemb);
for (; in < end; in = (char *)in + size) {
if (compare(in, size, cookie)) {
memmove(out, in, size);
out = (char *)out + size;
}
}
const size_t new_nmemb = ((char *)out - (char *)base) / size;
*out_nmemb = new_nmemb;
return realloc(base, size * new_nmemb);
}
int main(void) {
size_t size = 8;
int *a = malloc(sizeof(*a) * size);
a[0] = 2;
a[1] = -3;
a[2] = 1;
a[3] = 0;
a[4] = 4;
a[5] = 7;
a[6] = 0;
a[7] = 6;
int *res = filter_generic(a, size, sizeof(*a), &size, intpnt_compare_to_zero, NULL);
for (size_t i = 0; i < size; ++i) {
printf("%d%s", res[i], i + 1 == size ? "\n" : " ");
}
free(res);
}
代码打印 0 0
.