Reader small image

You're reading from  Learn C Programming. - Second Edition

Product typeBook
Published inAug 2022
PublisherPackt
ISBN-139781801078450
Edition2nd Edition
Right arrow
Author (1)
Jeff Szuhay
Jeff Szuhay
author image
Jeff Szuhay

Jeff Szuhay is the principal developer at QuarterTil2 which specializes in graphics-rich software chronographs for desktop environments. In his software career of over 35 years, he has engaged in a full range of development activities from systems analysis and systems performance tuning to application design, from initial development through full testing and final delivery. Throughout that time, he has taught computer applications and programming languages at various educational levels from elementary school students to university students, as well as developed and presented professional, on-site training.
Read more about Jeff Szuhay

Right arrow

Chapter 16: Creating and Using More Complex Structures

In the real world, objects that we may want to model with data types and then manipulate with our program code are often best expressed as collections – sometimes complex collections – of the various data types we have already encountered. We saw how to make homogenous collections with arrays, where all of the values in the collection are of the same type and size. We also saw how to make heterogeneous collections with structures, where the various types in a structure are simple intrinsic types, even if they are not all the same type in the real world.

In this chapter, we will explore more complex structures. These include the following:

  • Arrays of structures
  • Structures consisting of arrays
  • Structures consisting of other structures
  • Structures consisting of arrays of structures

This may sound bewilderingly complex at first, but it is not. In reality, this is a logical extension of the...

Technical requirements

Continue to use the tools you chose in the Technical requirements section of Chapter 1, Running Hello, World!.

The source code for this chapter can be found at https://github.com/PacktPublishing/Learn-C-Programming-Second-Edition/tree/main/Chapter16.

Introducing the need for complex structures

We have explored C's intrinsic types – integers, floats/doubles, Booleans, and characters. We have also explored C's custom types – structures and enumerations. We have seen how a structure is a single instance of a grouping of intrinsic types to represent a set of related characteristics of something. Additionally, we have explored C's collection type, arrays, which are groups containing all the same type of thing.

Each of the data types we have explored more or less represents real-world objects that we may wish to manipulate. More often, however, real-world things are far more complicated. Therefore, these types alone may not adequately represent the real-world object we want to model and manipulate. So, we need to learn how to combine structures with arrays and arrays of structures to be able to represent a much broader set of real-world things. In doing so, we can model them and then manipulate them with...

Revisiting card4.h

We left Chapter 10, Creating Custom Data Types with typedef, with the card.h program and card5.c, which split card4.c into a header file and an implementation file. However, instead of going further with multiple-file program development, we will return to card4.c and rework a few things to include the knowledge we've gained since Chapter 10, Creating Custom Data Types with typedef. We'll use it to create a series of programs, carddeck.c. The carddeck.c series of programs will start out simple, but we will continue to modify it until we've added all the complex structures needed. This will remain a single file throughout this chapter. We will see how to logically split up our final carddeck.c program into multiple files and then build it in Chapter 24, Working with Multi-File Programs. Our goal in the development of carddeck.c is to represent a deck of 52 cards and shuffle it into 4 hands. The final output will print out the 4 hands, as follows:

...

Understanding an array of structures

Before we begin with the next set of changes, make a copy of carddeck_0.c and rename it carddeck_1.c. In this section, we will make changes to carddeck_1.c.

Probably the simplest of the complex structures we will explore in this chapter is an array of structures. Recall that all the elements of an array are of a single type and size. Before, we created arrays of one intrinsic type or another; now, we will create an array of a single custom type, Card.

Creating an array of structures

In the carddeck_1.c program, we need to model a deck of cards. To do this, we will create an array of the Card structures, as follows:

Card deck[52];

With this statement, we have created an array of 52 cards.

Note how, in the preceding definition, 52 is a magic number; that is, it is a literal number that has a special meaning. However, there is no context associated with that number unless it is stated in the comments. One problem with magic numbers...

Using a structure with other structures

In card4.c from Chapter 10, Creating Custom Data Types with typedef, we saw a structure, Hand, that contains another structure, Card. However, in that program, we accessed the entire substructure. We assigned the hand.card substructure by copying an entire Card structure to it. While this is convenient if we are dealing with complete substructures, we also need to know how to access elements within the substructure of a structure.

Here, we are going to look at accessing substructure elements within a structure. Before we begin our exploration, copy the carddeck_1.c file (this is the carddeck_1c.c file in the repository) to carddeck_2.c. In carddeck_2.c, we'll add the Hand structure with substructures and operations on Hand.

Creating a structure consisting of other structures

We have already seen how to create a Hand structure that consists of the Card structures, as follows:

typedef struct  {
   int...

Using a structure with arrays

We currently use an array of cards to represent a deck of cards. However, this representation is not sufficient for things we still need to do to a deck of cards. Two operations that are common to a deck of cards are first, to shuffle the deck into a random order, and second, to properly deal out cards from the randomized deck. We'll need to keep track of how many cards have been dealt and whether the deck is shuffled.

Our model for a deck of cards has just got a bit more complex. A single array representation is no longer sufficient. We will create a new structure, Deck, to hold additional information about our deck of cards as well as its shuffled or random state.

Before we begin defining this structure and operations on it, let's consider the randomization (shuffling) of our deck of cards. We could randomize our deck array by copying the structures in it from one index to another. However, since we now know about pointers, we can put...

Using a structure with an array of structures

Before we implement the Shuffled struct and operations on it, let's pause for a moment and reconsider how we might implement a shuffled deck. Because a deck of cards and a shuffled deck of cards are so similar, it makes somewhat more sense to combine them into a single structure, rather than have to declare and manipulate them separately. Our final Deck structure will consist of two arrays – one of an ordered set of cards and another of pointers to cards in that deck, which can then be shuffled as needed. In one array, the Card elements will always be ordered, while in the other array, the pointers can be swapped and moved around as needed. We will add additional information to the Deck structure to keep track of whether the deck is shuffled and how many cards have been dealt.

As we enhance our Deck structure and create/modify operations on the new structure, you should notice how little any of the other structures and methods...

Summary

This chapter not only explored complex structures but also reviewed nearly all the concepts we've explored in previous chapters.

We learned about various ways to access arrays of structures, substructures within structures, and arrays of structures within a structure. Each version of our carddeck.c program included a review of what was changed in that version.

We also learned about PRNGs and used a system-supplied PRNG to shuffle our deck of cards.

Throughout this chapter, we developed a complex program using stepwise refinement as we added structures and operations to these structures. More significantly, we got an in-depth view of how a program might change over its development life cycle. When we add or change structures, we also need to add or change the routines that manipulate those structures. This chapter demonstrated the software development process first described in Chapter 1, Running Hello, World!.

In the next two chapters, we will explore C&apos...

Questions

  1. Describe the composition of each of the structures given in carddeck.c:
    1. Card
    2. Hand
    3. Deck
  2. What is another name for the method of developing a program from a last-known good state to the next?
  3. What are magic numbers and why should they be avoided? How do we avoid them?
  4. We used two naming conventions for enumerated constants in carddeck.c. Why?
lock icon
The rest of the chapter is locked
You have been reading a chapter from
Learn C Programming. - Second Edition
Published in: Aug 2022Publisher: PacktISBN-13: 9781801078450
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Jeff Szuhay

Jeff Szuhay is the principal developer at QuarterTil2 which specializes in graphics-rich software chronographs for desktop environments. In his software career of over 35 years, he has engaged in a full range of development activities from systems analysis and systems performance tuning to application design, from initial development through full testing and final delivery. Throughout that time, he has taught computer applications and programming languages at various educational levels from elementary school students to university students, as well as developed and presented professional, on-site training.
Read more about Jeff Szuhay