Coding Challenge: Modeling Complex Objects and Relationships (1)

Introduction

We aim to practice working with pointers, structures, and dynamic memory allocations by building a mini-project to manage a flower business.

Our business is quite the hit with flower enthusiasts, so we want to be able to expand in different continents and keep track of each continent individually.

Each continent can have multiple flower shops, depending on how many we decide to open in that continent.

Each flower shop sells only two types of flowers since they are exotic flowers and quite expensive. It is a very focused business, quality over quantity. In reality, the restriction of selling only two flowers is here to simplify our code.

Suppose you’re familiar with object-oriented programming (OOP). In that case, you may recognize that we’re defining a hierarchy using structures similar to how we would with classes in an OOP language.

Note: This lesson has two parts, which appear to be pretty long. The complete solution at the end takes the most time to read. We promise the text doesn’t take an hour to read! In fact, without the playground code widget, the lessons take around 24 minutes to read. It may take a few hours to solve all the challenges.

Lesson structure

This lesson is interactive by providing a mix of a tutorial, a follow-along session, and a coding challenge. We’ll build the project bit by bit, incrementally.

  • Some functions will be provided as a tutorial.
  • You will have to complete other functions and pass the test cases.

Note: Tasks marked with “demo task” are tutorial tasks. You don’t have to write any code. Make sure to understand the code. However, if you want, you can attempt to write the code on your own in any text editor or IDE and then compare it with the provided solution.

Structures

We’ll use the following structures to model the objects in our business.

Flower

We represent a flower using the TFlower structure. It contains:

  • flowerName: Pointer to the name of the flower
  • color: 32-bit string holding the color of the flower
  • price: The price of the flower (float)
  • quantity: The quantity we have in stock (int)
  • totalSold: Number of units we sold (int)

Flower shop

A flower shop sells flowers. We represent it using the TFlowerShop structure, with the following members:

  • name: Pointer to the name of the flower shop
  • address: 64-bit string containing the shop’s address
  • openingYear: The year when we opened this shop (int)
  • flowers: Array of two flowers. Recall that we only sell two flowers

Continents

We identify flower shops using the continent where they are operating. We represent a continent using the TContinent structure, with the following members:

  • continentId: int, the id of the continent. The available ids are:
    • EUROPE: 0
    • ASIA: 1
    • AFRICA: 2
    • NORTH_AMERICA: 3
    • SOUTH_AMERICA: 4
    • OCEANIA: 5
  • flowerShops: A resizable dynamically allocated array of pointers to shops.
    • INITIAL_FLOWER_SHOPS_SIZE : 1 as the initial size for the array.
  • length: The current number of flower shops in the array (int). We use it to regrow when there is no more empty space.
  • size: The maximum size of the array (int). We use it to regrow when there is no more empty space.

Flower business

We use a structure called TFlowerBusiness to keep track of the whole business. It contains:

  • continents: An array of size 6 of pointers to continents. Instead of the magic number 6, use the definition MAX_CONTINENTS.
  • onContinent: An array of size 6 of integers, where each value can be either 0 or 1.
    • 0: The flower business is not present on this continent.
    • 1: The flower business is present on this continent.

Note: Ensure you’re familiar with the objects involved and their members.

Task 1: Demo task

We’ll provide the definitions to ensure that we’re all on the same page. However, before reading the solution, write them on your own and compare them with the ones provided below…

Note: This step is ungraded as we can’t check it, but it’s important. Please write the definitions on your own, in any text editor or IDE.

According to the specifications provided above, we can write the structures like so:

typedef struct
{
	char* flowerName;
	char color[32];
	float price;
	int quantity;
	int totalSold;
} TFlower;

typedef struct
{
	char* name;
	char address[64];
	int openingYear;
	TFlower flowers[2];
} TFlowerShop;

typedef struct
{
	int continentId;
	TFlowerShop** flowerShops;
	int length;
	int size;
} TContinent;

typedef struct
{
	TContinent* continents[MAX_CONTINENTS];
	int onContinents[MAX_CONTINENTS];
} TFlowerBusiness;

Check the structure definitions against the specifications to understand why some types are the way they are.

The most complicated type is TFlowerShop** flowerShops; from TContinent. Make sure you understand why it is TFlowerShop**.

  • We want an array of pointers to TFlowerShop, each element inside the array is of type TFlowerShop*.
  • We want an array where each element is of type TFlowerShop*. We know that for a type T we can represent an array as T*.
  • Then, for the type TFlowerShop*, the array is of type TFlowerShop**.
  • Another way to think about this is in terms of array decaying. We can represent an array as a pointer to the first element. A pointer to TFlowerShop* is TFlowerShop**.
  • Another way to think about this is that malloc or calloc returns a pointer to the memory block. We want a memory block of type TFlowerShop*. A pointer to it is TFlowerShop**.

Helpful defines

We use the following defines for convenience, to avoid using magic numbers.

//Continent IDs
#define EUROPE 0
#define ASIA 1
#define AFRICA 2
#define NORTH_AMERICA 3
#define SOUTH_AMERICA 4
#define OCEANIA 5
#define MAX_CONTINENTS 6

//Macro to check if a continent id is valid
#define IsContinentIdValid(x) (EUROPE <= x <= OCEANIA)

//The initial size of the flower shops array for each continent
#define INITIAL_FLOWER_SHOPS_SIZE 1

const char* CONTINENT_NAMES[MAX_CONTINENTS] =
{
	"Europe",
	"Asia",
	"Africa",
	"North America",
	"South America",
	"Oceania"
};

Get hands-on with 1200+ tech skills courses.