Title: CptS 121 Fall 06 Lecture 151
1CptS 121 Fall 06 Lecture 15-1
- Linked Structures (cont.) HK Chapter 13
Programming in the Large - Lecture Outline
- Discussion of Quiz 11
- Managing Programming in the Large
- Personal Libraries
2Programming in the Large
- Most programs you have written this semester have
been relatively small ( - This is called "programming in the small"
- It's an appropriate scale for beginning
programmers - In the real world, however, you'll be called upon
to implement much bigger programs (thousands, and
even millions of lines of code) - High level programming languages (and C in
particular) have several facilities to support
this scale of programming - The concept of abstraction is central
3Programming in the Large (cont.)
- Managing programming in the large Goals
- Modularize the project
- Break project up into small pieces that can be
independently implemented by different people at
different times - Promote reuse
- Basic building blocks should be readily usable by
different programmers, so there's no need to
reinvent the wheel
4Programming in the Large (cont.)
- Managing programming in the large Tools
- Procedural abstraction
- We decompose the problem into smaller pieces that
can be developed independently - What these smaller pieces do (how their outputs
are related to their inputs) must be known at the
time you design a program - However, how these smaller pieces do the job need
not be a concern at design-time - This separation of what and how is a powerful
design tool it allows us to focus on structure,
without getting steeped in implementation details - We have talked about this concept all semester
nowhere is it more important than in designing
large-scale software systems
5Programming in the Large (cont.)
- Example problem that will allow us to explore
procedural abstraction Saw Mill Simulation
Program - Available on the web athttp//eecs.wsu.edu/hund
haus/teaching/cpts121/lectures/SawMill.html
6Programming in the Large (cont.)
- High-level Decomposition
- High-level algorithm Program component
- Get and open input file get_and_open_file()
- Read in log orders read_log_orders()
- Process log orders process_log_orders()
- Print out simulation stats print_stats()
7Programming in the Large (cont.)
- Procedural abstraction can go deeper
- Low-level component Sub-components
- process_log_orders() init_scrapbin()
- get_longest_scrap()
- cut_longest_scrap()
- add_to_scrapbin()
- Procedural abstraction can go even deeper
- Lower-level component Sub-components
- cut_longest_scrap() remove_longest_scrap()
- add_to_scrapbin()
8Programming in the Large (cont.)
- Managing programming in the large Tools (cont.)
- Data Abstraction
- We specify the data objects and operations that
can be performed on those objects, without
specifying how the data objects will be
represented in memory - Example The concept of the scrap bin in the Saw
Mill simulation - We know what it needs to be capable of doing
- Add a scrap
- Obtain the length of the longest scrap
- Remove longest scrap
- But we don't care how the scrap bin is
represented - The array implementation is just one of many
possibilities
9Programming in the Large (cont.)
- Managing programming in the large Tools (cont.)
- Information Hiding
- We hide details of
- the internal representation of data
- the operators that manipulate that data
- This allows us to postpone discussions of
implementation details, so that we can focus on
design issues
10Programming in the Large (cont.)
- Managing programming in the large Tools (cont.)
- Reusable Code
- We write code that can be easily plugged into
applications without modification - Encapsulation is one way to achieve reusable code
- Example A microwave oven encapsulates the task
of warming food, without revealing the process by
which it does so (with radio waves that are
absorbed by food, but not by dishes) - Similarly, we can package up data with functions
that operate on that data in a personal library,
which can be included into code. Programmers can
use our libraries without fully understanding the
implementation details
11Personal Libraries
- The code we've written so far has invariably
included standard libraries such as
and - In the same way, we can use functions defined in
our own personal libraries - We include the personal library at compile-time
- We link to the library at link-time
- Let's take a look at how we can create personal
libraries by way of example
12Example Personal Library The Stack
- Suppose we want to create a personal library that
defines the classic stack abstract data type
(ADT) - A stack is known as a "LIFO" ("Last in, first
out") data structure, because the last item
placed in the stack is the first one removed
(like a stack of cafeteria trays) - The stack has numerous applications in
programming, e.g., - Reversing a list of items
- Parsing an expression (CptS 122)
- The stack defines four key operations
- Push pushes a new item onto the stack
- Pop removes the top item from the stack
- Peek returns the value of the top item on the
stack, without removing the item - Empty determines whether the stack has items in
it - Full determines whether stack is full
13Example Personal Library The Stack (cont.)
- In future CptS courses, you'll learn how to
define a personal ADT library (such as a stack)
capable of storing items of any data type - Such an ADT is beyond the scope of this course,
however in this example, we'll define a stack
that is only capable of storing integer data - In general, writing a personal library requires
creating two files - A header file
- An implementation file
- Let's define each of these
14Example Personal Library The Stack (cont.)
- The header file
- Contains all the information that the compiler
needs to compile code that uses your personal
library - Contains documentation that enables others to use
the library - In particular
- A block comment at the head of the file
- define directives
- type definitions
- function prototypes, with block comments
describing what they do and how to use them
15Example Personal Library The Stack (cont.)
- Header file for the stack ADT
16Example Personal Library The Stack (cont.)
- The implementation file
- The header file describes what the personal
library can do the implementation file actually
implements the functionality - In particular, an implementation file will look
suspiciously similar to the programs you have
written, except that no main function will be
defined. - Rather, an implementation file contains
- a block comment summarizing the purpose of the
library - include directives (at a minimum, the
corresponding library header file must be
included) - define directives
- type definitions
- documented function definitions
17Example Personal Library The Stack (cont.)
- The implementation file (cont.)
- You might wonder why we need to include the
library header file. Isn't that redundant? - It is, but including it makes maintenance easier
- If any of our define, data structure
definitions, or function prototypes change, we
only need to make such changes in one file,
instead of two
18Example Personal Library The Stack (cont.)
- Implementation file for the stack ADT
19Example Personal Library The Stack (cont.)
- Using the stack ADT
- Believe it or not, the saw mill application could
use the stack ADT as its scrap bin! - Granted, this would be a foolish choice, since
the stack would only be capable of removing from
the scrap bin the most recently added scrap,
Thus, it is likely that the scrap bin wouldn't be
used much, and there would be much more wasted
lumber - Nonetheless, to illustrate the use of the stack
ADT, I have written a version of the Saw Mill
simulation that uses it as the scrap bin. - Let's check out Week15ExampleCode.c for the
details
20Next Lecture
- We'll continue with Chapter 13, "Programming in
the Large" - Storage classes
- Using the "exit" statement in library functions
to gracefully handle bad input - Conditional compilation
- Passing arguments to main
- Defining macros with parameters