繁体   English   中英

C-返回指向数组的指针

[英]C - return pointer to an array

我必须用签名编写一个函数

 int *greater (int n[], int length, int value) 

返回指向包含n []中大于值的元素的数组的指针。 返回的数组必须恰好是长度,以容纳大于value的值并且没有未使用的元素。

我有以下代码:

#include <stdio.h>

int k=0, v[100];

int * greater(int n[], int length, int value)
{
    for (int i=0; i<length-1; i++)
        if (n[i]>value)
        {
            v[k]=n[i];
            k++;
        }
    int *p=v;
    return p;
}
int main ()
{
    int a[]={1,2,3,4,5};
    int *p=greater (a,5,3);
    int *end; end=v+k;
    while (p<=end)
    {
        printf ("%i ", *p);
        p++;
    }
}

问题是p将仅保留4的值,因此它将打印4 0,而不是45。任何想法我做错了吗?

要解决您的问题,请不要使用全局数组( v[100]; )。 代替,

  1. greater()定义一个指针
  2. 使用malloc()动态分配内存。
  3. 使用realloc()根据要求调整内存大小
  4. 返回指针。

根据@alk先生的评论,您可以使用全局变量k获得数组中元素的数量。

注意:使用完内存后,请不要忘记从main() free()指针。

顺便说一句, main()的推荐签名是int main(void)


编辑:

此外,就逻辑部分而言,如@BLUEPIXY先生和@karma_geek先生的评论中所述,请注意

  1. 将循环条件更改为for (int i=0; i<length; i++)
  2. while循环更改为while (p<end)

除了已经提到的建议之外,我还建议进行2个更改:

迭代for loop直到<length ,因为<legnth-1不会覆盖整个数组。

int * greater(int n[], int length, int value)
{
    for (int i=0; i<length; i++)
        if (n[i]>value)
        {
            v[k]=n[i];
            k++;  // increment
        }
    int *p=v;
    return p;
}

此外,更改结束公式。 这是因为在函数中发生增量的位置, k=0会更改为: k=1表示4 > 3 ,然后k=2表示5 > 3 现在,

end = v + k ; 

当我们想要少1个值时,将导致end = v + 2

int *end; end=v+k-1;  

输出正确的代码

由于规范不需要返回目标数组的大小,因此在函数内部分配新数组会使返回的指针变得无用,因为调用者不知道哪些元素(如果有)有效。

因此,唯一明智的方法是为目标分配内存,甚至不使用第二个数组。 规范也不要求这样做,因此您可能希望采用以下方法

  1. 对输入进行排序。
  2. 只需将1的结果循环即可找到大于给定阈值的第一个元素。
  3. 将指针返回到2中找到的元素。

例:

#include <qsort.h>

int cmp(const void * pv1, const void * pv2)
{
  int i1 = *((int *) pv1);
  int i2 = *((int *) pv2);

  return (i1 - i2);
}

int * greater(int n[], int length, int value)
{
  qsort(n, sizeof *n, length, cmp);

  while (0 < length)
  {
    --length;
    if (n[length] > value)
    {      
      break;
    }
  }

  return n + length + 1;
}

唯一要求/

返回的数组必须确切地是长度,以容纳大于value的值

被满足。

修改搜索功能,以返回在指针参数中找到的元素数。 在函数内分配结果数组,最小化函数中可能的分配数量,缩小结果数组,然后再返回。

例如:

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

int *
greater(
        const int const n[],
        const size_t n_elem,
        const int threshold,
        size_t *n_greater
        )
{
    size_t i = 0;
    size_t n_found = 0;
    size_t n_allocated = 0;
    int *ret = NULL;

    for (i = 0; i < n_elem; i += 1) {
        if (n[i] > threshold) {
            n_found += 1;
            if (n_found > n_allocated) {
                size_t new_size = (n_allocated < (n_elem / 2))
                                ? 2 * n_found
                                : n_elem
                ;
                int *tmp = realloc(ret, new_size * sizeof(*tmp));
                if (!tmp) {
                    fputs("Failed to allocate memory", stderr);
                    exit(EXIT_FAILURE);
                }
                n_allocated = new_size;
                ret = tmp;
            }
            ret[n_found - 1] = n[i];
        }
    }
    if (n_allocated > n_found) {
        int *tmp = realloc(ret, n_found * sizeof(*tmp));
        if (!tmp) {
            fputs("Failed to shrink result array", stderr);
            exit(EXIT_FAILURE);
        }
        ret = tmp;
    }
    *n_greater = n_found;
    return ret;
}

int main (void)
{
    int a[] = {1,2,3,4,5,1,1,2,3,7,6,5,5,0,-1,7};
    size_t n_greater_than_three = 0;
    size_t i =0;
    int *p = greater(a, sizeof(a)/sizeof(a[0]), 3, &n_greater_than_three);

    for (i = 0; i < n_greater_than_three; i += 1) {
        printf("%d\n", p[i]);
    }

    free(p);

    return EXIT_SUCCESS;
}

输出:

C:\...\Temp> greater.exe
4                                             
5                                             
7                                             
6                                             
5                                             
5                                             
7

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM