如何在c中找到未知类型数组中的max元素(使用指向函数的指针)

Jes*_*ahm 2 c arrays algorithm pointers function

我试图写一个通用的函数,即获得任何类型的数组(int,float,string)并返回它的最大元素(如果它是一个字符串数组-然后词典编纂).我设法编译它,但是当我运行它时,我得到了segmentation fault (core dumped).谁能告诉我我的代码有什么问题?

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

void *maxElement(void **arr, int size, int(*comp)(void*, void*)) {
    int i = 0;
    void *max = NULL;

    for (i = 0; i < size; i++) {
        if (comp(arr[i], arr[i + 1])) {
            max = (void*)arr[i];        
        } else
            max = (void*)arr[i + 1];
    }
    return (void*)max;
}

int compareInt(void *a, void *b) {
    int *temp_a = (int*)a, *temp_b = (int*)b;

    if (*temp_a > *temp_b)
        return 1;
    return 0;
}

int main() {
    int i;
    int *result = 0;
    int array[4] = { 1, 3, 7, 0 };
    float array_f[4] = { 1.23, 6.57, 9.89, 11.56 };
    float result_f = 0;
    char string[5][6] = { "jess", "ron", "tom", "mia", "alex" };
    char answer[6];

    result = (int*)maxElement((void*)array, 4, &compareInt);
    printf("result: %d\n", *result);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

chq*_*lie 5

你走在正确的轨道上.以下是您的代码中缺少的一些内容:

  • 数组参数应该有类型void*,而不是void**.

  • 该函数maxElement应该采取的元素数一个元件的尺寸,等qsort().

  • maxElement函数有缺陷:它没有找到最大值并访问超出数组末尾的元素.

这些是可选的,但建议更改:

  • 数组参数应该是const限定的,因为您没有修改它.

  • 您应该返回元素索引以避免不必要的强制转换,并且所有索引和大小变量都应该具有类型size_t.

  • 为了与qsort和一致bsearch,比较函数应该接受const void*参数并返回0比较相等的元素,如果第一个参数小于第二个则返回负值,否则返回非零正值.

这是相应的代码:

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

size_t maxElement(const void *arr, size_t count, size_t size,
                  int(*comp)(const void*, const void*)) {
    size_t i, res = 0;
    const unsigned char *p1 = arr;
    const unsigned char *p2 = p1 + size;

    for (i = 1; i < count; i++, p2 += size) {
        if (comp(p1, p2) < 0) {
            p1 = p2;
            res = i;
        }
    }
    return res;
}

int compareInt(const void *p1, const void *p2) {
    const int *i1 = p1, *i2 = p2;
    return (*i1 > *i2) - (*i1 < *i2);
}

int compareFloat(const void *p1, const void *p2) {
    const float *f1 = p1, *f2 = p2;
    return (*f1 > *f2) - (*f1 < *f2);
}

int compareChars(const void *p1, const void *p2) {
    const char *s1 = p1, *s2 = p2;
    return strcmp(s1, s2);
}

int compareString(const void *p1, const void *p2) {
    const char * const *s1 = p1;
    const char * const *s2 = p2;
    return strcmp(*s1, *s2);
}

int main(void) {
    size_t result;
    int array[4] = { 1, 3, 7, 0 };
    float array_f[4] = { 1.23, 6.57, 9.89, 11.56 };
    char array_s[5][6] = { "jess", "ron", "tom", "mia", "alex" };
    const char *array_str[5] = { "jess", "ron", "tom", "mia", "alex" };

    result = maxElement(array, sizeof(array) / sizeof(*array),
                        sizeof(*array), compareInt);
    printf("int result: %d\n", array[result]);

    result = maxElement(array_f, sizeof(array_f) / sizeof(*array_f),
                        sizeof(*array_f), compareFloat);
    printf("float result: %f\n", array_f[result]);

    result = maxElement(array_s, sizeof(array_s) / sizeof(*array_s),
                        sizeof(*array_s), compareChars);
    printf("string result: %s\n", array_s[result]);

    result = maxElement(array_str, sizeof(array_str) / sizeof(*array_str),
                        sizeof(*array_str), compareString);
    printf("string result: %s\n", array_str[result]);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

请注意array_s固定长度字符数组和array_str字符串指针数组之间的区别.它们需要不同的比较功能.