0% found this document useful (0 votes)
27 views

Module03 ClassNotes

This document discusses data abstraction in C programming. It explains that data abstraction allows grouping of related data and specification of meaningful operations on that data, while separating implementation from abstraction. It then discusses various ways of implementing data abstraction in C, including structures, arrays, strings, nested structures, typedefs, and passing structures as function parameters. The document provides examples and explanations of each concept.

Uploaded by

Geay Peter
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
27 views

Module03 ClassNotes

This document discusses data abstraction in C programming. It explains that data abstraction allows grouping of related data and specification of meaningful operations on that data, while separating implementation from abstraction. It then discusses various ways of implementing data abstraction in C, including structures, arrays, strings, nested structures, typedefs, and passing structures as function parameters. The document provides examples and explanations of each concept.

Uploaded by

Geay Peter
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 26

RCS 210: PROGRAMMING IN C

Module 03 -- Data Abstraction using C

“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;

[0] [1] [2] [3] [4]


table 1.24 4.24 3.24 18.0 ???
3-7
No bounds checking in C
• C does not check for array boundary violations
table[5] = 12.2; /* syntactically legal */
table[-1] = 0.78;/* but not semantically */

[0] [1] [2] [3] [4]


0.78 2.24 4.24 3.24 18.0 ??? 12.2

memory has been corrupted!

• it is the programmer’s responsibility to ensure that a program


does not access outside an array’s limits
3-8
Text strings
• there is no explicit data type in C for a text string
• C defines a string to be:
an ASCII-NUL (‘\0’) terminated array of char so...

‘H’ ‘e’ ‘l’ ‘l’ ‘o’ ‘’ ‘w’ ‘o’ ‘r’ ‘l’ ‘d’

is just an array of char … but …

‘H’ ‘e’ ‘l’ ‘l’ ‘o’ ‘’ ‘w’ ‘o’ ‘r’ ‘l’ ‘d’ ‘\0’

is an array of char which is also (i.e. contains) a string


3-9
Text strings - arrays of char
There is an extensive library of functions within C for
manipulating strings (see <string.h>)

char *strcpy(char *destn, char *source);


copies source to destn
int strcmp(char *str1, char *str2);
compares str1 with str2 all of these depend on
char *strcat(char *str1, char *str2); their parameters (arrays of
concatenates str2 on to str1 char) being terminated
with an ASCII-NUL (‘\0’)

… and many others … see also Standard Library Function examples …


3-10
structs
• a struct in C is a complex data type, like an array, except each
element can be of a different type
• each element, known as a member, has its own name (not a
subscript) and its own type
• a member can itself be a structured type
• corresponds to the “record” structure in other languages

3-11
structs
struct studentRecord structure tag (optional)
{
char stNum[STNUM_LEN];
int ass1, ass2, exam;
float total;
char grade;
};
struct members

We can then declare variables of this type by:


struct studentRecord student1, student2;

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;

• … but we’ll see a better way soon ...

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.

typedef int Time; we now have a type name Time


Time hrs, min, secs;
declares variables hrs, min and
secs of type Time (i.e. int)

• this is most commonly used with structs to simplify data type


names and to build more complex structs of structs ( … of
structs … )

3-15
User-defined types using typedef
the recommended way …

typedef struct studentRecord


{
char sNum[9];
int ass1, ass2, exam;
float total;
char grade;
} StudentType;

StudentType student1, student2;

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

type name StudentType

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;
...

• even the inventors of C saw this as an “ugly” notation and so


gave us an alternative ...
3-20
Structs as parameters
void calculateGrade(StudentType *student)
{
:
student->total = student->ass1 * 0.15 +
student->ass2 * 0.25 +
student->exam * 0.4;
:
}

• The so-called arrow-operator is just an alternative (though more


pleasing) syntax for de-referencing members of structs via
pointers to a struct
3-21
Arrays of arrays
• multi-dimensional arrays are easily managed in C
• it is best to view a 2-D array as an array of arrays - this
generalises to n-D arrays

int matrix[NUM_ROWS][NUM_COLS];

for (i=0; j < NUM_ROWS; j++)


for (j=0; j < NUM_COLS; j++)
matrix[i][j] = i * 1000 + j;

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.” };

• a 2D array of char … or alternatively ...


• an array of strings

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;

• Not recommended for actual source code !

• See also: http://www.gnu.org/fun/jokes/declarations.html

3-26

You might also like