Home > Software engineering >  Shuffling elements in an array (C language)
Shuffling elements in an array (C language)

Time:05-30

The task is to shuffle an array entered by a user. The problem is probably with passing the array to the shuffle() function, so I must have messed sth up with pointers - however I have no idea where exactly is the bug. Here's my code:

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

void shuffle(int* tab, int size)
{
    int a[size];
    int occupied[size];
    int i;
    srand((unsigned) time(NULL));
    for (i=0; i<size; i  )
    {
        int j = rand() % size;
        for(int o=0; o<i; o  )
        {
            int b = 0;
            if(occupied[o]== j)
                b = 1;
            if(b==0)
                a[j] = tab[i];
        }
        occupied[i] = j;
    }
    for(int n = 0; n < size; n  )
    {
        printf(" %d",a[n] );
    }
}

int main(){
    int a[100];
    int i = 0;
    int x;
    while(x != 0)
    {
        printf("NEXT: ");
        scanf("%d", &x);
        if(x!=0) {
            a[i] = x;
            i  ;
        }

    }
    int size = i;
    printf("before: ");
    for(int n = 0; n < size; n  )
    {
        printf("=",a[n] );
    }
    printf("\nafter: ");
    shuffle(*a,size);

    return 0;
}

Thank you for any hints

CodePudding user response:

Let's suppose that everything in the shuffle function is right! When you declare the array int a[100]; the type of variable a is from type int*. The type you need to pass in the shuffle function is int*, so you don't need to pass *a as an argument.

CodePudding user response:

This is where we start:

$ gcc -Wall shuffle.c
shuffle.c:51:13: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'int *'; remove * [-Wint-conversion]
    shuffle(*a,size);
            ^~
shuffle.c:5:19: note: passing argument to parameter 'tab' here
void shuffle(int* tab, int size)
                  ^
shuffle.c:33:9: warning: variable 'x' is used uninitialized whenever function 'main' is called [-Wsometimes-uninitialized]
    int x;
    ~~~~^
shuffle.c:34:11: note: uninitialized use occurs here
    while(x != 0)
          ^
shuffle.c:33:10: note: initialize the variable 'x' to silence this warning
    int x;
         ^
          = 0
2 warnings generated.
$ 

The comments below the question already address many issues.

  • Use do-while for input.
  • Handover a instead of *a. For reference: a equals &a[0]
  • The occupied array was also not initialized.
  • There is this nice bool type which was introduced in C99. It is perfect for occupied, now called is_occupied.
  • The search for an empty position just rolled once and then tried to take the next free entry. I changed this to roll as many times as needed to find a free entry.
  • Copy the shuffled array into the input array. Hmm, that certainly has room for improvement. But it works for now.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>

void shuffle(int *tab, int size)
{
    int a[size];
    bool is_occupied[size];
    int i;
    for (i = 0; i < size; i  ) {
        is_occupied[i] = false;
    }
    srand((unsigned)time(NULL));
    for (i = 0; i < size; i  )
    {
        // roll new position
        int j = rand() % size;
        // roll again if position is occupied
        // until free position is found
        // there must be a free one
        while (is_occupied[j])
        {
            j = rand() % size;
        }
        a[j] = tab[i];
        is_occupied[j] = true;
    }
    for (i = 0; i < size; i  ) {
        tab[i] = a[i];
    }
}

int main()
{
    int a[100];
    int i = 0;
    int x;
    do
    {
        printf("Enter number (0 to quit): ");
        scanf("%d", &x);
        if (x != 0)
        {
            a[i] = x;
            i  ;
        }
    } while (x != 0);
    int size = i;
    printf("before: ");
    for (int n = 0; n < size; n  )
    {
        printf("=", a[n]);
    }
    printf("\nafter:  ");
    shuffle(a, size);
    for (int n = 0; n < size; n  )
    {
        printf("=", a[n]);
    }
    printf("\n");
    return 0;
}
$ gcc -Wall shuffle.c
$ ./a.out            
Enter number (0 to quit): 5
Enter number (0 to quit): 4
Enter number (0 to quit): 3
Enter number (0 to quit): 2
Enter number (0 to quit): 1
Enter number (0 to quit): 0
before:   5  4  3  2  1
after:    4  1  5  3  2
$ 
  • Related