Enums
- Enumerated types are integral types with a small number of possible values.
- They are used rather that declaring many integer constants.
Declaring Enums
enum suit { CLUBS, DIAMONDS, HEARTS, SPADES };
- This declares a type called enum suit (not suit).
- By default, the enumeration constants take on the values 0, 1, 2, ...
- The values can be specified.
enum fruit { APPLE, ORANGE, PEAR = 5, MANGO, TOMATO = 7 };
Structs
- Structs are similar to objects, but cannot have methods.
- All fields are public.
Declaring Structs
struct point { double x; double y; };
- This declares a struct type whose name is struct point (not just point).
Accessing Fields
struct point p; p.x = 3.0; p.y = 5.7;
Pointers to Structs
struct point *q; q = malloc(sizeof(struct point)); (*q).x = 3.0; q->y = 5.7;
-
When q is a pointer to a struct with field x,
q->x
is syntactic sugar for(*q).x.
Bitfields
struct foo { int w : 4; int x : 1; int y : 3; int z : 2; };
- w occupies 4 bits
- x occupies 1 bits
- y occupies 3 bits
- z occupies 2 bits
- Bitfields can be signed or unsigned
Typedef
typedef struct foo { int x; double y; } foo;
- Creates a type called struct foo
- Creates an alias for struct foo called foo
- The typedef can be done separately from the declaration of the struct.
typedef struct foo { int x; double y; }; typedef struct foo foo;
- Typedefs can be used to give an alias for any type
typedef long double ldouble; typedef FILE *stream;
Recursive Types
- A typical declaration for a linked list.
struct node { int data; struct node *next; }; typedef struct node *list;
stack.c
Initializing Structs
struct foo { int n; double x; }; ... struct foo f = { 10, 4.5 };
Assigning Structs
Structs can be assigned, and all the fields are copied.
struct foo f = { 10, 4.5 }; struct foo g = f;
Passing Structs as Arguments
If a struct is passed as an argument (as opposed to a pointer to a struct), then all the fields are copied into a struct on the runtime stack.
Functions Returning Structs
A function can return a struct. When the return value is assigned to a variable, all the fields are copied.
struct foo foobar() { struct foo f = { 10, 4.5 }; return f; } ... struct foo g = foobar();
This is different than returning an array that is allocated on the stack, because a copy is made.
rational.h
rational.c
testrational.c
Unions
In a union, the fields are all stored in the same area of memory (they overlay each other).
union foo { long n; double x; };
Base 64 Encoding
Each group of 3 bytes is encoded as 4 printable characters by dividing a 24 bit group into 4 6 bit quantities. Each 6 bit quantity is represented by a printable character (a-Z, A-Z, 0-9, +, and /. (There are 64 of these characters, and 64 different 6 bit numbers).
A union can be used to separate 24 bit group into 4 6 bit sextets.
union base64 { char characters[3]; struct { sextet0 : 6; sextet1 : 6; sextet2 : 6; sextet3 : 6; } encoded; };