Module03 ClassNotes
Module03 ClassNotes
“Act in haste and repent at leisure; Code too soon and debug forever.”
--Raymond Kennington
3-1
Data Abstraction
• In much the same way procedural abstraction lets one think about
a series of computational steps as an abstract unit, data
abstraction lets one think about collections of data as abstract
entities. This could be useful for:
– grouping related pieces of information together.
– understanding and specifying what meaningful operations can be
performed on the data.
– enforcing certain restrictions on the use of the data.
– separating the implementation from the abstraction itself, so:
• we can change the internal representation
• we can change the implementation without changing the abstract behaviour
• others can use the abstraction without needing to understand the internal
implementation.
3-2
Data Abstraction (cont’d)
• The result of procedural abstraction is a procedure.
• Similarly, the result of data abstraction is an abstract data type
(ADT).
• In object-oriented languages (like Java), ADT's are
implemented as classes.
• In a structured language (like ANSI C), ADT’s are implemented
using structures, functions, storage classes and multiple source
files.
3-3
Data Abstraction (cont’d)
• An abstract data type (ADT) consists of:
1. An interface -- a set of operations that can be performed
2. The allowable behaviours -- the way we expect instances of the ADT to
respond to operations.
• The implementation of an ADT consists of:
1. An internal representation -- data stored inside the object's instance
variables/members.
2. A set of methods implementing the interface.
3. A set of representation invariants, true initially and preserved by all methods
• We will revisit the ADT’s later once we have explored more of the
necessary features of the C programming language; starting with
structures.
3-4
Structured Data Types
• Structures are built from basic data types
• Arrays
• No bounds checking in C
• Text strings
• Structs
• User-defined types using typedef
• Nested structs
• Structs as parameters
• Arrays of arrays and arrays of structs
3-5
Structures built from basic data types
• it is possible to construct more complex (i.e. structured) data
types from the basic types
• the 2 main structured types in C are:
– arrays - where each element is of the same type
– structs - where each element (known as a member) can be of a different
type
• these simple building blocks allow us to model complex real life
entities
3-6
Arrays
A simple one-dimensional array:
Array declaration - subscript is
float table[5]; the number of elements in the
int i = 1; j = 2;
array
table[2] = 3.24
table[i] = table[2] + 1;
table[i+j] = 18.0;
table[--i] = table[j] - 2;
‘H’ ‘e’ ‘l’ ‘l’ ‘o’ ‘’ ‘w’ ‘o’ ‘r’ ‘l’ ‘d’
‘H’ ‘e’ ‘l’ ‘l’ ‘o’ ‘’ ‘w’ ‘o’ ‘r’ ‘l’ ‘d’ ‘\0’
3-11
structs
struct studentRecord structure tag (optional)
{
char stNum[STNUM_LEN];
int ass1, ass2, exam;
float total;
char grade;
};
struct members
3-12
structs
• alternatively, variables can be declared with the struct
definition:
struct studentRecord
{
char sNum[9];
int ass1, ass2, exam;
float total;
char grade;
} student1, student2;
3-13
structs
• once variables have been declared, we reference individual
members using the ‘dot’ (.) operator:
strcpy(student1.stNum, “2012345X”);
student1.ass1 = 75;
student1.total = student1.ass1 * 0.15 +
student1.ass2 * 0.25 +
student1.exam * 0.6;
if (student1.total < 50) student1.grade = ‘N’;
3-14
User-defined types using typedef
• the typedef statement allows us to assign a user-defined name
to a type definition - e.g.
3-15
User-defined types using typedef
the recommended way …
3-16
Nested structs
typedef struct dateStruct
{
int day;
int month;
int year;
} DateType;
type name DateType
typedef struct studentRecord
{
char stNum[9];
DateType birthdate;
:
:
} StudentType;
nested struct
3-17
Nested structs
Again we just use the (repeated) dot notation:
simpler, clearer declaration
StudentType student1; of variable’s type
strcpy(student1.stNum, “2012345X”);
student1.birthdate.day = 6;
student1.birthdate.month = 2; a “dot” (.) for each
student1.birthdate.year = 1955; level of nesting
3-18
Structs as parameters
• consider function calculateGrade() which uses values of some
members of student to calculate values for other members
- i.e. student is an in-out parameter:
int main(void)
{
StudentType student;
:
calculateGrade(&student);
:
}
3-19
Structs as parameters
void calculateGrade(StudentType *student)
{
...
(*student).total=(*student).ass1 * 0.15
+ (*student).ass2 * 0.25
+ (*student).exam * 0.4;
...
int matrix[NUM_ROWS][NUM_COLS];
3-22
Arrays of arrays
#define LINE_LEN 80
#define NUM_LINES 3
char poem[NUM_LINES][LINE_LEN] =
{ “This message transmitted on 100% recycled electrons.”,
“ASCII stupid question, get a stupid ANSI!”,
“To iterate is human; to recurse, divine.” };
3-23
Arrays of structs
• we can also easily have arrays where each element of the array
is a struct
StudentType student[10];
strcpy(student[i].stNum, “9912345A”);
student[i].birthdate.day = 12;
student[i].birthdate.month = 11;
student[i].birthdate.year = 2002;
3-24
Arrays as parameters
• arrays can only be call-by-reference parameters, never call-by-
value
• … because of the unique relationship between array names and
pointers in C …
• … our next topic ...
3-25
Declaration Fun :-)
static electricity;
short circuit;
struct by_lightning;
struct dumb by[sizeof assignment];
double entendre;
3-26