2. User-Defined Types
• C provides facilities to define one’s own types.
• These may be a composite of basic types (int,
double, etc) and other user-defined types.
• The most common user-defined type is a structure,
defined by the keyword struct.
2
3. Structures
• A structure is a collection of one or more variables,
possibly of different types, grouped together under a
single name
• Structures are user-defined aggregate types.
• They assist program organisation by
– Grouping logically related data, and giving this set of
variables a higher-level name and more abstract
representation.
– Reducing the number of parameters that need to be passed
between functions.
– Providing another means to return multiple values from a
function.
3
4. Structure Syntax
• A structure is defined by the keyword struct followed by a set of
variables enclosed in braces.
• Consider the following structure to represent a person’s details.
struct Personnel {
char name[100];
int age;
double height;
};
• The variables name, age and height are called members of the
structure type Personnel.
4
5. Declaring Structure Variables
•
There are two ways to define variables of a particular
structure type.
1. Declare them at the structure definition.
struct Personnel {
char name[100];
int age;
double height;
} p1, p2, p3; /* Define 3 variables */
2. Define the variables at some point after the structure
definition.
struct Personnel p1, p2, p3; /* Define 3 variables */
5
6. Initialising Structure Variables
•
A structure may be initialised when it is
defined using brace notation.
struct Personnel captain = {“Fred”, 37, 1.83};
•
The order of values in the initialise list
matches the order of declarations in the
structure.
6
7. Accessing Members
• Members of a structure type may be accessed via the
“.” member operator.
struct Personnel captain;
strcpy(captain.name, “Fred”);
captain.age = 37;
captain.height = 1.83;
printf(“%s is %d years old.”,
captain.name, captain.age);
7
8. Nested Structures
• Structures may be defined inside other
structures.
struct first
{
struct second
{
int a;
}s;
double amount;
}f;
• To access lower-level members, need to use
member operator multiple times.
f.s.a = 2.1;
f.amount = 75.4;
8
9. Operations on Structures
• Structure types only support one of the operations that are
permitted on primitive types.
– Assignment (ie., copying) is permitted
– All other operations (ie., arithmetic, relational, logical) are not
allowed
struct Personnel p1 = {“Fred”, 37, 1.83};
struct Personnel p2;
p2 = p1;
/* Valid. */
if (p1 == p2)
/* Invalid. Won’t compile. */
printf(“People are equaln");
if (strcmp(p1.name, p2.name) == 0 && /* Valid. */
p1.age == p2.age &&
p1.height == p2.height)
printf("People are equaln");
9
10. Structures and Functions
• Structures may be passed to functions and returned
from functions.
– Like all variables, they are passed by value
10
11. Pointers to Structures
• Defining pointers is the same as for variables of
primitive types
struct Personnel captain = {“Fred”, 37, 1.83};
struct Personnel *pp;
pp = &captain;
pp->age = 38; /* captain.age is now 38. */
11
12. Arrays of Structures
• The definition of arrays of structure types is
the same as for arrays of primitive types.
struct Personnel pa[10];
12
13. Self-Referential Structures
• A structure may not contain a variable of its own type.
struct Node {
int item;
struct Node n; /* Invalid */
};
• However, a structure may contain a pointer, self referential
structure
struct Node {
int item;
struct Node *pn; /* Valid */
};
13
15. Example: A Linked List
• Linked lists come in two basic varieties: singly linked and
doubly linked.
• We describe here a simple version of a singly linked list.
• List consists of a set of nodes, where each node contains an item
and a pointer to another list node.
struct List {
int item;
struct List *next;
};
• (Here we have chosen an int as the contained item. Any other
type(s) may be used.)
15
16. Singly Linked List
• List is formed by connecting the pointer of one node to the
address of the next.
• We keep a pointer to the head of the list. This permits traversal.
• The end of the list is marked by a NULL pointer.
• Example, to start at the head of the list and traverse to the end
node:
struct List *node = head;
while (node->next != NULL)
node = node->next;
printf(“Last node item: %d“, node->item);
16
17. Linked-List Properties
• Linked-Lists are useful because they can be grown (or
shrunk) very easily. Unlike arrays, there are no issues
of reallocating memory and copying data.
• Nodes can even be inserted (or removed) from midway
along the list without difficulty (and efficiently).
17
18. Adding Nodes to a List
• Show example code for adding a node to the end of the list.
• Show example code for adding a node midway through the
list.
18
19. Splicing in a New Node
•
Remember that everything is manipulated as an address. Consider the pointer variables, eg.,
–
–
–
node
node->next
newnode
is address 0x4D
is address 0xA1
is address 0xB6
0x4D
•
0xA1
Splicing:
newnode->next = node->next; assign to 0xA1
node->next = newnode;
assign to 0xB6
0xB6
0x4D
0xA1
19