0

I want to manipulate an array of integers in a function, but I am not sure if I should use the address prefix or the pointer prefix:

void shuffle(int *deck[]){  
    //statements
}

or

void shuffle(int &deck[]){  
    //statements
}

Further, when I directly want to manipulate the values of the array, I'm not sure if I should use (within the function)

*deck[4] = 34

or something else.

Any clarification is appreciated.

6 Answers 6

3

There are no references in C(your Q is tagged C only) so you will have to use the pointer version.

When you say pass an array to the function, what you essentially pass to the function is the pointer to its first element, both of the following two syntaxes mean one and the same thing to the compiler:

void shuffle(int *p_deck); 
void shuffle(int deck[]);
Sign up to request clarification or add additional context in comments.

Comments

0

Neither.

Since arrays can be passed by reference only, you don't need to do tricks, just pass a pointer and dereference it. (That syntax involving the & in your 2nd function is not valid, anyway). So:

void shuffle(int arr[])
{
    arr[0] = 1337;
}

or

void shuffle(int *arr)
{
}

etc. And you can pass it like this:

int deck[52];
shuffle(deck);

3 Comments

I don't think that your last variant is correct. The address is the same but the type is int (*)[52], so this is a constraint violation.
@Jens did I write it's the same type? No. Did I write it's the same address? Yes. Is that correct? Yes. Problem?
Passing a pointer of wrong type is a constraint violation (= error), that's all. It forces a compiler message. Don't teach beginners cruft like that.
0

You would have to use the pointer version, but because of the Right-Left Rule, I believe your:

int * deck[] would actually be an array of int pointers, instead of an array of ints.

http://cseweb.ucsd.edu/~ricko/CSE131/rt_lt.rule.html

You should just pass a reference to the first element in the array:

int * deck but you may want to pass in the size of the array so you avoid going out of bounds.

Comments

0

Arrays decay into pointers when passed to functions, so there's no point in using an additional level of indirection here.

According to §6.3.2.1 of the C99 standard,

Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type "array of type" is converted to an expression with type "pointer to type" that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

void shuffle(int deck[]) {
  ...
}

Note that C does not support references, only pointers. You're probably thinking of C++.

Comments

0

You can pass an array by reference in C++, if you specify the size of the array:

void shuffle(int (&deck)[52])
{
   deck[4] = 34;
}

If you don't know the size, or if you're limited to C, you need to use pointers.

The other (C++) option is to use a vector for the deck and pass a reference to the vector instead.

Comments

0

C doesn't have references (a), that's C++.

In C, arrays of X decay into a pointer to X[0] when passed to functions, so one way is to use:

void shuffle (int *pDeck) {
    // use pDeck[something]
}
:
int deck[] = {0,1,2,3,4,5,6,7,8,9};
shuffle (deck);

I actually prefer that method to the void shuffle (int pDeck[]) variant since the former makes it absolutely clear that you're now dealing with a pointer rather than an array.

The reason this is important is because you lose the size information when you do that, so you may want to pass that in as well:

void shuffle (int *pDeck, size_t sz) {
    // use pDeck[0 thru sz-1]
}
:
int deck[] = {0,1,2,3,4,5,6,7,8,9};
shuffle (deck, sizeof (deck) / sizeof (*deck));

(a): Although they are a very nice feature. I do hope that ISO considers them for the next C standard, since a large number of problems newcomers to the language have are involved with pointers, and references can hide the complexity of that very well.

3 Comments

No, &deck is of the wrong type, it is int (*)[10]. Either use just deck or &deck[0].
@JensGustedt, you're absolutely right, the &deck would be more suitable for something like int deck = 42 (though of course the sizeof wouldn't work then). After the stick I give other people here for making the same mistake, I should have checked the code in a compiler. The effect is the same in this case but, yes, smart compilers generate a warning for this. Have changed to use the right type.
No, this is not a question of "smart" compiler or not. This is a constraint violation and a conforming compiler must issue a diagnostic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.