William
William

Reputation: 81

When to use const in a function for C

I've been studying for my midterm tomorrow, and I came across this question where I couldn't decide between answers 2 and 3. PlayingCard is a struct, and HANDSIZE is a constant with a value of 5.

The right answer was apparently option 2, but both a friend and I thought that the better choice here would be 3, as we were told that we should use const as good programming practice when we know that the variable isn't going to be changed. Seeing as it isn't changed here, why would option 2 be better than option 3?

/* QUESTION: What should go for the definition of isFlush that detects flushes
   1: Nothing
   2: bool isFlush(PlayingCard hand[HANDSIZE]) {
   3: bool isFlush(const PlayingCard hand[HANDSIZE]) {
   4: bool isFlush(PlayingCard ** hand) {
   5: bool isFlush(const PlayingCard ** hand) {
   6: bool isFlush(PlayingCard *** hand) {
   7: bool isFlush(CardFace * hand) {
   8: bool isFlush(CardSuit * hand) {
   9: bool isFlush(CardSuit suits[HANDSIZE]) {
*/
// missing function defintion
    CardSuit suit = hand[0].suit;
    for (int i = 1;  i < HANDSIZE; i++ ) {
        if (suit != hand[i].suit) {
            return false;
        }
    }
    return true;
}

Upvotes: 3

Views: 182

Answers (2)

anastaciu
anastaciu

Reputation: 23792

as we were told that we should use const as good programming practice when we know that the variable isn't going to be changed

This is true, but only when you pass a pointer to a variable. If you pass the variable by value there is no advantage that I can see.

In this case I agree that the best answer is 3. It is probably too late to ask the author of the question why the correct answer is 2.

Upvotes: 3

jxh
jxh

Reputation: 70382

You can use const as a hint that the function will not modify something. You can pass a pointer to non-const thing to a function that declares it will take a pointer to const thing.

We don't have sufficient information to inform you which function declaration will work. I can eliminate options 1, 4, 5, 6, 8 and 9.

I can eliminate option 1 because it would not compile.

I can eliminate options 4, 5, and 6 because you cannot access a pointer with the . operator as is being done in the initialization of suit.

I can eliminate option 8, because a struct or union cannot be compared using !=.

I can eliminate option 9, because the name of the argument is wrong.

Options 8 and 9 are also unlikely because of the recursive definition required of the type CardSuit that is being suggested in the initialization of suit.

You asked:

Seeing as it isn't changed here, why would option 2 be better than option 3?

You seems to have eliminated option 7. I have insufficient information to do so, since PlayingCard might not have a suit member, whereas CardFace might have such a member. If that were the case, the correct answer would be option 7.

But assuming option 7 should be eliminated, then either options 2 or 3 would work for the function. So, to answer your question above in particular, option 3 is superior because it communicates the intention that the function will not modify the elements of the array.

The only advantage option 2 has over option 3 is that it will exclude attempts to call the function with an array of const things. You would only want to do that if the function wished to modify the elements.

Upvotes: 2

Related Questions