Declaring Your Own Types in C

Structures

The struct keyword lets you declare a type that bundles together several values, possibly of different types. To access the fields inside a struct variable, use dot syntax, like thing.field. Here’s an example:

struct rect_t { int left; int bottom; int right; int top; }; int main() { struct rect_t myRect; myRect.left = -4; myRect.bottom = 1; myRect.right = 8; myRect.top = 6; printf("Bottom left = (%d,%d)\n", myRect.left, myRect.bottom); printf("Top right = (%d,%d)\n", myRect.right, myRect.top); return 0; }

This program declares a type struct rect_t and then uses a variable myRect of that type.

Enumerations

The enum keyword declares a type that can be one of several options. Here’s an example:

enum threat_level_t { LOW, GUARDED, ELEVATED, HIGH, SEVERE }; void printOneLevel(enum threat_level_t threat) { switch (threat) { case LOW: printf("Green/Low.\n"); break; // ...omitted for brevity... case SEVERE: printf("Red/Severe.\n"); break; } } void printLevels() { printf("Threat levels are:\n"); for (int i = LOW; i <= SEVERE; i++) { printOneLevel(i); } }

This code declares a type enum threat_level_t that can be one of 5 values.

Type Aliases

You can use the typedef keyword to give new names to existing types. Use typedef <old type> <new name>;, like this:

typedef int whole_number;

Now, you can use whole_number to mean the same thing as int.

Short Names for Structs and Enums

You may have noticed that struct and enum declarations make types that are kind of long and hard to type. For example, we declared a type enum threat_level_t. Wouldn’t it be nice if this type could just be called threat_level_t?

typedef is also useful for defining these short names. You could do this:

enum _threat_level_t { ... } typedef enum _threat_level_t threat_level_t;

And that does work! But there’s also a shorter way to do it, by combining the enum and the typedef together:

typedef enum { ... } threat_level_t;

That defines an anonymous enumeration and then immediately gives it a sensible name with typedef.

Below is a helpful table which summarizes the different ways that you can declare and initialize a struct (or an enum).

Description Declaration Declaration & Initialization
Define a type struct rect_t only.
struct rect_t { int left; int bottom; int right; int top; };
struct rect_t myRect; myRect.left = 1; ...
myRect has type struct rect_t
Define a type struct _rect_t and then define its type alias rect_t.
struct _rect_t { int left; int bottom; int right; int top; }; typedef struct _rect_t rect_t;
struct _rect_t myRect; myRect.left = 1; ...
OR
rect_t myRect; myRect.left = 1; ...
Define a type struct _rect_t and its type alias rect_t in the same statement.
typedef struct _rect_t { int left; int bottom; int right; int top; } rect_t;
struct _rect_t myRect; myRect.left = 1; ...
OR
rect_t myRect; myRect.left = 1; ...
Define a type rect_t.
typedef struct { int left; int bottom; int right; int top; } rect_t;
rect_t myRect; myRect.left = 1; ...