Structures
Structures
Heterogeneous Structures
Collection of values of possibly different types.
Name the collection.
Name the components.
Example : Student record
Singhal
name "V Singhal"
rollno "00CS1001"
classtest 14
midterm 78
final 73
grade ‘B
Structure : terminology
A struct is a group of items (variables) which
may be of different types.
Each item is identified by its own identifier,
each of which is known as a member or field
of the structure.
A struct is sometimes called a record or
structure.
Structs are the basis of classes in C++ and
Java.
Structure declaration
This declaration creates
struct { two structure variables,
sname and ename, each
char first[10]; of which contains 3
char midinit; members.
We can use
char last[20]; sname.first,
ename.midinit,
} sname, ename; etc.
Members
To access the members of a structure,
we use the member access operator “.”.
strcpy (sname.first, “Sudeshna”);
sname.midinit = ‘K’;
strcpy (sname.last, “Sarkar”) ;
Tagged structure
struct nametype { This definition creates
char first[10]; a structure tag nametype
char midinit; containing 3 members:
char last[20]; first, midinit, last.
Variables may be declared
};
of type struct <tagname>.
struct nametype sname,
ename; typedef is normally used
typedef struct nametype NTYPE; to give names to a
NTYPE aname, bname; struct type.
typedef
typedef struct {
char first[10];
char midinit;
char last[20];
} NAMETYPE;
NAMETYPE sname,ename;
Another example
#define MAX_NAME 40
typedef struct {
char name[MAX_NAME+1];
char rollno[10];
int classtest;
int midterm;
int final;
char grade;
} StudentRecord;
Defines a new data type called StudentRecord. Does
not declare a variable.
Declaring struct variables
/* typedef structs go at top of program */
...
int .....
float ....
StudentRecord s1;
StudentRecord singhal ;
/* StudentRecord is a type; s1 and singhal are variables*/
struct nametype aname;
/* struct nametype is a type; aname is a variable */
Things you can and can't do
You can
Use = to assign whole struct variables
You can
Have a struct as a function return type
You cannot
Use == to directly compare struct variables;
can compare fields directly
You cannot
Directly scanf or printf structs; can read
fields one by one.
Struct initializers
/* typedef structs go on top */
StudentRecord s1 = {"V Singhal", "00CS1002", 15,
78, 73, 'B'};
argument.
int avg (StudentRec class[MAX]) { ... }
int main (void) {
StudentRec bt01[MAX];
int average;
...
average = avg_midpt(bt01) ;
}
Dynamic Memory Allocation,
Structure pointers
Basic Idea
Many a time we face situations where data is
dynamic in nature.
Amount of data cannot be predicted
beforehand.
Number of data item keeps changing during
program execution.
Such situations can be handled more easily and
effectively using dynamic memory
management techniques.
C language requires the number of
elements in an array to be specified at
compile time.
Often leads to wastage or memory space
or program failure.
Dynamic Memory Allocation
Memory space required can be specified at
the time of execution.
C supports allocating and freeing memory
dynamically using library routines.
Memory Allocation Process in
C
int main () {
int *a, n;
printf (“Input n: “) ;
scanf (“%d”, &n) ;
a = calloc (n, sizeof (int)) ;
read_array (a, n) ;
wrt_array (a, n) ;
printf (“Sum = %d\n”, sum_array(a, n);
}
void read_array (int *a, int n) {
int i;
for (i=0; i<n; i++)
scanf (“%d”, &a[i]) ;
}
void sum_array (int *a, int n) {
int i, sum=0;
for (i=0; i<n; i++)
sum += a[i] ;
return sum;
}
void wrt_array (int *a, int n) {
int i;
........
}
Arrays of Pointers
Array elements can be of any type
array of structures
array of pointers
int main (void) {
char word[MAXWORD];
char * w[N]; /* an array of pointers */
int i, n; /* n: no of words to sort */
for (i=0; scanf(“%s”, word) == 1); ++i) {
w[i] = calloc (strlen(word)+1, sizeof(char));
if (w[i] == NULL) exit(0);
strcpy (w[i], word) ;
}
n = i;
sortwords (w, n) ;
wrt_words (w, n);
return 0;
}
Input : A is for apple or alphabet pie which
all get a slice of come taste it and try
w
0 A \0
1 i s \0
2 f o r \0
3 a p p l e \0
17 t r y \0
void sort_words (char *w[], int n) {
int i, j;
for (i=0; i<n; ++i)
for (j=i+1; j<n; ++j)
if (strcmp(w[i], w[j]) > 0)
swap (&w[i], &w[j]) ;
}
void swap (char **p, char **q) {
char *tmp ;
tmp = *p;
*p = *q;
*q = tmp;
}
Before swapping
w[i]
f o r \0
a p p l e \0
w[j]
After swapping
w[i]
f o r \0
a p p l e \0
w[j]
Pointers to Structure
Pointers and Structures
You may recall that the name of an array stands
for the address of its zero-th element.
Also true for the names of arrays of structure
variables.
Consider the declaration:
struct stud {
int roll;
char dept_code[25];
float cgpa;
} class[100], *ptr ;
The name class represents the address of the
zero-th element of the structure array.
ptr is a pointer to data objects of the type struct
stud.
The assignment
ptr = class ;
will assign the address of class[0] to ptr.
When the pointer ptr is incremented by one
(ptr++) :
The value of ptr is actually increased by
sizeof(stud).
It is made to point to the next record.
Once ptr points to a structure variable,
the members can be accessed as:
ptr –> roll ;
ptr –> dept_code ;
ptr –> cgpa ;
b 2
xxx q
c 3
p = &a ;
q = &b ;
a 1 p
b 2
q
c 3
c = *p ;
p=q;
*p = 13 ;
a 1 p
b 13
q
c 1
Bad pointer Example
void BadPointer () { p xxx
int *p;
*p = 42; X
}
int * Bad2 () {
int num, *p;
num = 42;
p = #
return p;
}
A function call malloc(size) allocates a block of
mrmory in the heap and returns a pointer to the new
block. size is the integer size of the block in bytes.
Heap memory is not deallocated when the creating
function exits.
malloc generates a generic pointer to a generic data
item (void *) or NULL if it cannot fulfill the request.
Type cast the pointer returned by malloc to the type
of variable we are assigning it to.
free : takes as its parameter a pointer to an allocated
region and de-allocates memory space.
Dynamic memory allocation: review
typedef struct {
int hiTemp;
int loTemp;
double precip;
} WeatherData;
main () {
int numdays;
WeatherData * days;
scanf (“%d”, &numdays) ;
days=(WeatherData *)malloc (sizeof(WeatherData)*numdays);
if (days == NULL) printf (“Insufficient memory”);
...
free (days) ;
}
Self-referential structures
Dynamic data structures : Structures with
pointer members that refer to the same
structure.
Arrays and other simple variables are
data next
head n NULL
Storage allocation
head->next = malloc (sizeof(ELEMENT));
head->next->d = ‘e’;
head->next->next = NULL;
head n e NULL
Storage allocation
head->next=>next = malloc (sizeof(ELEMENT));
head->next->next->d = ‘e’;
head->next->next-> = NULL;
head n e w NULL
List operations
Create a list
Count the elements
Look up an element
Insert an element
Delete an element
Produce a list from a string
(recursive version)
#include “list.h”
LINK StrToList (char s[]) {
LINK head ;
if (s[0] == ‘\0’)
return NULL ;
else {
head = malloc (sizeof(ELEMENT));
head->d = s[0];
head->next = StrToList (s+1);
return head;
}
}
#include “list.h” list from a string
LINK SToL (char s[]) {
LINK head = NULL, tail;
(iterative version)
int i;
if (s[0] != ‘\0’) {
head = malloc (sizeof(ELEMENT));
head->d = s[0];
tail = head;
for (i=1; s[i] != ‘\0’; i++) {
tail->next = malloc(sizeof(ELEMENT));
tail = tail->next;
tail->d = s[i];
}
tail->next = NULL;
}
return head;
}
1. A one-element list
head
A ? 4. after assigning NULL
tail head
2. A second element is attached A B NULL
head tail
A ? ?
tail
3. Updating the tail
head
A B ?
tail
/* Count a list recursively */
int count (LINK head) {
if (head == NULL)
return 0;
return 1+count(head->next);
}
q
B
Insertion
/* Inserting an element in a linked list. */
void insert (LINK p1, LINK p2, LINK q) {
p1->next = q;
q->next = p2;
}
After Insertion
p1 p2
A C
q
B
Deletion
Before deletion
p
1 2 3
p->next = p->next->next;
p garbage
After deletion
1 2 3
Deletion
Before deletion
p
1 2 3
q = p->next;
p->next = p->next->next;
p After deletion
1 2 3
q
free (q) ;
Delete a list and free memory
/* Recursive deletion of a list */
void delete_list (LINK head) {
if (head != NULL) {
delete_list (head->next) ;
free (head) ; /* Release storage */
}