#include <stdio.h>
#include <stdbool.h>
#include <string.h>
// 1. Define the discriminator (tag) to track the active union state
typedef enum {
SHAPE_CIRCLE,
SHAPE_RECTANGLE
} ShapeType;
// 2. Define nested specific structs
typedef struct {
float radius;
} Circle;
typedef struct {
float width;
float height;
} Rectangle;
// 3. Define the main container struct with nested metadata and a union
typedef struct {
int id;
ShapeType type; // The tag that dictates which union member is valid
// Nested standard struct for metadata
struct {
char name[32];
bool is_active;
} metadata;
// Nested union for mutually exclusive variant data
union {
Circle circle;
Rectangle rectangle;
} dimensions;
} Shape;
/**
* @brief Safely accesses and prints items from nested structs and unions.
* @Pointer to the Shape structure being inspected.
*/
void print_shape_properties(const Shape *shape) {
// Best practice: Always validate pointer inputs
if (shape == NULL) {
printf("Error: Received NULL shape pointer.\n");
return;
}
// Accessing nested struct fields using the arrow operator (->)
printf("Shape ID: %d\n", shape->id);
printf("Shape Name: %s\n", shape->metadata.name);
printf("Status: %s\n", shape->metadata.is_active ? "Active" : "Inactive");
// Switch on the discriminator (tag) to safely access the correct union member
switch (shape->type) {
case SHAPE_CIRCLE:
// Accessing union member: shape->dimensions.circle.radius
printf("Type: Circle\n");
printf("Radius: %.2f\n", shape->dimensions.circle.radius);
break;
case SHAPE_RECTANGLE:
// Accessing union member: shape->dimensions.rectangle.width / height
printf("Type: Rectangle\n");
printf("Width: %.2f, Height: %.2f\n",
shape->dimensions.rectangle.width,
shape->dimensions.rectangle.height);
break;
default:
printf("Warning: Unknown shape type encountered.\n");
break;
}
printf("------------------------------------\n");
}
int main(void) {
// Initialize a Circle shape
Shape my_circle = {
.id = 101,
.type = SHAPE_CIRCLE,
.metadata = {
.name = "Unit Circle",
.is_active = true
},
.dimensions = {
.circle = { .radius = 5.5f }
}
};
// Initialize a Rectangle shape
Shape my_rectangle = {
.id = 102,
.type = SHAPE_RECTANGLE,
.metadata = {
.name = "Bounding Box",
.is_active = false
},
.dimensions = {
.rectangle = { .width = 10.0f, .height = 20.0f }
}
};
// Access and print using our safe function
print_shape_properties(&my_circle);
print_shape_properties(&my_rectangle);
return 0;
}
/*
run:
Shape ID: 101
Shape Name: Unit Circle
Status: Active
Type: Circle
Radius: 5.50
------------------------------------
Shape ID: 102
Shape Name: Bounding Box
Status: Inactive
Type: Rectangle
Width: 10.00, Height: 20.00
------------------------------------
*/