【问题标题】:Problem with effective function and arrays in CC中有效函数和数组的问题
【发布时间】:2021-01-05 16:20:41
【问题描述】:

我正在尝试编写一个有效的函数来接收大小为nab 的数组。

该函数应搜索数组中的所有数字,例如b-a < array[i],并将它们收集到一个名为incoming 的新排序数组中。

例如,对于输入 11,12,8,15,3,12,3,12b=15a=8,输出将是一个 6 大小的数组,其中包含值 8,11,12,12,12,15(任何高于 (b) 15-(a)8 )。

这是我自己的代码尝试:

#include<stdio.h>
#include<stdlib.h>
int* f5(int arr[], int n, int a, int b, int* p)
{
    int i,min,minIndex;
    int* incoming = (int*)malloc(*p*sizeof(int));
    for ( i = 0; i < n; i++)
    {
        if (arr[i]>(b - a))
        {
            incoming[i] = arr[i];
            (*p)++;
        }
    }

    return *incoming;

}
void main()
{
    int arr[] = { 12,3,12,3,15,8,12,11 };
    int  p, i;
    int incoming[] = f5(arr, sizeof(arr) / sizeof(arr[0]), 8,15, &p);
    printf("The size is: %d and the new marahc is: ", p);
    for (i = 0; i < p; i++) {
        printf("%d", incoming[i]);
    }
    free(incoming);
}

【问题讨论】:

  • 你的问题是什么?
  • 你说的有效函数是什么意思,或者,为什么有人会写一个无效的函数?
  • @Jabberwocky 抱歉,我的问题是是否有人能指出我的代码有什么问题。
  • 请跟进给出的编译器警告。
  • int p 的地址被传递给函数,该函数使用*p 来确定内存分配。 p未设置为任何值

标签: arrays c function


【解决方案1】:

所以我更正了您的 f5 函数,因为您没有正确分配新数组,因为您在将 (*p) 设置为您需要存储的元素数量之前使用了 malloc。之后,我按升序排列incoming 数组,如示例输出中的qsort 所示。我还添加了您从用户那里获取输入值的部分,因为在您发布的代码中,您可能只是在尝试特定的测试用例。

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

// compare function for qsort
int mycompare (const void* a, const void* b) {
    int val1 = *(const int*)a;
    int val2 = *(const int*)b;
    
    return (val1 - val2);
}
int* f5(int arr[], int n, int a, int b, int* p) {
    int target = b - a;
    int i;
    
    for (i=0;i<n;i++) { // storing number of values > (a-b)
        if (arr[i]>target) (*p)+=1;
    }
    
    int* incoming;
    if ((incoming= malloc((*p)*sizeof(int)))==NULL); // should always check malloc errors
    {
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    int j = 0;
    i = 0;
    while (i<n && j<(*p)) { // storing values in new array
        if (arr[i]>target) {
            incoming[j] = arr[i];
            j++;
        }
        i++;
    }
    
    return incoming;
}

void main() {
    int n, a, b, i;
    
    printf("Insert 'a' value: ");
    scanf("%d", &a);
    printf("Insert 'b' value: ");
    scanf("%d", &b);
    printf("Insert array size: ");
    scanf("%d", &n);
    
    int arr[n];
    printf("Insert array values: \n");
    for (i=0;i<n;i++) {
        scanf("%d", &arr[i]);
    }
    
    int size = 0;
    int *incoming = f5(arr, n, a, b, &size);
    qsort(incoming, size, sizeof(int), mycompare); // sorting array
    
    printf("The size is: %d and the new marahc is: ", size);
    for (i=0; i<size;i++) {
        printf("%d ", incoming[i]);
    }
    free(incoming);
}

【讨论】:

    【解决方案2】:

    f5 中,您需要确定分配所需的长度。您可以对arr[] 内容进行初始传递以确定所需的长度,也可以将长度设置为上限n,并在知道实际长度后调整其大小。

    使用初始通道的第一种方法:

    int* f5(int arr[], int n, int a, int b, int* p)
    {
        int i;
        int j;
        int* incoming;
        j = 0;
        for ( i = 0; i < n; i++)
        {
            if (arr[i]>(b - a))
            {
                j++;
            }
        }
        incoming = malloc(j*sizeof(int));
        if (incoming == NULL)
        {
            return NULL;
        }
        j = 0;
        for ( i = 0; i < n; i++)
        {
            if (arr[i]>(b - a))
            {
                incoming[j++] = arr[i];
            }
        }
    
        *p = j;
        return incoming;
    }
    

    使用分配大小上限的第二种方法:

    int* f5(int arr[], int n, int a, int b, int* p)
    {
        int i;
        int j;
        int* incoming = malloc(n*sizeof(int));
        if (incoming == NULL)
        {
            return NULL;
        }
        j = 0;
        for ( i = 0; i < n; i++)
        {
            if (arr[i]>(b - a))
            {
                incoming[j++] = arr[i];
            }
        }
    
        int* resized_incoming = realloc(incoming, j*sizeof(int));
        if (resized_incoming != NULL)
        {
            incoming = resized_incoming;
        }
    
        *p = j;
        return incoming;
    }
    

    如果malloc 返回NULL,则以上内容已编写为返回NULL

    第三种方法是从 incoming 的少量开始,并在必要时重新分配到更大的数量。

    main中,需要将变量incoming从数组类型改为指针:

        int* incoming = f5(arr, sizeof(arr) / sizeof(arr[0]), 8,15, &p);
    

    由于f5 现在可以返回NULL,因此应检查返回值并采取适当的措施:

        if (incoming == NULL)
        {
            fprintf(stderr, "Failed to allocate memory!\n");
            exit(EXIT_FAILURE);
        }
    

    您还需要添加代码来对过滤后的数字进行排序。

    【讨论】:

    • 首先非常感谢您!其次,我想在第一个代码中问你为什么将'j'初始化为 0 的两倍,如果我在函数 f5 中执行更多循环来对传入进行排序,函数的运行时是否仍保持 n 的大小?另外,您将如何以最有效的方式对新数组进行排序?还有一件事,为什么在函数 f5 中,您在开始时将传入定义为指针?再次感谢您的代码帮助我理解了很多。
    • 在将 j 重置为 0 后,我们知道在第一个和第二个循环之后它将以相同的值结束,因为递增 j 的条件测试在两者中是相同的循环。但是,您可以将第二个循环中的 j 替换为另一个初始化为 0 的变量 k,它的值应该与 j 相同。过滤后需要进行排序。要排序的元素数量为j(或k,或*p)。对元素进行排序的一种有效方法是使用qsort 库函数,如@Mateo Pinna 的回答所示。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 2020-12-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多