Home > Net >  Is there someway to sort a structure while passing it in a void function using pointers only?
Is there someway to sort a structure while passing it in a void function using pointers only?

Time:10-04

I'm trying to sort some random points and the distance of the points from a user input point (consider it to be (0,0) i.e. the origin) on an XY coordinate system in a sort function by using pointers, when I remove the points sorting code from the sort function then distance sorting is fine, but when I try to sort the points as well as the distance the code doesn't work. I know a similar question about sorting points has been asked but I know the logic I want to implement it using pointers only. Could someone help?

Code

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

struct point {
    float x, y;
};

void sort();

int main() {
    int n;
    printf("Enter the number of points in the system:");
    scanf("%d", &n);
    float d[n], xi, yi;
    struct point p[n];
    printf("\nEnter the X and Y coordinates of the points-\n");
    
    for (int i = 0; i < n; i  ) {
        printf("Enter the X coordinate of point %d: ", i   1);
        scanf("%f", &p[i].x);
        printf("Enter the Y coordinate of point %d: ", i   1);
        scanf("%f", &p[i].y);
    }
    
    printf("\nPoints entered are-\n");
    
    for (int i = 0; i < n; i  ) {
        printf("%d- (%0.2f,%0.2f)\n", i   1, p[i].x, p[i].y);
    }
    
    printf("\nEnter the X coordinate of point from which distance is to be calculated:");
    scanf("%f", &xi);
    printf("Enter the Y coordinate of point from which distance is to be calculated:");
    scanf("%f", &yi);
    
    for (int i = 0; i < n; i  ) {
        d[i] = fabs(sqrt(pow(((p[i].x) - xi), 2)   pow(((p[i].y) - yi), 2)));
    }
    
    printf("\nDistance- ");
    
    for (int i = 0; i < n; i  ) {
        printf("%0.2f  ", d[i]);
    }
    
    printf("\n");
    sort(d);
    printf("\n\nSorted distance- ");
    
    for (int i = 0; i < n; i  ) {
        printf("%0.2f  ", d[i]);
    }
    
    printf("\n\n");
    
    for (int i = 0; i < n; i  ) {
        printf("%d- (%0.2f,%0.2f)\n", i   1, p[i].x, p[i].y);
    }
}

void sort(float *d, struct point *p) {
    for (int i = 0; i < sizeof(d) / sizeof(float); i  ) {
        for (int j = 1; j < (sizeof(d) / sizeof(float)) - i; j  ) {
            if (*(d   i) > *(d   i   j)) {
                float temp = *(d   i), pxtemp = (p   i)->x, pytemp = (p   i)->y;            
                *(d   i) = *(d   i   j);                                              
                *(d   i   j) = temp;
                /*(p   i)->x = (p   i   j)->x;
                (p   i   j)->x = pxtemp;
                (p   i)->y = (p   i   j)->y;
                (p   i   j)->y = pytemp;*/
            }
        }
    }
}

Output

Enter the number of points in the system:2

Enter the X and Y coordinates of the points-
Enter the X coordinate of point 1: 5
Enter the Y coordinate of point 1: 6
Enter the X coordinate of point 2: 3
Enter the Y coordinate of point 2: 4

Points entered are-
1- (5.00,6.00)
2- (3.00,4.00)

Enter the X coordinate of point from which distance is to be calculated:0
Enter the Y coordinate of point from which distance is to be calculated:0

Distance- 7.81  5.00

CodePudding user response:

There are multiple problems in the code:

  • you do not pass p to the sort function.
  • in this sort function, sizeof(d) / sizeof(float) does not evaluate to the number of entries in the array pointed to by d because d is just a pointer. You must pass the length of the arrays n as an extra argument.
#include <math.h>
#include <stdio.h>

struct point {
    float x, y;
};

void sort(float *d, struct point *p, int n) {
    for (int i = 1; i < n; i  ) {
        for (int j = 0; j < n - i; j  ) {
            if (d[i] > d[i   1]) {
                float temp = d[i];
                d[i] = d[i   1];
                d[i   1] = temp;
                struct point temp1 = p[i];
                p[i] = p[i   1];
                p[i   1] = temp1;
            }
        }
    }
}

int main() {
    int n;
    printf("Enter the number of points in the system:");
    if (scanf("%d", &n) != 1 || n < 1)
        return 1;
    float d[n], xi, yi;
    struct point p[n];
    printf("\nEnter the X and Y coordinates of the points-\n");
    
    for (int i = 0; i < n; i  ) {
        printf("Enter the X coordinate of point %d: ", i   1);
        if (scanf("%f", &p[i].x) != 1)
            return 1;
        printf("Enter the Y coordinate of point %d: ", i   1);
        if (scanf("%f", &p[i].y) != 1)
            return 1;
    }
    
    printf("\nPoints entered are-\n");
    
    for (int i = 0; i < n; i  ) {
        printf("%d- (%0.2f,%0.2f)\n", i   1, p[i].x, p[i].y);
    }
    
    printf("\nEnter the X coordinate of point from which distance is to be calculated:");
    if (scanf("%f", &xi) != 1)
        return 1;
    printf("Enter the Y coordinate of point from which distance is to be calculated:");
    if (scanf("%f", &yi) != 1)
        return 1;
    
    for (int i = 0; i < n; i  ) {
        // use hypot() to compute the distance between 2 points
        // it has better behavior than sqrt(dx2   dy2) in corner cases.
        d[i] = hypot(p[i].x - xi, p[i].y - yi);
    }
    printf("\n");

    printf("Distance- ");
    for (int i = 0; i < n; i  ) {
        printf("%0.2f  ", d[i]);
    }
    printf("\n");

    sort(d, p, n);

    printf("\n\nSorted distance- ");
    for (int i = 0; i < n; i  ) {
        printf("%0.2f  ", d[i]);
    }
    printf("\n\n");
    
    for (int i = 0; i < n; i  ) {
        printf("%d- (%0.2f,%0.2f)\n", i   1, p[i].x, p[i].y);
    }
    return 0;
}

CodePudding user response:

Declare your function with all input parameters:

void sort(float *d,struct point *p);

And use both parameters when you call it:

sort(d, p);

Afterwards it seems to work fine, test here.

Also, as Konrad Rudolph correctly pointed out, you need to pass the length of your array to the function, to use the correct length on your for-loops. They are also better readable afterwards.

void sort(float *d, struct point *p, int n);

and

for(int i=0; i<n; i  )
{
    for(int j=1; j<n-i; j  )

CodePudding user response:

"Could someone help?"

Why do you have, and try to maintain, two "parallel" arrays?
One for x,y and one for a calculated distance.
Then try to keep their elements together when sorting and printing.

struct point {
    float x, y;
    float d;
};

Wouldn't that solve a lot of your problems?

You might even be able to pass the array full of these things to the standard library function qsort() to have it do the heavy lifting. (You'd have to comment out or remove your own sort() function, of course.)

Why make life harder than it already is?


EDIT:
Here are some fragments of code (and pseudocode) that you might find useful.

typedef struct {
    float x, y; // rect co-ord's
    float d; // calc'd distance from user co-ord
} xyd_t; // x,y and distance type


int cmpDist( const void *a1, const void *a2 ) { return ((xyd_t*)a)->d - ((xyd_t*)b)->d; }

xyd_t arr[ 20 ]; // 20 only as example
memset( arr, 0, sizeof arr ); // initialise all to zero

for( int i = 0; i < n; i   ) {
    arr[ i ].x = /* value */
    arr[ i ].y = /* value */
}

xyd_t user = { 37.5, 53.2, /* don't care */ };

calcDist( user, arr );

qsort( arr, n, sizeof arr[0], cmpDist );

for( int i = 0; i < n; i   )
    print i, arr[i].d; // distance
  • Related