-1

我有一个数字数组..需要什么:通过malloc创建2个新数组,一个用于偶数,一个用于奇数,我们也需要在main中打印它们以及每个数组的大小

数组为 1,2,5,6,8,4,5,10,65,69,98,76,46,49,67

偶数数组必须是:2,6,8,4,10,98,76,46

奇数数组必须是:1,5,5,65,69,49,67

函数一定要这样写(老师要这样)

void evenodd(int a[],int** even,int* evensize,int** odd,int* oddsize)

我的代码:

#include <stdio.h>
#include <stdlib.h>
#define N 15
void evenodd(int a[],int** even,int* evensize,int** odd,int* oddsize)
{
    int i,j,cnte,cnto,e,o;
    cnte=cnto=0;
    for(i=0;i<N;i++)
    if(a[i]%2==0) cnte++;
    else cnto++;

    even=(int**)malloc(sizeof(int)*cnte);
    *evensize=cnte;
    odd=(int**)malloc(sizeof(int)*cnto);
    *oddsize=cnto;

    for(i=0,o=0,e=0;i<N;i++)
        if(a[i]%2==0)
        even[e++]=a[i];
        else odd[o++]=a[i];
  return;
}

int main()
{
    int i;
    int a[N]={1,2,5,6,8,4,5,10,65,69,98,76,46,49,67};
int *even,evensize,*odd,oddsize;
evenodd(a,&even,&evensize,&odd,&oddsize);
printf("Even Numbers Array: ");
for(i=0;i<evensize;i++)
printf("%d ",even[i]);
printf("\nSize of even array is: %d",evensize);
    printf("\n\n");
printf("Even Numbers Array: ");
for(i=0;i<oddsize;i++)
    printf("%d ",odd[i]);
printf("\nSize of even array is: %d",oddsize);
}

我认为错误出在 Malloc 中.. 但我不知道为什么..

4

3 回答 3

4

更新分配为

*even = malloc(sizeof(int)*cnte);
*odd = malloc(sizeof(int)*cnto);

并用作

for(i=0,o=0,e=0;i<N;i++)
    if(a[i]%2==0)
      (*even)[e++]=a[i];
    else 
      (*odd)[o++]=a[i];
于 2013-07-20T18:24:43.873 回答
3

您的malloc电话是:

even=(int**)malloc(sizeof(int)*cnte);
...
odd=(int**)malloc(sizeof(int)*cnto);

您认为这是错误的第一个线索应该是even并且odd是函数的输出参数evenodd,但在这里您正在修改局部变量。C 按值传递参数;为了修改调用者传递的对象,您必须添加一个级别间接(指针)。(有关此问题的解释,请参阅我对C Programming: malloc() inside another function的回答。)

因此malloc调用应该是:

*even=malloc(sizeof(int)*cnte);
...
*odd=malloc(sizeof(int)*cnto);

请注意,在 C 中,没有必要显式转换结果malloc这样做可以隐藏错误)。通常还建议使用p = malloc(sizeof *p)而不是p = malloc(sizeof (type))这样,如果类型发生p变化,您就不会默默地分配不正确的缓冲区大小:

*even=malloc(sizeof **even * cnte);
...
*odd=malloc(sizeof **odd * cnto);
于 2013-07-20T18:27:20.987 回答
2

由于 C 函数调用使用按值传递,要通过 out 参数传回一个值,您需要一个指向将保存传回值的变量的指针。但是,在该函数中,您需要取消引用指针以更改存储在变量中的值,以便调用者看到被传回的值。(您的计数器函数参数evensizeoddsize.)

举个例子,你的even数组是这样分配的:

    even=(int**)malloc(sizeof(int)*cnte);

当您动态分配类型的项目(或在本例中为项目数组)时FOOmalloc()逻辑上返回一个FOO *. 您不应该转换的返回值 malloc(),但无论如何您的转换都是错误的,它应该是:

    even=(int*)malloc(sizeof(int)*cnte);

然而,even是一个int **,它是一个指向int *even变量的指针main()。要main()查看结果,您必须取消引用传递给您的函数的指针。如前所述,您不应该转换 的结果malloc(),因为如果原型丢失,它可能会掩盖错误,这在最坏的情况下会导致未定义的行为。

    *even=malloc(sizeof(int)*cnte);

在 C 中,变量的声明模仿使用。所以int **even意味着这**even是一个int. 因此,要正确分配int值,even必须取消引用两次。第一次到达分配的数组malloc(),第二次到达所需的索引位置。所以,你的赋值语句:

        even[e++]=a[i];

是错误的,因为它正在为一个类型分配一个int值,因为它只被取消引用一次。由于是指向 的指针,请使用:int *evenevenint *

        (*even)[e++] = a[i];

同样,对odd函数参数进行相同的更正。

于 2013-07-20T18:22:46.187 回答