ivyraveneve
ivyraveneve

Reputation: 43

How to make a copy of an array in this code and use it

So I have this code that randomly generates an integer array based on user input, and puts the elements in ascending and descending order. However, currently, the code only prints the descending order twice. So I would like to know how to make a copy of the array ascd and use the copy in the piece of code that organizes the descending order. I am just a beginner, so I apologize if this is a silly question, and appreciate all the guidance I can get. Here is my code:

#include <stdio.h>
#include <string.h> 
#include <time.h>
#include <stdlib.h>
int main (){ 


int x; 
printf("Enter the size of your array\n");//User is entering number of elements
scanf("%d", &x); 
int ascd[x]; //Array 
int c; 
int d;
int e; 
int kk = 0;
int temp;
int tempother;
int turtle; 

for(c = 0; c<x; c++){//Randomly generating elements
    srand(time(0)); 
    ascd[kk] = (rand() %100) + 1;
}

for(c = 0; c<x; c++){ //Ascending order
    for(d = 0; d<(x-c-1); d++){
        if(ascd[d] > ascd[d+1]){
                temp = ascd[d]; 
                ascd[d] = ascd[d+1]; 
                ascd[d+1] = temp; 
                }

                            }

               }




for(turtle = 0; turtle<x; turtle++){//Descending order
    for(e = 0; e<(x-turtle-1); e++){
        if(ascd[e] < ascd[e+1]){
                tempother = ascd[e]; 
                ascd[e] = ascd[e+1]; 
                ascd[e+1] = tempother; 
                }

                            }

               }




printf("The ascending order is\n\n"); 
         for(c = 0; c<x; c++){
     printf("%d\n", ascd[c]);
     }


printf("\n\nThe descending order is\n\n"); 
         for(turtle = 0; turtle<x; turtle++){
         printf("%d\n", ascd[turtle]);
         }   




}

Upvotes: 0

Views: 105

Answers (3)

David C. Rankin
David C. Rankin

Reputation: 84642

There are a number of additional issues you need to consider. First always, always, validate user input. If nothing else, with the scanf family of functions, make sure the expected number of conversions were successfully performed. e.g.

int x = 0;
printf ("\n enter the number of elements for your array: ");
if (scanf ("%d", &x) != 1) {    /* always validate user input */
    fprintf (stderr, "error: invalid input, integer required.\n");
    return 1;
}
int ascd[x], desc[x];

Next, you only need to seed the random number generator once. Move srand (time (NULL)); out of the loop.

While not a requirement, it is good practice to initialize your VLA's to all zero (or some number, since you cannot provide an initializer) to eliminate the chance of an inadvertent read from an uninitialized value when iterating over the array (you can consider your filling in this case an initialization, making the memset optional here, but you won't immediately loop and fill in all cases. Something as simple as the following is sufficient if you are not immediately filling the array, e.g.

memset (ascd, 0, x * sizeof *ascd); /* good idea to zero your VLA */

After filling your array, a simple memcpy will duplicate the array if you wish to preserve both ascending and descending sorts, e.g.

for (int i = 0; i < x; i++)            /* x random values 1 - 100 */
    ascd[i] = (rand () % 100) + 1;

memcpy (desc, ascd, x * sizeof *ascd);       /* copy ascd to desc */

The remainder is just a bit of cleanup. Resist the urge to create a (variable next) for every value in your code. That quickly becomes unreadable. While I prefer the C89 declarations, the C99/C11 declarations inside the for block are convenient, e.g.:

for (int i = 0; i < x; i++)                    /* ascending order */
    for (int j = 0; j < (x - i - 1); j++)
        if (ascd[j] > ascd[j + 1]) {
            int temp = ascd[j];
            ascd[j] = ascd[j + 1];
            ascd[j + 1] = temp;
        }

Putting all the pieces together, and noting that main() is type int and therefore will return a value, you could tidy things up as follows. Your style is completely up to you, but the goal should be readability. e.g.

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

int main (void) {

    int x = 0;
    printf ("\n enter the number of elements for your array: ");
    if (scanf ("%d", &x) != 1) {    /* always validate user input */
        fprintf (stderr, "error: invalid input, integer required.\n");
        return 1;
    }
    int ascd[x], desc[x];

    srand (time (NULL));                /* you only need do this once */
    memset (ascd, 0, x * sizeof *ascd); /* good idea to zero your VLA */

    for (int i = 0; i < x; i++)            /* x random values 1 - 100 */
        ascd[i] = (rand () % 100) + 1;

    memcpy (desc, ascd, x * sizeof *ascd);       /* copy ascd to desc */

    for (int i = 0; i < x; i++)                    /* ascending order */
        for (int j = 0; j < (x - i - 1); j++)
            if (ascd[j] > ascd[j + 1]) {
                int temp = ascd[j];
                ascd[j] = ascd[j + 1];
                ascd[j + 1] = temp;
            }

    for (int i = 0; i < x; i++)                   /* descending order */
        for (int j = 0; j < (x - i - 1); j++)
            if (desc[j] < desc[j + 1]) {
                int temp = desc[j];
                desc[j] = desc[j + 1];
                desc[j + 1] = temp;
            }

    printf ("\n the ascending order is\n\n");
    for (int i = 0; i < x; i++) {
        if (i && !(i % 10)) putchar ('\n');
        printf (" %3d", ascd[i]);
    }

    printf ("\n\n the descending order is\n\n");
    for (int i = 0; i < x; i++) {
        if (i && !(i % 10)) putchar ('\n');
        printf (" %3d", desc[i]);
    }
    putchar ('\n');

    return 0;
}

Example Use/Output

$ ./bin/sort_copy

 enter the number of elements for your array: 100

 the ascending order is

   1   1   4   4   5   5   7   8   8   9
  10  13  16  16  17  20  22  22  22  23
  24  24  25  27  29  29  33  35  35  35
  37  38  40  41  41  41  41  42  44  45
  46  48  48  48  49  50  53  54  56  57
  58  59  61  61  63  64  65  65  66  66
  67  68  68  70  71  73  74  74  74  75
  76  80  80  80  80  82  84  84  85  85
  85  85  86  88  88  89  89  90  91  91
  91  92  92  93  93  93  96  99 100 100

 the descending order is

 100 100  99  96  93  93  93  92  92  91
  91  91  90  89  89  88  88  86  85  85
  85  85  84  84  82  80  80  80  80  76
  75  74  74  74  73  71  70  68  68  67
  66  66  65  65  64  63  61  61  59  58
  57  56  54  53  50  49  48  48  48  46
  45  44  42  41  41  41  41  40  38  37
  35  35  35  33  29  29  27  25  24  24
  23  22  22  22  20  17  16  16  13  10
   9   8   8   7   5   5   4   4   1   1

Look things over and let me know if you have any questions.


Sorting with qsort

Continuing for the comment, qsort is an optimized sorting routine that is part of the C standard library (in stdlib.h) and is the go-to sort function regardless of the type of data you have to sort. The only requirement that generally catches new C programmers is the need to write a comparison function to pass to qsort so that qsort knows how you want the collection of objects sorted. qsort will compare two elements by passing a pointer to the values to the compare function you write. The declaration for the comparison is the same regardless of what you are sorting, e.g.

int compare (const void *a, const void *b);

You know you are sorting integer values, so all you need to do to sort ascending is to write a function that returns a positive value if a > b, returns zero if they are equal, and finally returns a negative value if b > a. The simple way, is to write

int compare (const void *a, const void *b) {
    int x = *(int *)a;
    int y = *(int *)b;
    return x - y;
}

That satisfies the sort requirement for ascending order, and to sort in descending order return y - x; -- but there is a problem. If x and y happen to be large positive and large negative values, there is a potential that x - y will exceed the maximum (or minimum) value for an integer (e.g. overflow, because the result will not fit in an integer value).

The solution is simple. You can perform the same comparison, but using the results of an inequality, e.g. returning (a > b) - (a < b) for the ascending comparison, and (a < b) - (a > b) for the descending comparison. (this scheme will work for all numeric types, you just need to adjust the cast). Step though the inequality. In the ascending case, if a > b the return is 1 (e.g. return 1 - 0;). If they are equal, the inequality returns 0 (0 - 0 ), and finally if a < b, the value returned is -1 ( 0 - 1 ).

While you are free to continue to explicitly declare the x and y variables, you will generally see it written with the cast in the comparison, eliminating the need for the x and y variables altogether, e.g.

/* integer comparison ascending (prevents overflow) */
int cmpascd (const void *a, const void *b)
{
    /* (a > b) - (a < b) */
    return (*(int *)a > *(int *)b) - (*(int *)a < *(int *)b);
}

Putting those pieces together, the same program can be written using qsort instead of the inefficient nested loops (and moving the print array routine to a function of its own) as follows,

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

#define ROW 10

int cmpascd (const void *a, const void *b);
int cmpdesc (const void *a, const void *b);
void prnarr (int *a, int n, int row);

int main (void) {

    int x = 0;
    printf ("\n enter the number of elements for your array: ");
    if (scanf ("%d", &x) != 1) {    /* always validate user input */
        fprintf (stderr, "error: invalid input, integer required.\n");
        return 1;
    }
    int ascd[x], desc[x];

    srand (time (NULL));                /* you only need do this once */
    memset (ascd, 0, x * sizeof *ascd); /* good idea to zero your VLA */

    for (int i = 0; i < x; i++)            /* x random values 1 - 100 */
        ascd[i] = (rand () % 100) + 1;

    memcpy (desc, ascd, x * sizeof *ascd);       /* copy ascd to desc */

    qsort (ascd, x, sizeof *ascd, cmpascd);       /* qsort ascending */
    qsort (desc, x, sizeof *desc, cmpdesc);      /* qsort descending */

    printf ("\n the ascending order is\n\n");
    prnarr (ascd, x, ROW);

    printf ("\n\n the descending order is\n\n");
    prnarr (desc, x, ROW);

    putchar ('\n');

    return 0;
}

/* integer comparison ascending (prevents overflow) */
int cmpascd (const void *a, const void *b)
{
    /* (a > b) - (a < b) */
    return (*(int *)a > *(int *)b) - (*(int *)a < *(int *)b);
}

/* integer comparison descending */
int cmpdesc (const void *a, const void *b)
{
    /* (a < b) - (a > b) */
    return (*(int *)a < *(int *)b) - (*(int *)a > *(int *)b);
}

void prnarr (int *a, int n, int row)
{
    for (int i = 0; i < n; i++) {
        printf (" %3d", a[i]);
        if (i && !((i + 1) % row))
            putchar ('\n');
    }
}

As with the first answer, give it a try and let me know if you have any questions. (And remember to always compile with a minimum -Wall -Wextra to enable most compiler warnings -- and fix any warnings generated before you consider your code reliable -- you won't run into any circumstance where warnings can be understood and safely ignored anytime soon) Add -pedantic to see virtually all warnings that can be generated. (if you look up pedantic in Websters, you will see why that name is apt.) Just FYI, the gcc compiler string I used to compile the code was:

$ gcc -Wall -Wextra -pedantic -std=c11 -Ofast -o bin/sort_copy sort_copy.c

Upvotes: 3

dulaj sanjaya
dulaj sanjaya

Reputation: 1340

Create an another array to store descending items. You can reverse the ascending array to create the descending array. Try this code. #include #include #include #include int main (){

int x;
printf("Enter the size of your array\n");//User is entering number of elements
scanf("%d", &x);
int ascd[x]; //Array
int desc[x];
int c;
int d;
int e;
int kk = 0;
int temp;
int tempother;
int turtle;
int z=0;

for(c = 0; c<x; c++){//Randomly generating elements
    srand(time(0));
    ascd[kk] = (rand() %100) + 1;
}

for(c = 0; c<x; c++){ //Ascending order
    for(d = 0; d<(x-c-1); d++){
        if(ascd[d] > ascd[d+1]){
                temp = ascd[d];
                ascd[d] = ascd[d+1];
                ascd[d+1] = temp;
                }

                            }

               }




for(turtle = x-1; turtle>=0; turtle--){//Descending order
        desc[z]=ascd[turtle];
        z++;


    }




printf("The ascending order is\n\n");
         for(c = 0; c<x; c++){
     printf("%d\n", ascd[c]);
     }


printf("\n\nThe descending order is\n\n");
         for(turtle = 0; turtle<x; turtle++){
         printf("%d\n", desc[turtle]);
         }




}

Upvotes: 0

hexiecs
hexiecs

Reputation: 322

You print the final array twice, you can have your ascending array output by printing the values of the array right after you have done the ascending operation.

Upvotes: 0

Related Questions