1

I use swapCardsRandomly(b) but when I tried swapCardsRandomly(*b) program still works without any problem.

What is the difference then?

/*
*shuffles cards randomly
*/
void shuffle( int b[][13] ) {

    int counter;
    int rand1 = rand() % 4;
    int rand2 = rand() % 13;

    b[rand1][rand2] = 1;

    counter = 2;
    while ( counter < 53 )
    {
        rand1 = rand() % 4;
        rand2 = rand() % 13;

        while ( b[rand1][rand2] != 0 )
        {
            rand1 = rand() % 4;
            rand2 = rand() % 13;
        }

        b[rand1][rand2] = counter++;
    }
    swapCardsRandomly( b );
}

//for better shuffling swap elements randomly
void swapCardsRandomly( int m[][13] ) {

    int temp;
    int rand1; 
    int rand2;

    for ( i = 0; i < 4; i++ )
    {
        for ( j = 0; j < 13; j++ )
        {
            rand1 = rand() % 4;
            rand2 = rand() % 13;

            temp = m[i][j];
            m[i][j] = m[rand1][rand2];
            m[rand1][rand2] = temp;

        }
    }
}
UpAndAdam
  • 4,515
  • 3
  • 28
  • 46
Lyrk
  • 1,936
  • 4
  • 26
  • 48

4 Answers4

2

Both b and *b have the same address (b[0][0]), check this:

int b[1][13];
printf("%p %p %p\n", (void *)b, (void *)*b, (void *)&(b[0][0]));

But there is a pointer type conflict with *b

demo.c:52:1: warning: passing argument 1 of ‘swapCardsRandomly’ from incompatible pointer type [enabled by default]
demo.c:9:7: note: expected ‘int (*)[13]’ but argument is of type ‘int *’
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
1

This is because value-wise both *b and b are equal that is (void*)b == (void*)(*b) == true.

b is a two-dimentational matrix =b[rand1][rand2]=1;

type of matrix name b is int[][13] that decays into address of first element that is 0th row in two dimensional array. (you can think a two dimensional array as array of one dimensional arrays).

Because b is address of 0th row, so *b decays into address of b[0][0] that is address of 0th element of 0th-row. Interesting is value (magnitude) wise both are equal that is why your code works. When your call your function with *b or b argument, address value auto typecasted into proper type int [][13].

To observe it, in your code try this printf-statement:

printf("\n %p  %p\n", b, *b);

You will find both are equal!

To understand it more better with a diagram read this: A[0], &A, *A linked answer.

Community
  • 1
  • 1
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
1

In a multi-dimensional array the first element, and a pointer to the first row have the same address. This is because the first element of an array has the same address as the array. So, in your case, b points to the first element of an int [][13] array and *b points to the first element of a int [13] array that happens to be the first row of an int [][13] array.

The next question is why it lets you pass *b to SwapCardsRandomly when it expects int [][13] as an argument. The answer is that arrays, including multi-dimensional arrays, are not proper types in C, so when passed in this manner it treats them as a way to interpret a pointer.

Jack Aidley
  • 19,439
  • 7
  • 43
  • 70
0

Because both of b and *b are equal in value but are of different types i.e both of these pointer expression are of different types but points to he same memory location.

  1. b decays to pointer to first row (0th row) and it is of type int (*)[]. *b dereferences the pointer expression b hence
  2. *b is of type int (*)[].Since that's an array type, it decays to a pointer to the first element of the array object. So it's of type int*.

For detailed explanation, must read this answer.

Community
  • 1
  • 1
haccks
  • 104,019
  • 25
  • 176
  • 264
  • 1
    This answer is pretty shaky. What does "symmetrically different" mean? What's the difference between them? – Carl Norum Jul 25 '13 at 15:20
  • @CarlNorum; `b` is the address of first row and `*b` is the address of first element of the array `b`. – haccks Jul 25 '13 at 15:22