如何在C中使用指针/返回一个int数组?

时间:2014-03-02 19:16:40

标签: c pointers quicksort

我目前正在尝试用C编写一个简单的Quicksort代码,但我似乎无法理解C语法和指针。我习惯用Java编码,所以我对如何返回int数组感到困惑,以及我做错了什么。

这是我现在的代码,非常感谢任何帮助。

#include <stdio.h>

#define MAX 100
int input[MAX];

int* QuickSort(int A[], int n);
int* combine (int first[], int pivot, int last[]);

//main method to run program
int main()
{
    int i, n;

//read in input and store values in array named input
printf ("Enter several numbers separated by spaces or returnsand ended by Ctrl-D:\n");
for (n = 0; n < MAX && scanf("%d", &input[n]) != EOF; n++);

//runs QuickSort on the array
int new[n] = QuickSort(input, n);

printf("Here is your sorted array:\n");
//goes through sorted array to print values
for (i = 0; i < n; i++)
    printf("%d\n", new[i]);
}

int* QuickSort(int A[], int n)
{
//if array has 1 value or is empty, automatically return
if (n <= 1)
    return A;

int pivot = A[0]; 
int less[n/2];
int more[n/2]; 

int lesscount = 0;
int morecount = 0;
int i;
for (i = 1; i<n; i++)
{
    if (A[i] <= pivot)
    {
        less[lesscount] = A[i];
        lesscount++;
    }
    else if (A[i] > pivot)
    {
        more[morecount] = A[i];
        morecount++;
    }
}
int size = n/2;
return combine(QuickSort(less, size), pivot, QuickSort(more, size));

}
int* combine (int first[], int pivot, int last[])
{
int firstsize = sizeof(first)/sizeof(first[0]);
int lastsize = sizeof(last)/sizeof(last[0]);
int totalsize = firstsize + lastsize + 1;
int combined[totalsize];

int n;
for (n =0; n<firstsize; n++)
{
    combined[n]= first[n];
}
combined[n]=pivot;
n++;
int m;
for (m =0; m<totalsize; m++)
{
    combined[n] = last[m];
    n++;
}

return combined;
}

1 个答案:

答案 0 :(得分:1)

基础知识

指针是一个可以取消引用和访问的内存地址。它与一个对象非常不同,并且(很可能)只是一个8字节的值。而在Java中你可能能够传递对象(它确实指向一些内存),在C中你必须更加小心你所指向的记忆。

特别是stackheap之间存在差异。 stack是您的程序用于跟踪局部变量并将自动分配空间的内容。另一方面,heap通常是您需要自己管理的东西。特别是,除非您明确分配堆地址,否则您将无法获得堆地址(即使用malloc)。为什么区别?因为堆栈会自动分配空间,但也会在函数返回时自动释放空间。

为什么这适用于你?

让我们来看看你的一些功能:

int* combine (int first[], int pivot, int last[])
/* i.e., int* combine (int *first, int pivot, int *last) */
{
    int firstsize = sizeof(first)/sizeof(first[0]);
    int lastsize = sizeof(last)/sizeof(last[0]);
    int totalsize = firstsize + lastsize + 1;
    int combined[totalsize];
    /* The rest of the code */
    return combined;
}

你正在向任何正在调用你的函数的人返回combined,一个堆栈分配的变量。这样做是合法的&#34;从严格意义上说,它是不正确的,因为一旦你从函数返回,程序将自动释放内存。这意味着你可能会得到一些非常令人困惑的结果和/或错误。

现在,你如何解决这个问题?

在你的情况下,quicksort不需要更多的空间,只需要对变量进行一些巧妙的操作。因此,您实际上甚至不需要使用任何子数组,也不需要返回任何数组。关于指针的巧妙之处在于你获得了一个内存地址。因此,如果您更改了指向的内容(即A[0] = x),那么任何其他也知道A的函数都会看到该更新。

并适用于快速排序?

您的初始实施也不完全正确。 Quicksort可以大致分为两个步骤:分区和组合。分区时,您希望将所有小于枢轴值的值与大于枢轴值的所有值分开。但是,因为您还不知道有多少,假设您在每个分区中都有size/2会给您带来麻烦。

对于分区,您可以使用就地迭代方法。像这样:

while index < end:
    if A[index] < pivot:
        index ++
    else if A[index] > pivot:
        swap(A[index], A[end])
        end --
swap(pivot, A[index])

(上面可能有一些错误。)基本的想法是,通过用两个索引跟踪下部和上部,你可以添加&#34;您正在与正确的一方进行比较的当前值(通过移动到下一个索引,或者交换和减少结束)。通过这样做,您不需要处理内存分配。

然后,递归步骤将知道您的子片段在哪里,并递归地调用每个子片段。