-1

I have some C code to practice the quick sort. I want to use macro the get the length of the array. The macro works fine in the main() function. But when I use the macro inside the sort function, it does not return the length of array. Please see the comments inside the code I left.

Also, I want to use struct to create the member function pointer called "sort" and "quick_sort". Any people who are good at c programming gives me some advise if there are some points that I can improve, not matter the syntax, the code format. I feel kind of weird about the sort and quick_sort functions format inside the struct. My purpose is use Array struct to call the functions.

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

#define NELEMS(a) (sizeof(a) / sizeof(a[0]))

typedef struct _Array Array;
struct _Array
{
    void (*sort)(int* arr); 
    void (*quick_sort)(int* arr, int l, int r);
};

void sort(int* arr);
void sort(int* arr)
{
    // Issues here.
    // The len is 2 not 5.
    // the macro returns the sizeof arr here is 8, not 20.
    int len = NELEMS(arr);
    if(len == 0){
        return;
    }
    void quick_sort(int* arr, int l, int r);
    quick_sort(arr, 0, len-1);
}

void quick_sort(int* arr, int l, int r)
{
    int j;
    if(l < r)
    {
        j = partition(arr, l, r);
        quick_sort(arr, l, j - 1);
        quick_sort(arr, j+1, r);
    }
}

int partition( int* a, int l, int r) {
    int pivot, i, j, t;
    pivot = a[l];
    i = l; j = r+1;

    while( 1)
    {
        do ++i; while( a[i] <= pivot && i <= r );
        do --j; while( a[j] > pivot );
        if( i >= j ) break;
        t = a[i]; a[i] = a[j]; a[j] = t;
    }
    t = a[l]; a[l] = a[j]; a[j] = t;
    return j;
}

void print_array(int* array, int len){
    int i;
    for(i = 0; i < len; i++)
        printf("%d, \n", array[i]);
}

int main(int argc, char const *argv[])
{
    int nums[5] = {5, 1, 3, 2, 4};
    // len is 20 / 4 = 5. It works fine.
    int len = NELEMS(nums); 
    Array *array = malloc(sizeof(Array));
    array->sort = sort;
    array->quick_sort = quick_sort;
    sort(nums);
    print_array(nums, NELEMS(nums));
    return 0;
}
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
user1323328
  • 119
  • 1
  • 5
  • 11
  • You have to pass length as function argument or some other way. – keltar Aug 10 '15 at 04:53
  • This must be a duplicate of some other question. – Jonathan Leffler Aug 10 '15 at 05:21
  • @keltar Thanks for comments. Except passing the length to the sort function, is there any elegant way to get the length of array if passing by pointer. – user1323328 Aug 10 '15 at 05:23
  • @user1323328 while there are more than one way to pass size (e.g. packing ponter and size into structure and passing this structure to functions), - no, you still have to pass size somehow. There is no way for generated function to know array size from pointer alone, or even if pointer is array at all or just single element. – keltar Aug 10 '15 at 05:32

1 Answers1

4

The macro works in main because nums is an array, sizeof(nums) gets the size of the array.

However, when it's passed as function argument, it's automatically converted to a pointer. In sort(), sizeof(nums) only gets the size of the pointer.

You could fix it by passing the size of the array explicitly.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
  • Thanks for comments. Except passing the length to the sort function, is there any elegant way to get the length of array if passing by pointer. – user1323328 Aug 10 '15 at 05:23
  • @user1323328 Passing the size explicitly is very elegant. – this Aug 10 '15 at 07:00