C语言 filter函数如何处理不同类型的指针?

3pvhb19x  于 2023-05-22  发布在  其他
关注(0)|答案(1)|浏览(203)

写一个可以处理C中不同类型数组的filter函数!

我试着写一个过滤器函数,它接受一个整数数组和一个计算结果为true或false的回调函数。根据回调函数的结果,将一个元素添加到筛选后的数组中,该函数返回筛选后的数组。我们能概括它吗?比如,我们能让它适用于任何类型的数组吗?我不知道如何使它适用于字符串(char *)。
下面是代码片段,有人能解释一下它是如何工作的吗?(流以及为整数数组和char * 数组传递的内容)。如果是char * 数组,memcpy复制的是什么?

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>

void *filter(void *array, int size, int elementSize, int (*fn)(void *), int *filteredSize);
int isEven(void *);
int startsWith(void *);

void main()
{
    int arr[8] = {1,2,3,4,5,6,7,8}, *evens;
    char *strs[5] = {"Boy", "Apple", "Cat", "Zebra", "Aeroplane"};
    char **fStrs;
    int n, i;
    evens = (int *)filter(arr, 8, sizeof(int), isEven, &n);
    puts("Evens");
    for (i = 0; i < n; i++)
    {
        printf("%d\t", evens[i]);
    }
    printf("\n");
    free(evens);

    fStrs = (char **)filter(strs, 5, sizeof(char *), startsWith, &n);
    for (i = 0; i < n; i++)
        printf("%s  ", fStrs[i]);
    printf("\n");
    free(fStrs);
}

void *filter(void *array, int size, int elementSize, int (*fn)(void *), int *filteredSize)
{
    int i;
    void *filteredArray;
    *filteredSize = 0;
    filteredArray = malloc(size * elementSize);
    if (filteredArray == NULL)
        return NULL;
    for (i = 0; i < size; i++)
    {
        void *currentElementLoc = (char *)array + (i * elementSize);
        if ((*fn)(currentElementLoc))
        {
            void *filteredElementLoc = (char *)filteredArray + (*filteredSize * elementSize);
            memcpy(filteredElementLoc, currentElementLoc, elementSize);
            (*filteredSize)++;

        }
    }
    filteredArray = realloc(filteredArray, *filteredSize * elementSize);
    if (filteredArray == NULL)
    {
        free(filteredArray);
        return NULL;
    }

    return filteredArray;
}

int isEven(void *p)
{
    int num = *((int *)p);
    return !(num & 1);
}

int startsWith(void *ptrToStr)
{
    static int hasRun = 0;
    static char ch;
    char *str = *((char **)ptrToStr);
    if (!hasRun)
    {
        puts("Starts with");
        scanf(" %c", &ch);
        hasRun = 1;
    }
    return *str == ch;
}
5sxhfpxr

5sxhfpxr1#

如果你的意思是一个字符串的数组(而不是一个char的数组),那么你的“elementSize”是sizeof(char *)。字符串数组是指向字符串的指针列表。在这种情况下,“过滤器”将接受或拒绝整个字符串。

相关问题