Returning a char?

Hello All!
I was trying to create a random card, like from a deck of cards, and I've been having some trouble. If there was a way to return a char, I feel the problem would be much easier. (I realize I could do the same thing assigning a global variable)

You should either return a struct object representing a card with both rank and suit, or return a single number that uniquely identifies rank and suit.

By the way, move this:

Code:

srand(time(NULL));

to near the start of your main function. srand should only be called once in your program to seed the pseudorandom number generator, whereas rand would be called whenever you want to generate a pseudorandom number.

Originally Posted by Bjarne Stroustrup (2000-10-14)

I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.

srand() should only be called once in your program. Put it early in main.

cardNum is rand() % 13, so it will be 0 to 12, inclusive. So cardNum == 13 will never be true. Your numbers in this section should go from 9 to 12 (Jack is 9).

"rank variable, which is either an int or a char"
Not in C. You need to pick one or the other. Make it a char and set it like so:

Code:

char rank = "23456789TJQKA"[cardNum];

I'm not sure what you mean by "a way to return a char".
If you want to return a char, return a char. Or have you made a double typo and meant "return a card"? I.e., you'd like to return both the rank and suit.

Alternatively, you can represent a card as a random int from 0 to 51, inclusive. When you need the suit, just use (ncard / 13), when you want the value use (ncard % 13) (possibly + 2, depending on your purpose).

Return a unsigned char
the lower 4bits is: 1(ace) to 13 (king) value
the next 2 bits is family: (0-3)

Code:

char getcard(void){
return ((rand()%13 +1) | ((rand()%4) <<4));
}

Not that different from using base-10 numbers in a similar fashion (ie suit and rank are incorporated into a unique ID number). I have a strong dislike for solutions that use bitwise operations for no apparent reason than "just because." Hardware prefers to work in larger segments of memory.

Why should global variables be avoided? Is it just bad practice or do they make for a more intensive program?

Global variables are generally considered bad practice, especially during the learning phase.

As programs become larger, it becomes more difficult to keep track of where global variables are updated, as their value can be changed by any functions in the same scope. This also makes reading the code more difficult, since it's not immediately obvious who might be changing their value. Additionally, this makes troubleshooting a lot more difficult for the same reason.

Global variables also threaten modularity, which is a goal for writing clean, maintainable, and testable code. Functions should receive the data they need to work with, and return a value if necessary. Once functions start reaching outside themselves to interact with data, it becomes easier for the code to become tangled. Functions should be used to reduce coupling between pieces of code - otherwise, changing one function might accidentally break something else that relies on the same global data. This makes the program a lot more fragile, which may come back to bite you when you have to make changes later on. Functions utilizing global data also inhibit their reuse, since they become tied to that specific task.

There are other potential problems, as well, such as conflicts if the same variable name is accidentally used elsewhere in the program, which could lead to confusing bugs.

Most of these problems will not be encountered when you're still writing small "practice" programs, but it's still good to avoid globals. If you use them too much as a "quick fix" in the early stages, then you might come to rely on them as the size of your programs start to grow, which will eventually lead to the problems above. Also, by properly passing information to/from functions, you will develop good coding habits and cleaner logic as your experience develops over time.

Some MCU/CPU don't have good bit access or they have limited like ARM's bitfield shadow memory trick that it's only good for one bit at a time.
TI's MSP430 have BitTest,BitClear and BitSet instructions so it handles bits pretty good.
But copy bit-pair's from one bitfield to another bitfield you need 4-6 instructions, so that should be avoided.