size of multi-dimensional array and qsort

Discussion in 'C Programming' started by bsder, Jul 14, 2005.

  1. bsder

    bsder Guest

    Hi,

    Can anyone please tell me how to calculate the size of the following
    4-dimensional array, and now to use qsort for sorting on this array?

    double sp[3] = { 4.0, 5.0, 6.0 };
    double spa[3][2] = {
    { 4.0, 2.0 },
    { 5.0, 8.0 },
    { 6.0, 6.0 },
    };

    double spb[3][2][2] = {
    { {1.0, 2.0}, {3.0, 4.0} },
    { {5.0, 6.0}, {7.0, 8.0} },
    { {9.0, 10.0 }, {11.0, 12.0} },
    };

    // spc(Time, X, Y, Z)
    double spc[3][1][1][1] = {
    { {{1.0}} },
    { {{5.0}} },
    { {{9.0}} },
    };


    for (int t=0; t<max_time; t++)
    for (int x=0; x<max_x; x++)
    for (int y=0; y<max_y; y++)
    for (int z=0; z<max_z; z++)
    qsort(...);

    Thanks
    D
    bsder, Jul 14, 2005
    #1
    1. Advertising

  2. bsder

    Michael Mair Guest

    bsder wrote:
    > Hi,
    >
    > Can anyone please tell me how to calculate the size of the following
    > 4-dimensional array, and now to use qsort for sorting on this array?
    >
    > double sp[3] = { 4.0, 5.0, 6.0 };
    > double spa[3][2] = {
    > { 4.0, 2.0 },
    > { 5.0, 8.0 },
    > { 6.0, 6.0 },
    > };
    >
    > double spb[3][2][2] = {
    > { {1.0, 2.0}, {3.0, 4.0} },
    > { {5.0, 6.0}, {7.0, 8.0} },
    > { {9.0, 10.0 }, {11.0, 12.0} },
    > };
    >
    > // spc(Time, X, Y, Z)
    > double spc[3][1][1][1] = {
    > { {{1.0}} },
    > { {{5.0}} },
    > { {{9.0}} },
    > };


    Sizes:
    sizeof sp
    sizeof spa
    sizeof spb
    sizeof spc
    If you want the number of elements per first dimension, you can use
    sizeof sp/sizeof sp[0].

    >
    >
    > for (int t=0; t<max_time; t++)
    > for (int x=0; x<max_x; x++)
    > for (int y=0; y<max_y; y++)
    > for (int z=0; z<max_z; z++)
    > qsort(...);


    The problem is: How do you want to sort?
    You seem to want to sort along the highest dimension of spc:
    If yes, pass spc[t][x][y] to qsort() along with a comparison
    function for double* to achieve it.
    If no, define "order" on a n-dimensional array with all dimensions
    but one fixed or provide transformations to and from a 1D array
    along with appropriate comparison functions.

    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
    Michael Mair, Jul 14, 2005
    #2
    1. Advertising

  3. bsder

    bsder Guest

    Michael Mair wrote:
    > bsder wrote:
    >
    >> Hi,
    >>
    >> Can anyone please tell me how to calculate the size of the following
    >> 4-dimensional array, and now to use qsort for sorting on this array?
    >>
    >> double sp[3] = { 4.0, 5.0, 6.0 };
    >> double spa[3][2] = {
    >> { 4.0, 2.0 },
    >> { 5.0, 8.0 },
    >> { 6.0, 6.0 },
    >> };
    >>
    >> double spb[3][2][2] = {
    >> { {1.0, 2.0}, {3.0, 4.0} },
    >> { {5.0, 6.0}, {7.0, 8.0} },
    >> { {9.0, 10.0 }, {11.0, 12.0} },
    >> };
    >>
    >> // spc(Time, X, Y, Z)
    >> double spc[3][1][1][1] = {
    >> { {{1.0}} },
    >> { {{5.0}} },
    >> { {{9.0}} },
    >> };

    >
    >
    > Sizes:
    > sizeof sp
    > sizeof spa
    > sizeof spb
    > sizeof spc
    > If you want the number of elements per first dimension, you can use
    > sizeof sp/sizeof sp[0].
    >
    >>
    >>
    >> for (int t=0; t<max_time; t++)
    >> for (int x=0; x<max_x; x++)
    >> for (int y=0; y<max_y; y++)
    >> for (int z=0; z<max_z; z++)
    >> qsort(...);

    >
    >
    > The problem is: How do you want to sort?
    > You seem to want to sort along the highest dimension of spc:
    > If yes, pass spc[t][x][y] to qsort() along with a comparison
    > function for double* to achieve it.
    > If no, define "order" on a n-dimensional array with all dimensions
    > but one fixed or provide transformations to and from a 1D array
    > along with appropriate comparison functions.
    >
    > Cheers
    > Michael

    Hi, I wrote the following version of passing 4-dimensional array in to a
    function for printing, but there is an error when passing a
    4-dimensional array in to the function.
    Here is the code:

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

    void prn_sorted_distance(double *spc)
    {
    //qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
    }

    void prn_distance(double *spb)
    {
    register int a,b,c, t,x,y,z;
    x=y=z=0;
    double tmp_x, tmp_y, tmp_z, distance, total;
    int size_T = sizeof spb / sizeof spb[0];
    int size_X = sizeof spb[0] / sizeof spb[0][0];
    int size_Y = sizeof spb[0][0] / sizeof spb[0][0][0];
    int size_Z = sizeof spb[0][0][0] / sizeof spb[0][0][0][0];
    int x_co_ord, y_co_ord, z_co_ord;
    for ( t = 0; t < size_T; t++ ) {
    for ( x = 0; x < size_X; x++ ) {
    tmp_x = 100.00-spb[t][x][y][z];
    //printf("x: %6.1lf\n", spb[t][x][y][z]);
    for ( y = 0; y < size_Y; y++ ) {
    tmp_y = 100.00-spb[t][x][y][z];
    //printf("y: %6.1lf\n", spb[t][x][y][z]);
    for ( z = 0; z < size_Z; z++ ) {
    printf("z: %6.1lf; ", spb[t][x][y][z]);
    tmp_z = 100.00-spb[t][x][y][z];
    a = tmp_x * tmp_x;
    b = tmp_y * tmp_y;
    c = tmp_z * tmp_z;
    total = a + b + c;
    distance = sqrt(total);
    printf("distance: %6.1lf\n", distance);
    }
    }
    }
    }
    }

    int main()
    {
    double spb[3][1][1][1] = {
    { {{1.0}} },
    { {{5.0}} },
    { {{9.0}} },
    };

    prn_distance(&spb);
    //prn_sort_distance(spb);

    return 1;
    }

    I haven't implement the function for comparison. The comparison will be
    based on distance of two points. But I need to solve the array passing
    by reference first.

    Thanks
    D
    bsder, Jul 14, 2005
    #3
  4. On Thu, 14 Jul 2005 05:48:23 +0000, bsder wrote:

    > Hi,
    >
    > Can anyone please tell me how to calculate the size of the following
    > 4-dimensional array, and now to use qsort for sorting on this array?


    You'll need to explain what you mean by "sorting" a 4-dimensional array.
    Sorting is inherently a 1D process, there is no single way in which a 4D
    array might be considered "sorted".

    > double sp[3] = { 4.0, 5.0, 6.0 };
    > double spa[3][2] = {
    > { 4.0, 2.0 },
    > { 5.0, 8.0 },
    > { 6.0, 6.0 },
    > };
    >
    > double spb[3][2][2] = {
    > { {1.0, 2.0}, {3.0, 4.0} },
    > { {5.0, 6.0}, {7.0, 8.0} },
    > { {9.0, 10.0 }, {11.0, 12.0} },
    > };
    >
    > // spc(Time, X, Y, Z)
    > double spc[3][1][1][1] = {
    > { {{1.0}} },
    > { {{5.0}} },
    > { {{9.0}} },
    > };


    In this case it is fairly obvious because the array is degenerate: only
    one dimension has a size other then 1. Here you could write

    qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);

    This works when other dimensions are greater than 1, as long as you are
    just viewing the array as a 1D array of "rows" where each row happens to
    be an array in its own right. The comparison function will need to sort
    out the details of how to compare 2 complete rows in a valid way.

    Lawrence
    Lawrence Kirby, Jul 14, 2005
    #4
  5. bsder

    bsder Guest

    Lawrence Kirby wrote:
    > On Thu, 14 Jul 2005 05:48:23 +0000, bsder wrote:
    >
    >
    >>Hi,
    >>
    >>Can anyone please tell me how to calculate the size of the following
    >>4-dimensional array, and now to use qsort for sorting on this array?

    >
    >
    > You'll need to explain what you mean by "sorting" a 4-dimensional array.
    > Sorting is inherently a 1D process, there is no single way in which a 4D
    > array might be considered "sorted".
    >
    >
    >> double sp[3] = { 4.0, 5.0, 6.0 };
    >> double spa[3][2] = {
    >> { 4.0, 2.0 },
    >> { 5.0, 8.0 },
    >> { 6.0, 6.0 },
    >> };
    >>
    >> double spb[3][2][2] = {
    >> { {1.0, 2.0}, {3.0, 4.0} },
    >> { {5.0, 6.0}, {7.0, 8.0} },
    >> { {9.0, 10.0 }, {11.0, 12.0} },
    >> };
    >>
    >> // spc(Time, X, Y, Z)
    >> double spc[3][1][1][1] = {
    >> { {{1.0}} },
    >> { {{5.0}} },
    >> { {{9.0}} },
    >> };

    >
    >
    > In this case it is fairly obvious because the array is degenerate: only
    > one dimension has a size other then 1. Here you could write
    >
    > qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
    >
    > This works when other dimensions are greater than 1, as long as you are
    > just viewing the array as a 1D array of "rows" where each row happens to
    > be an array in its own right. The comparison function will need to sort
    > out the details of how to compare 2 complete rows in a valid way.
    >

    I feel abit trouble creating a "compare" function for the comparison of
    two different 2D arrays. Is there any simple example I can follow?

    Thanks
    D
    > Lawrence
    bsder, Jul 14, 2005
    #5
  6. bsder

    bsder Guest

    bsder wrote:
    > Lawrence Kirby wrote:
    >
    >> On Thu, 14 Jul 2005 05:48:23 +0000, bsder wrote:
    >>
    >>
    >>> Hi,
    >>>
    >>> Can anyone please tell me how to calculate the size of the following
    >>> 4-dimensional array, and now to use qsort for sorting on this array?

    >>
    >>
    >>
    >> You'll need to explain what you mean by "sorting" a 4-dimensional array.
    >> Sorting is inherently a 1D process, there is no single way in which a 4D
    >> array might be considered "sorted".
    >>
    >>
    >>> double sp[3] = { 4.0, 5.0, 6.0 };
    >>> double spa[3][2] = {
    >>> { 4.0, 2.0 },
    >>> { 5.0, 8.0 },
    >>> { 6.0, 6.0 },
    >>> };
    >>>
    >>> double spb[3][2][2] = {
    >>> { {1.0, 2.0}, {3.0, 4.0} },
    >>> { {5.0, 6.0}, {7.0, 8.0} },
    >>> { {9.0, 10.0 }, {11.0, 12.0} },
    >>> };
    >>>
    >>> // spc(Time, X, Y, Z)
    >>> double spc[3][1][1][1] = {
    >>> { {{1.0}} },
    >>> { {{5.0}} },
    >>> { {{9.0}} },
    >>> };

    >>
    >>
    >>
    >> In this case it is fairly obvious because the array is degenerate: only
    >> one dimension has a size other then 1. Here you could write
    >>
    >> qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
    >>
    >> This works when other dimensions are greater than 1, as long as you are
    >> just viewing the array as a 1D array of "rows" where each row happens to
    >> be an array in its own right. The comparison function will need to sort
    >> out the details of how to compare 2 complete rows in a valid way.
    >>

    >
    > I feel abit trouble creating a "compare" function for the comparison of
    > two different 2D arrays. Is there any simple example I can follow?
    >

    Here is what I got now:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>

    void prn_sorted_distance(double spc[][4], int n)
    {
    //qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
    printf("size_spc*: %d\n", sizeof *spc);
    qsort(spc, n, sizeof *spc, compare);
    }

    void prn_distance(double spb[][4], int n)
    {
    register int x,y,z, t,coor=0;
    double distance, total;
    int size_coor = sizeof spb[0] / sizeof spb[0][0];
    double tmp[size_coor];
    if (n == 0 || size_coor < 3)
    return;

    for ( t = 0; t < n; t++ ) {
    for ( coor = 0; coor < size_coor; coor++ ) {
    printf("point: %6.1lf; ", spb[t][coor]);
    tmp[coor] = 100.00-spb[t][coor];
    }
    x = tmp[0] * tmp[0];
    y = tmp[1] * tmp[1];
    z = tmp[2] * tmp[2];
    distance = sqrt(x+y+z);
    printf("distance: %6.1lf\n", distance);
    }
    }

    int main()
    {
    double spb[3][4] = {
    {1.0, 2.0, 1.0, 3.0},
    {8.0, 3.0, 12.0, 8.0},
    {4.0, 7.0, 2.0, 5.0}
    };

    int size_elem = sizeof spb / sizeof spb[0];
    prn_distance(spb, size_elem);
    printf("--------------------------\n");
    printf("size_spc: %d\n", sizeof spb/sizeof *spb);
    printf("size_spc*: %d\n", sizeof *spb);
    prn_sorted_distance(spb, size_elem);

    return 1;
    }

    Thanks
    > Thanks
    > D
    >
    >> Lawrence
    bsder, Jul 14, 2005
    #6
  7. bsder

    bsder Guest

    bsder wrote:
    > bsder wrote:
    >
    >> Lawrence Kirby wrote:
    >>
    >>> On Thu, 14 Jul 2005 05:48:23 +0000, bsder wrote:
    >>>
    >>>
    >>>> Hi,
    >>>>
    >>>> Can anyone please tell me how to calculate the size of the following
    >>>> 4-dimensional array, and now to use qsort for sorting on this array?
    >>>
    >>>
    >>>
    >>>
    >>> You'll need to explain what you mean by "sorting" a 4-dimensional array.
    >>> Sorting is inherently a 1D process, there is no single way in which a 4D
    >>> array might be considered "sorted".
    >>>
    >>>
    >>>> double sp[3] = { 4.0, 5.0, 6.0 };
    >>>> double spa[3][2] = {
    >>>> { 4.0, 2.0 },
    >>>> { 5.0, 8.0 },
    >>>> { 6.0, 6.0 },
    >>>> };
    >>>>
    >>>> double spb[3][2][2] = {
    >>>> { {1.0, 2.0}, {3.0, 4.0} },
    >>>> { {5.0, 6.0}, {7.0, 8.0} },
    >>>> { {9.0, 10.0 }, {11.0, 12.0} },
    >>>> };
    >>>>
    >>>> // spc(Time, X, Y, Z)
    >>>> double spc[3][1][1][1] = {
    >>>> { {{1.0}} },
    >>>> { {{5.0}} },
    >>>> { {{9.0}} },
    >>>> };
    >>>
    >>>
    >>>
    >>>
    >>> In this case it is fairly obvious because the array is degenerate: only
    >>> one dimension has a size other then 1. Here you could write
    >>>
    >>> qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
    >>>
    >>> This works when other dimensions are greater than 1, as long as you are
    >>> just viewing the array as a 1D array of "rows" where each row happens to
    >>> be an array in its own right. The comparison function will need to sort
    >>> out the details of how to compare 2 complete rows in a valid way.
    >>>

    >>
    >>
    >> I feel abit trouble creating a "compare" function for the comparison
    >> of two different 2D arrays. Is there any simple example I can follow?
    >>

    > Here is what I got now:
    > #include <stdio.h>
    > #include <stdlib.h>
    > #include <math.h>
    >
    > void prn_sorted_distance(double spc[][4], int n)
    > {
    > //qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
    > printf("size_spc*: %d\n", sizeof *spc);
    > qsort(spc, n, sizeof *spc, compare);
    > }
    >
    > void prn_distance(double spb[][4], int n)
    > {
    > register int x,y,z, t,coor=0;
    > double distance, total;
    > int size_coor = sizeof spb[0] / sizeof spb[0][0];
    > double tmp[size_coor];
    > if (n == 0 || size_coor < 3)
    > return;
    >
    > for ( t = 0; t < n; t++ ) {
    > for ( coor = 0; coor < size_coor; coor++ ) {
    > printf("point: %6.1lf; ", spb[t][coor]);
    > tmp[coor] = 100.00-spb[t][coor];
    > }
    > x = tmp[0] * tmp[0];
    > y = tmp[1] * tmp[1];
    > z = tmp[2] * tmp[2];
    > distance = sqrt(x+y+z);
    > printf("distance: %6.1lf\n", distance);
    > }
    > }
    >
    > int main()
    > {
    > double spb[3][4] = {
    > {1.0, 2.0, 1.0, 3.0},
    > {8.0, 3.0, 12.0, 8.0},
    > {4.0, 7.0, 2.0, 5.0}
    > };
    >
    > int size_elem = sizeof spb / sizeof spb[0];
    > prn_distance(spb, size_elem);
    > printf("--------------------------\n");
    > printf("size_spc: %d\n", sizeof spb/sizeof *spb);
    > printf("size_spc*: %d\n", sizeof *spb);
    > prn_sorted_distance(spb, size_elem);
    >
    > return 1;
    > }
    >

    I actually want to compare the distance of each row in this 2D array.

    > Thanks
    >
    >> Thanks
    >> D
    >>
    >>> Lawrence
    bsder, Jul 14, 2005
    #7
  8. In article <0VrBe.48530$>,
    bsder <> wrote:
    .... (mucho el code grande - snipped)
    >I haven't implement the function for comparison. The comparison will be
    >based on distance of two points. But I need to solve the array passing
    >by reference first.


    Thanks for keeping us posted. Good luck in your endeavors.

    >Thanks
    >D


    Oh, no, thank *you*! You've done all the work. We appreciate it.
    Kenny McCormack, Jul 14, 2005
    #8
  9. bsder

    bsder Guest

    Kenny McCormack wrote:
    > In article <0VrBe.48530$>,
    > bsder <> wrote:
    > ... (mucho el code grande - snipped)
    >
    >>I haven't implement the function for comparison. The comparison will be
    >>based on distance of two points. But I need to solve the array passing
    >>by reference first.

    >
    >
    > Thanks for keeping us posted. Good luck in your endeavors.
    >
    >
    >>Thanks
    >>D

    >
    >
    > Oh, no, thank *you*! You've done all the work. We appreciate it.
    >

    Execuse me, what do you meant?
    bsder, Jul 14, 2005
    #9
  10. bsder

    bsder Guest

    Hi,

    I finally written a full program with comparison in a 2-dimensional
    array. But the compilation is not successful. It appeared I didn't pass
    in the correct method "compare".
    Can anyone please point me to the direction how to correct this error?
    Here is the program:


    #include <stdlib.h>
    #include <math.h>

    int compare(const double *rowA, const double *rowB)
    {
    double diffA[3], diffB[3], distance[2];
    diffA[0] = 100.0 - *rowA+1;
    diffA[1] = 100.0 - *rowA+2;
    diffA[2] = 100.0 - *rowA+3;

    diffA[0] = 100.0 - *rowB+1;
    diffA[1] = 100.0 - *rowB+2;
    diffA[2] = 100.0 - *rowB+3;

    distance[0] = sqrt(diffA[0]+diffA[1]+diffA[2]);
    distance[1] = sqrt(diffB[0]+diffB[1]+diffB[2]);

    return 0 ? distance[0] > distance[1] : 1;
    }

    void prn_sorted_distance(double spc[][4], int n)
    {
    //qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
    printf("size_spc*: %d\n", sizeof *spc);
    qsort(spc, n, sizeof *spc, compare);
    prn_distance(spb, n);
    }

    void prn_distance(double spb[][4], int n)
    {
    register int x,y,z, t,coor=0;
    double distance;
    int size_coor = sizeof spb[0] / sizeof spb[0][0];
    double tmp[size_coor];
    if (n == 0 || size_coor < 3)
    return;

    for ( t = 0; t < n; t++ ) {
    for ( coor = 0; coor < size_coor; coor++ ) {
    printf("point: %6.1lf; ", spb[t][coor]);
    tmp[coor] = 100.00-spb[t][coor];
    }
    x = tmp[0] * tmp[0];
    y = tmp[1] * tmp[1];
    z = tmp[2] * tmp[2];
    distance = sqrt(x+y+z);
    printf("distance: %6.1lf\n", distance);
    }
    }

    int main()
    {
    double spb[3][4] = {
    {1.0, 2.0, 1.0, 3.0},
    {8.0, 3.0, 12.0, 8.0},
    {4.0, 7.0, 2.0, 5.0}
    };

    int size_elem = sizeof spb / sizeof spb[0];
    prn_distance(spb, size_elem);
    printf("--------------------------\n");
    printf("size_spc: %d\n", sizeof spb/sizeof *spb);
    printf("size_spc*: %d\n", sizeof *spb);
    prn_sorted_distance(spb, size_elem);

    return 1;
    }

    Thanks
    D
    bsder, Jul 14, 2005
    #10
  11. In article <kluBe.48654$>,
    bsder <> wrote:
    ....
    >Thanks
    >D


    You're welcome!
    Kenny McCormack, Jul 14, 2005
    #11
  12. bsder

    bsder Guest

    Hi,

    After made an attempt to change the function "compare", I still can't
    get the sorting workout correctly.
    Here is the code:

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

    int compare(const double *rowA, const double *rowB)
    {
    double diffA[3], diffB[3], distance[2];
    printf("DA1_row: %6.1lf\n", rowA[1]);
    printf("DA2_row: %6.1lf\n", rowA[2]);
    printf("DA3_row: %6.1lf\n\n", rowA[3]);
    printf("DB1_row: %6.1lf\n", rowB[1]);
    printf("DB2_row: %6.1lf\n", rowB[2]);
    printf("DB3_row: %6.1lf\n\n", rowB[3]);

    diffA[0] = 100.0 - rowA[1];
    diffA[1] = 100.0 - rowA[2];
    diffA[2] = 100.0 - rowA[3];

    diffB[0] = 100.0 - rowB[1];
    diffB[1] = 100.0 - rowB[2];
    diffB[2] = 100.0 - rowB[3];

    distance[0] =
    sqrt(diffA[0]*diffA[0]+diffA[1]*diffA[1]+diffA[2]*diffA[2]);
    distance[1] =
    sqrt(diffB[0]*diffB[0]+diffB[1]*diffB[1]+diffB[2]*diffB[2]);

    printf("Comp_p1: %6.1lf; ", distance[0]);
    printf("Comp_p2: %6.1lf\n", distance[1]);

    return 1 ? distance[0] > distance[1] : 0;
    }
    void prn_distance(double spb[][4], int n)
    {
    register int x,y,z, t,coor=0;
    double distance;
    int size_coor = sizeof spb[0] / sizeof spb[0][0];
    double tmp[size_coor];
    if (n == 0 || size_coor < 3)
    return;

    for ( t = 0; t < n; t++ ) {
    for ( coor = 0; coor < size_coor; coor++ ) {
    printf("point: %6.1lf; ", spb[t][coor]);
    tmp[coor] = 100.00-spb[t][coor];
    }
    x = tmp[0] * tmp[0];
    y = tmp[1] * tmp[1];
    z = tmp[2] * tmp[2];
    distance = sqrt(x+y+z);
    printf("distance: %6.1lf\n", distance);
    }
    }

    void prn_sorted_distance(double spc[][4], int n)
    {
    //qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
    printf("size_spc*: %d\n", sizeof *spc);
    qsort(spc, n, sizeof *spc, (int (*)(const void *, const void
    *))compare);
    prn_distance(spc, n);
    }

    int main()
    {
    double spb[5][4] = {
    {1.0, 2.0, 1.0, 3.0},
    {8.0, 3.0, 12.0, 8.0},
    {4.0, 7.0, 2.0, 5.0},
    {8.0, 1.0, 2.0, 1.0},
    {9.0, 92.0, 81.0, 93.0}
    };

    int size_elem = sizeof spb / sizeof spb[0];
    prn_distance(spb, size_elem);
    printf("--------------------------\n");
    printf("size_spc: %d\n", sizeof spb/sizeof *spb);
    printf("size_spc*: %d\n", sizeof *spb);
    prn_sorted_distance(spb, size_elem);

    return 1;
    }

    D
    bsder, Jul 14, 2005
    #12
  13. On Thu, 14 Jul 2005 14:08:16 +0000, bsder wrote:

    > Hi,
    >
    > I finally written a full program with comparison in a 2-dimensional
    > array. But the compilation is not successful. It appeared I didn't pass
    > in the correct method "compare".


    compare isn't a method, it is a function.

    > Can anyone please point me to the direction how to correct this error?
    > Here is the program:
    >
    >
    > #include <stdlib.h>
    > #include <math.h>


    You need to include <stdio.h> because you use printf().

    > int compare(const double *rowA, const double *rowB)
    > {


    qsort() requires a comparison function that takes 2 const void *
    arguments, you've defined one that take 2 const double * arguments i.e.
    your function does not meet the specification. If you wanted to sort an
    array of doubles you might write:

    int compare(const void *vA, const void *vB)
    {
    const double *rowA = vA;
    const double *rowB = vB;

    But looking below you're not doing that, you're trying to sort an array
    of arrays of double. The first argument you pass to qsort() has type
    pointer to an array of 4 doubles or double (*)[4] i.e. the elements to be
    sorted each have type array of 4 doubles. qsort() passes a pointer to the
    element converted to void *, and that is the type you need to convert back
    to:

    int compare(const void *vA, const void *vB)
    {
    const double *rowA = *(const double (*)[4])vA;
    const double *rowB = *(const double (*)[4])vB;

    The cast converts to the correct pointer to array type, this pointer is
    then dereferenced to give the element to be compared (an array), that
    array is then automatically converted to a pointer to its first element
    which is assigned.

    > double diffA[3], diffB[3], distance[2];
    > diffA[0] = 100.0 - *rowA+1;
    > diffA[1] = 100.0 - *rowA+2;
    > diffA[2] = 100.0 - *rowA+3;
    >
    > diffA[0] = 100.0 - *rowB+1;
    > diffA[1] = 100.0 - *rowB+2;
    > diffA[2] = 100.0 - *rowB+3;


    Should these be diffB? Do you mean rowA[1] etc.?

    > distance[0] = sqrt(diffA[0]+diffA[1]+diffA[2]);
    > distance[1] = sqrt(diffB[0]+diffB[1]+diffB[2]);


    Should those be sums of squares? Also sqrt() is pointless here because it
    won't change the relative ordering of the 2 values except for limits of
    accuracy issues.

    > return 0 ? distance[0] > distance[1] : 1;


    Did you mean

    return distance[0] > distance[1] ? 0 : 1;

    > }


    This isn't a valid comparison function. A valid comparison function must
    produce a consistent total ordering of the array elements. For example if
    X > Y then Y < X. Since this function never returns a value < 0 that is
    clearly not the case for this function.

    It would be a lot safer (and quite probably faster) to generate a separate
    array of "distance" values, or square of distance values, and then sort on
    that.

    > }
    > void prn_sorted_distance(double spc[][4], int n) {
    > //qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
    > printf("size_spc*: %d\n", sizeof *spc);


    the result of sizeof has type size_t, not int, so it is not valid to use a
    %d conversion specifier for it. A simple fix is:

    printf("size_spc*: %d\n", (int)sizeof *spc);

    > qsort(spc, n, sizeof *spc, compare);


    Correct, your commented out version is invalid because spc isn't an array,
    it is a pointer. You cannot pass arrays as function arguments in C, the
    true type of spc is double (*)[4] i.e. a pointer to an array of 4 doubles.

    > prn_distance(spb, n);
    > }
    > }
    > void prn_distance(double spb[][4], int n) {
    > register int x,y,z, t,coor=0;
    > double distance;
    > int size_coor = sizeof spb[0] / sizeof spb[0][0]; double
    > tmp[size_coor];
    > if (n == 0 || size_coor < 3)
    > return;
    >
    > for ( t = 0; t < n; t++ ) {
    > for ( coor = 0; coor < size_coor; coor++ ) {
    > printf("point: %6.1lf; ", spb[t][coor]); tmp[coor] =
    > 100.00-spb[t][coor];
    > }
    > x = tmp[0] * tmp[0];
    > y = tmp[1] * tmp[1];
    > z = tmp[2] * tmp[2];
    > distance = sqrt(x+y+z);
    > printf("distance: %6.1lf\n", distance);
    > }
    > }
    > }
    > int main()
    > {
    > double spb[3][4] = {
    > {1.0, 2.0, 1.0, 3.0},
    > {8.0, 3.0, 12.0, 8.0},
    > {4.0, 7.0, 2.0, 5.0}
    > };
    >
    > int size_elem = sizeof spb / sizeof spb[0]; prn_distance(spb,
    > size_elem);
    > printf("--------------------------\n");
    > printf("size_spc: %d\n", sizeof spb/sizeof *spb); printf("size_spc*:
    > %d\n", sizeof *spb);
    > prn_sorted_distance(spb, size_elem);
    >
    > return 1;


    There are 3 portable values you can return from the initial invocation of
    main(): 0, EXIT_SUCCESS and EXIT_FAILURE. The first 2 indicate success,
    the last 2 are macros defined in <stdlib.h>.

    Lawrence
    Lawrence Kirby, Jul 14, 2005
    #13
  14. On Thu, 14 Jul 2005 11:21:32 GMT, bsder <> wrote:

    snip 50+ irrelevant lines. Please trim your quotes.

    >Hi, I wrote the following version of passing 4-dimensional array in to a
    > function for printing, but there is an error when passing a
    >4-dimensional array in to the function.
    >Here is the code:
    >
    >#include <stdio.h>
    >#include <stdlib.h>
    >#include <math.h>
    >
    >void prn_sorted_distance(double *spc)
    >{
    > //qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
    >}
    >
    >void prn_distance(double *spb)


    Here you say the function will receive a pointer to double.

    >{
    > register int a,b,c, t,x,y,z;
    > x=y=z=0;
    > double tmp_x, tmp_y, tmp_z, distance, total;
    > int size_T = sizeof spb / sizeof spb[0];


    Since spb is a pointer to double, spb[0] is a double (spb is
    dereferenced).

    Unfortunately, sizeof spb evaluates to the size of the pointer, not
    the size of the array it points to. There is no way generic technique
    that can be used inside a function to determine the size of an array
    that is passed as an argument. Common techniques used to get around
    this limitation are 1) to pass the size as a parameter, to use a
    #define macro or a global enum value for the size, and 3) to use a
    sentinel value in the array that signals the end of the data.

    Since you obviously intend to pass a 4D array, define the function
    exactly that way. It is true that the argument will automatically be
    converted to a pointer by the compiler, but in this case it will have
    type pointer to 3D array. Based on the array in main, the function
    should look like
    void prn_distance(double spb[3][1][1][1])
    but you can replace the [3] with just []. (The first dimension of an
    array parameter can be omitted.) Within the function, spb would have
    type double (*)[1][1][1]. All of your size expressions will work
    correctly except the first one. sizeof spb is still the size of the
    pointer but now sizeof spb[0] is the size of the (first) array spb
    points to. You still need some other technique for determining the
    first dimension.

    > int size_X = sizeof spb[0] / sizeof spb[0][0];


    This is a syntax error. spb[0][0] is not a valid expression. You
    cannot dereference a double.

    > int size_Y = sizeof spb[0][0] / sizeof spb[0][0][0];
    > int size_Z = sizeof spb[0][0][0] / sizeof spb[0][0][0][0];
    > int x_co_ord, y_co_ord, z_co_ord;
    > for ( t = 0; t < size_T; t++ ) {
    > for ( x = 0; x < size_X; x++ ) {
    > tmp_x = 100.00-spb[t][x][y][z];
    > //printf("x: %6.1lf\n", spb[t][x][y][z]);
    > for ( y = 0; y < size_Y; y++ ) {
    > tmp_y = 100.00-spb[t][x][y][z];
    > //printf("y: %6.1lf\n", spb[t][x][y][z]);
    > for ( z = 0; z < size_Z; z++ ) {
    > printf("z: %6.1lf; ", spb[t][x][y][z]);
    > tmp_z = 100.00-spb[t][x][y][z];
    > a = tmp_x * tmp_x;
    > b = tmp_y * tmp_y;
    > c = tmp_z * tmp_z;
    > total = a + b + c;
    > distance = sqrt(total);
    > printf("distance: %6.1lf\n", distance);
    > }
    > }
    > }
    > }
    >}
    >
    >int main()
    >{
    > double spb[3][1][1][1] = {
    > { {{1.0}} },
    > { {{5.0}} },
    > { {{9.0}} },
    > };


    spb is a 4D array of double.

    >
    > prn_distance(&spb);


    You are passing prn_distance a pointer to a 4D array of double. This
    is also a syntax error since you promised that you would pass a
    (simple) pointer to double. These two types of pointers are not at
    all compatible.

    If you change prn_distance as described above and remove the & here,
    the types will match.

    > //prn_sort_distance(spb);
    >
    > return 1;
    >}
    >
    >I haven't implement the function for comparison. The comparison will be
    >based on distance of two points. But I need to solve the array passing
    >by reference first.


    C does not pass by reference, it passes by value. In the case of an
    array, that value is the address of the first element.


    <<Remove the del for email>>
    Barry Schwarz, Jul 15, 2005
    #14
  15. On Thu, 14 Jul 2005 14:08:16 GMT, bsder <> wrote:

    >Hi,
    >
    >I finally written a full program with comparison in a 2-dimensional
    >array. But the compilation is not successful. It appeared I didn't pass
    >in the correct method "compare".


    compare is a function. C does not have methods in the sense that C++
    does.

    >Can anyone please point me to the direction how to correct this error?
    >Here is the program:
    >
    >
    >#include <stdlib.h>
    >#include <math.h>
    >
    >int compare(const double *rowA, const double *rowB)


    The compare function you pass to qsort must accept two pointers of
    type const void*. You can later assign these pointers to pointers of
    the correct/desired type within the function but not in the function
    header
    ..
    >{
    > double diffA[3], diffB[3], distance[2];
    > diffA[0] = 100.0 - *rowA+1;
    > diffA[1] = 100.0 - *rowA+2;
    > diffA[2] = 100.0 - *rowA+3;
    >
    > diffA[0] = 100.0 - *rowB+1;
    > diffA[1] = 100.0 - *rowB+2;
    > diffA[2] = 100.0 - *rowB+3;


    You probably meant diffB here since otherwise you lose the first three
    values.

    >
    > distance[0] = sqrt(diffA[0]+diffA[1]+diffA[2]);
    > distance[1] = sqrt(diffB[0]+diffB[1]+diffB[2]);
    >
    > return 0 ? distance[0] > distance[1] : 1;


    You have the operands of the ?: operator out of order. Furthermore,
    you need to be able to return three possible values: -1, 0, +1.

    >}
    >
    >void prn_sorted_distance(double spc[][4], int n)
    >{
    > //qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
    >printf("size_spc*: %d\n", sizeof *spc);
    > qsort(spc, n, sizeof *spc, compare);
    > prn_distance(spb, n);
    >}
    >
    >void prn_distance(double spb[][4], int n)
    >{
    > register int x,y,z, t,coor=0;
    > double distance;
    > int size_coor = sizeof spb[0] / sizeof spb[0][0];
    > double tmp[size_coor];
    > if (n == 0 || size_coor < 3)
    > return;
    >
    > for ( t = 0; t < n; t++ ) {
    > for ( coor = 0; coor < size_coor; coor++ ) {
    > printf("point: %6.1lf; ", spb[t][coor]);
    > tmp[coor] = 100.00-spb[t][coor];
    > }
    > x = tmp[0] * tmp[0];
    > y = tmp[1] * tmp[1];
    > z = tmp[2] * tmp[2];
    > distance = sqrt(x+y+z);
    > printf("distance: %6.1lf\n", distance);
    > }
    >}
    >
    >int main()
    >{
    > double spb[3][4] = {
    > {1.0, 2.0, 1.0, 3.0},
    > {8.0, 3.0, 12.0, 8.0},
    > {4.0, 7.0, 2.0, 5.0}
    > };
    >
    > int size_elem = sizeof spb / sizeof spb[0];
    > prn_distance(spb, size_elem);
    > printf("--------------------------\n");
    >printf("size_spc: %d\n", sizeof spb/sizeof *spb);
    >printf("size_spc*: %d\n", sizeof *spb);
    > prn_sorted_distance(spb, size_elem);
    >
    > return 1;
    >}
    >
    >Thanks
    >D




    <<Remove the del for email>>
    Barry Schwarz, Jul 15, 2005
    #15
  16. On Thu, 14 Jul 2005 15:08:51 GMT, bsder <> wrote:

    >Hi,
    >
    >After made an attempt to change the function "compare", I still can't
    >get the sorting workout correctly.
    >Here is the code:
    >
    >#include <stdio.h>
    >#include <stdlib.h>
    >#include <math.h>
    >
    >int compare(const double *rowA, const double *rowB)
    >{
    > double diffA[3], diffB[3], distance[2];
    > printf("DA1_row: %6.1lf\n", rowA[1]);
    > printf("DA2_row: %6.1lf\n", rowA[2]);
    > printf("DA3_row: %6.1lf\n\n", rowA[3]);


    What about rowA[0]?

    > printf("DB1_row: %6.1lf\n", rowB[1]);
    > printf("DB2_row: %6.1lf\n", rowB[2]);
    > printf("DB3_row: %6.1lf\n\n", rowB[3]);
    >
    > diffA[0] = 100.0 - rowA[1];
    > diffA[1] = 100.0 - rowA[2];
    > diffA[2] = 100.0 - rowA[3];
    >
    > diffB[0] = 100.0 - rowB[1];
    > diffB[1] = 100.0 - rowB[2];
    > diffB[2] = 100.0 - rowB[3];
    >
    > distance[0] =
    >sqrt(diffA[0]*diffA[0]+diffA[1]*diffA[1]+diffA[2]*diffA[2]);
    > distance[1] =
    >sqrt(diffB[0]*diffB[0]+diffB[1]*diffB[1]+diffB[2]*diffB[2]);
    >
    > printf("Comp_p1: %6.1lf; ", distance[0]);
    > printf("Comp_p2: %6.1lf\n", distance[1]);
    >
    > return 1 ? distance[0] > distance[1] : 0;
    >}
    >void prn_distance(double spb[][4], int n)
    >{
    > register int x,y,z, t,coor=0;
    > double distance;
    > int size_coor = sizeof spb[0] / sizeof spb[0][0];
    > double tmp[size_coor];
    > if (n == 0 || size_coor < 3)
    > return;
    >
    > for ( t = 0; t < n; t++ ) {
    > for ( coor = 0; coor < size_coor; coor++ ) {
    > printf("point: %6.1lf; ", spb[t][coor]);
    > tmp[coor] = 100.00-spb[t][coor];
    > }
    > x = tmp[0] * tmp[0];
    > y = tmp[1] * tmp[1];
    > z = tmp[2] * tmp[2];
    > distance = sqrt(x+y+z);
    > printf("distance: %6.1lf\n", distance);
    > }
    >}
    >
    >void prn_sorted_distance(double spc[][4], int n)
    >{
    > //qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
    >printf("size_spc*: %d\n", sizeof *spc);
    > qsort(spc, n, sizeof *spc, (int (*)(const void *, const void
    >*))compare);
    > prn_distance(spc, n);
    >}
    >
    >int main()
    >{
    > double spb[5][4] = {
    > {1.0, 2.0, 1.0, 3.0},
    > {8.0, 3.0, 12.0, 8.0},
    > {4.0, 7.0, 2.0, 5.0},
    > {8.0, 1.0, 2.0, 1.0},
    > {9.0, 92.0, 81.0, 93.0}
    > };
    >
    > int size_elem = sizeof spb / sizeof spb[0];
    > prn_distance(spb, size_elem);
    > printf("--------------------------\n");
    >printf("size_spc: %d\n", sizeof spb/sizeof *spb);
    >printf("size_spc*: %d\n", sizeof *spb);
    > prn_sorted_distance(spb, size_elem);
    >
    > return 1;
    >}
    >
    >D




    <<Remove the del for email>>
    Barry Schwarz, Jul 15, 2005
    #16
  17. bsder

    Artie Gold Guest

    Barry Schwarz wrote:
    > On Thu, 14 Jul 2005 15:08:51 GMT, bsder <> wrote:
    >
    >> Hi,
    >>
    >> After made an attempt to change the function "compare", I still can't
    >> get the sorting workout correctly.
    >> Here is the code:
    >>
    >> #include <stdio.h>
    >> #include <stdlib.h>
    >> #include <math.h>
    >>
    >> int compare(const double *rowA, const double *rowB)

    This function should take `const void *'s; use them as initializers for
    variables of the appropriate type.
    >> {
    >> double diffA[3], diffB[3], distance[2];
    >> printf("DA1_row: %6.1lf\n", rowA[1]);
    >> printf("DA2_row: %6.1lf\n", rowA[2]);
    >> printf("DA3_row: %6.1lf\n\n", rowA[3]);

    >
    > What about rowA[0]?
    >
    >> printf("DB1_row: %6.1lf\n", rowB[1]);
    >> printf("DB2_row: %6.1lf\n", rowB[2]);
    >> printf("DB3_row: %6.1lf\n\n", rowB[3]);
    >>
    >> diffA[0] = 100.0 - rowA[1];
    >> diffA[1] = 100.0 - rowA[2];
    >> diffA[2] = 100.0 - rowA[3];
    >>
    >> diffB[0] = 100.0 - rowB[1];
    >> diffB[1] = 100.0 - rowB[2];
    >> diffB[2] = 100.0 - rowB[3];
    >>
    >> distance[0] =
    >> sqrt(diffA[0]*diffA[0]+diffA[1]*diffA[1]+diffA[2]*diffA[2]);
    >> distance[1] =
    >> sqrt(diffB[0]*diffB[0]+diffB[1]*diffB[1]+diffB[2]*diffB[2]);
    >>
    >> printf("Comp_p1: %6.1lf; ", distance[0]);
    >> printf("Comp_p2: %6.1lf\n", distance[1]);
    >>
    >> return 1 ? distance[0] > distance[1] : 0;


    You realize, of course, that the above line is equivalent to

    return distance[0] > distance[1];

    [IOW, it's not what you want. You also need to revisit what it is the
    qsort() function expects in terms of the semantics of the comparison
    function.]
    >> }
    >> void prn_distance(double spb[][4], int n)
    >> {
    >> register int x,y,z, t,coor=0;
    >> double distance;
    >> int size_coor = sizeof spb[0] / sizeof spb[0][0];


    `size_coor' will always be 4, your function signature says so.
    >> double tmp[size_coor];
    >> if (n == 0 || size_coor < 3)
    >> return;
    >>
    >> for ( t = 0; t < n; t++ ) {
    >> for ( coor = 0; coor < size_coor; coor++ ) {
    >> printf("point: %6.1lf; ", spb[t][coor]);
    >> tmp[coor] = 100.00-spb[t][coor];
    >> }
    >> x = tmp[0] * tmp[0];
    >> y = tmp[1] * tmp[1];
    >> z = tmp[2] * tmp[2];
    >> distance = sqrt(x+y+z);
    >> printf("distance: %6.1lf\n", distance);
    >> }
    >> }
    >>
    >> void prn_sorted_distance(double spc[][4], int n)
    >> {
    >> //qsort(spc, sizeof spc/sizeof *spc, sizeof *spc, compare);
    >> printf("size_spc*: %d\n", sizeof *spc);
    >> qsort(spc, n, sizeof *spc, (int (*)(const void *, const void
    >> *))compare);

    Ugly cast. Write your `compare' function as expected by qsort -- it's
    what void *s are *for*!

    >> prn_distance(spc, n);
    >> }
    >>
    >> int main()
    >> {
    >> double spb[5][4] = {
    >> {1.0, 2.0, 1.0, 3.0},
    >> {8.0, 3.0, 12.0, 8.0},
    >> {4.0, 7.0, 2.0, 5.0},
    >> {8.0, 1.0, 2.0, 1.0},
    >> {9.0, 92.0, 81.0, 93.0}
    >> };
    >>
    >> int size_elem = sizeof spb / sizeof spb[0];

    In this expression, you'll get the right answer
    >> prn_distance(spb, size_elem);
    >> printf("--------------------------\n");
    >> printf("size_spc: %d\n", sizeof spb/sizeof *spb);
    >> printf("size_spc*: %d\n", sizeof *spb);
    >> prn_sorted_distance(spb, size_elem);
    >>
    >> return 1;

    Why are you returning 1? It's a non-standard return value --
    particularly if you think that getting this far means something failed.
    >> }


    Have you (OP) got a good text?

    HTH,
    --ag

    --
    Artie Gold -- Austin, Texas
    http://it-matters.blogspot.com (new post 12/5)
    http://www.cafepress.com/goldsays
    Artie Gold, Jul 15, 2005
    #17
  18. bsder

    bsder Guest

    Artie Gold wrote:
    > Barry Schwarz wrote:
    > ....


    > In this expression, you'll get the right answer
    >
    >>> prn_distance(spb, size_elem);
    >>> printf("--------------------------\n");
    >>> printf("size_spc: %d\n", sizeof spb/sizeof *spb);
    >>> printf("size_spc*: %d\n", sizeof *spb);
    >>> prn_sorted_distance(spb, size_elem);
    >>>
    >>> return 1;

    >
    > Why are you returning 1? It's a non-standard return value --
    > particularly if you think that getting this far means something failed.
    >

    should it be exit(0) or return 0?

    Thanks
    D
    >>> }

    >
    >
    > Have you (OP) got a good text?
    >
    > HTH,
    > --ag
    >
    bsder, Jul 15, 2005
    #18
  19. bsder

    Michael Mair Guest

    bsder wrote:
    > Artie Gold wrote:
    >
    >> Barry Schwarz wrote:
    >> ....

    >
    >
    >> In this expression, you'll get the right answer
    >>
    >>>> prn_distance(spb, size_elem);
    >>>> printf("--------------------------\n");
    >>>> printf("size_spc: %d\n", sizeof spb/sizeof *spb);
    >>>> printf("size_spc*: %d\n", sizeof *spb);
    >>>> prn_sorted_distance(spb, size_elem);
    >>>>
    >>>> return 1;

    >>
    >> Why are you returning 1? It's a non-standard return value --
    >> particularly if you think that getting this far means something failed.
    >>

    > should it be exit(0) or return 0?


    exit() needs <stdlib.h> and has well-defined portable semantics for
    0, EXIT_SUCCESS, EXIT_FAILURE
    If you want to exit with success from anywhere but main() and are
    sure that this is a Good Thing, then use exit(0) or exit(EXIT_SUCCESS).
    If you want to exit indicating a failure and are sure that you have
    done everything you can do in terms of error handling, then use
    exit(EXIT_FAILURE); sometimes, a message to stderr and going on as
    good as possible may be better than killing a program after 99% of
    a longish computation.
    At the end of main(), I would use exit(EXIT_SUCCESS)/exit(0) only
    if I used exit(EXIT_FAILURE) somewhere else in the program and felt
    the need to actively exit() the program.

    These are only rough rules of thumb to get started and by no means
    exhaustive.


    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
    Michael Mair, Jul 15, 2005
    #19
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Venkat
    Replies:
    4
    Views:
    959
    Venkat
    Dec 5, 2003
  2. Nancy Keuss
    Replies:
    4
    Views:
    16,237
    Jeff Schwab
    Jan 13, 2004
  3. Replies:
    2
    Views:
    376
    Knute Johnson
    Jan 24, 2007
  4. bsder

    qsort on multi-dimensional array

    bsder, Jul 14, 2005, in forum: C Programming
    Replies:
    1
    Views:
    430
    Charles Mills
    Jul 14, 2005
  5. Wirianto Djunaidi
    Replies:
    2
    Views:
    194
    Wirianto Djunaidi
    Apr 29, 2008
Loading...

Share This Page