C Design Flowcontrol
C Design Flowcontrol
Introduction to C
79
State
The state of a running program can be split into:
Values stored in variables accessible to the program (including dynamically
allocated data structures, if the language allows for those)
Control flow state, including the current point of control (sometimes called
the program counter), and, in languages that allow for recursion, the calling
sequence for functions and procedures (normally represented by some kind of
stack
Assignments change the first part of the state, flow control constructs change
the second part
80
Design Criteria
Efficiency
Imperative languages map naturally to past and current hardware (and are
likely to map well onto hardware build in the forseeable future, too)
This advantage has generally made imperative language designers striving for
efficiently executable language features
Understandability/Structure
Static language features should illustrate the dynamic behaviour of the program,
i.e. it should be easy to understand the dynamic control flow from the static
program text
The language should support abstraction and infomation hiding, i.e. a separation of interface and implementation for new procedures and datatypes
82
Design Criteria II
Scope of Application
Language designers aim at a wide range of applications
Since imperative languages map well to hardware, some language include low
level constructs for manipulating hardware directly
On the other hand, wide portability of code written in the language is achieved
by a strong abstraction from the hardware
Imperative programming is still the predominant programming paradigm, followed
by its off-shot, object-oriented programming
83
84
C
C is a structured, imperative/procedural language, originally developed in 1972
to implement UNIX
C actions and basic data types allow low level programming
Most C datatypes correspond to machine datatypes
C has a (non-standardized, but in practice universal) mechanism for directly
accessing specific memory regions
Cs type system allows the same abstractions as the Algol family, but is more
pragmatic
C supports enough important structuring elements to allow the implementation
of large systems, again often in a very pragmatic way
The C language has a small core, based on just a few principles
The core language can be learned fast, and the average programmer uses a
large part of it
Much functionality is added by (portable and standardized) libraries
85
86
A first C program
Consider the following C program
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
printf("Hello World!\n");
return EXIT SUCCESS;
}
87
C Comilation Environment
A C program typically is build from multiple source files
Header-Files, containing mostly declarations (traditionally with the suffix .h)
Implementation files (suffix .c)
A combination of header file (defining the interface) and implementation file can
be seen as a module
C does not have an elaborate module system
Instead, it achieves a similar result using the combination of the C preprocessor
(which physically combines header files and implementation files) and the
languages scoping rules
88
Headers
(Declarations)
Headers
(Declarations)
Headers
(Declarations)
C Preprocessor
Sources
(Definitions)
Sources
(Definitions)
Sources
(Definitions)
Compiler
Object
Files
Object
Files
Object
Files
System
Library
System
Library
Linker
Includes
Executable
Translates into
RTE
(Shared libs)
Is combibed into
89
93
94
Argument Types
All basic and pointers
Binary *
/
%
+,<, <=,
>=, >
Numerical
Numerical
Integer type
Numerical, (Pointer)
Numerical and pointers
==, !=
&&
||
Description
Logical negation, 1 if arg is 0, 0
otherwise
Multiplication
Division (truncates on int)
Division rest
Addition and subtraction
Size/Adress comparison
Note: All relational operators return 0 if false, 1 if true
Equality (note two equal signs!),
inequality
Logical and, 1 if both arguments
are not zero, 0 otherwise
Logical or, 0 if both arguments are
zero, one otherwise
Assignment operator
99
100
Flow Diagrams
Flow diagrams give a graphical representation of the control flow for a program
or construct
Elements:
Entry point/Exit Point: This is where
the conrol flow starts or ends
Statement (sequence): Represents an
arbitrary sequence of statements, executed sequentially
true
101
Conditional Execution: if
true
E
102
Alternatives: if/else
true
E
S1
S2
Multiple Alternatives
Often, a program has to select between many alternatives, only one of which is
applicable:
E1
true
E2
true
E3
true
S1
S2
S3
S4
Preferred form:
if(E1)
S1
else if(E2)
S2
else if(E3)
S3
[else
S4]
The right hand version is not only more compact, but also shows that the alternatives
are at the same level of abstraction.
104
Loops
A loop repeatedly executes the same statements
Programming languages can support looping either by
A combination of arbitrary branching (goto) and conditional execution or
with dedicated loop constructs
Important questions about loop constructs:
Does the loop always terminate (after a predetermined number of repetitions)?
If a program (or program segment) only contains loop constructs guaranteed
to terminate, overall program termination is guaranteed!
Potentially infinite loops are necessary for full Turing completeness
Potential infinite loops also are (practically) indispensibe for server-type
programs or programs that read arbitrary sized input
Is the loop body executed at least once or can it be skipped totally?
Is the loop single entry/single exit?
Single entry/single exit allows us to argue about program correctness using
loop invariants (assertions about the state that always true at a certain
position in the loop)
111
E
true
Syntax in C:
while(E)
S
S can be a single statement (even the empty statement) or a block of statements
112
repeat
S
until E;
The body of the loop is executed at least once
After the body has been executed, the controlling
expression is evaluated
The loop is terminated, if the controlling expression
evaluates to true, otherwise control returns to the
first statement of the body
E
true
114
115
true
E
Syntax:
do
S
while(E);
116
Example: Uniq
We are looking for a program that eleminates successive occurences the same
element from a sequence
Eample: 1 1 1 2 3 4 4 1 2 2 = 1 2 3 4 1 2
Design idea:
We consider the original sequence as a sequence of sequences of equal characters (where many of the subsequences may have length 1)
Whenever we encounter a new subsequence, we print the first element and
skip all following elements of the same type
117
118
119
Pascal answers:
It is illegal to modify the loop variable in the loop
The limit is only evaluated once (before entering the loop), i.e. modifiying any
variables does not change the loop behaviour
The value of the loop variable after the loop is undefined
The possible values are reached sequentially (increasing for to, decreasing for
downto)
AWK answers:
If you do stupid things, you have to live with the result (everything is
implementation-defined in a cryptic way)
120
C-Style for
A for loop in C is a while-type loop which allows us to combine initialization,
controlling expression and updating in one place
Syntax:
121
122
125
Search in Loops
A frequent use of loops is to search for something in a sequence (list or array) of
elements
First attempt: Search for an element with property P in array
for(i=0; (i< array_size) && !P(array[i]); i=i+1)
{ /* Empty Body */ }
if(i!=array_size)
{
do_something(array[i]);
}
Combines property test and loop traversal test (unrelated tests!) in one
expression
Property test is negated
We still have to check if we found something at the end (in a not very intuitive
test)
Is there a better way?
126
E1
true
Example revisited:
S1
true
E2
S3
S2
Because of the special cases, all the main stuff is hidden away in an else
Wouldnt it be nice to just goto the top of the loop?
128
E1
true
<body>
EC
true
<body>
E3
131
132
Selection of Alternatives
Often, a program has to select between multiple alternatives based on the value
of a single variable:
if(blip == weather_ballon)
{
ignore();
}
else if(blip == airplane)
{
complain_to_ATC();
}
else if(blip == russian_missile)
{
press_red_button();
}
else
{
ufo_alarm();
}
133
Case Distinctions
Many languages offer a dedicated programming construct for case-distinctions
like that
Dedicated constructs may make code easier to read
In many cases, it can be compiled into faster code than a more general
if/else chain
C provides the switch statement:
switch(E)
{
case val1: S1;
case val2: S2;
...
default: Sd;
}
134
The Switch-Statement
switch(E)
{
case val1: S1;
case val2: S2;
...
default: Sd;
}
E has to be an integer-valued expression (this includes enumeration types)
val1, val2,. . . have to be constant integer expressions
E is evaluated and the result is compared to each of the constants after the case
labels. Execution starts with the first statement after the matching case. If no
case matches, execution starts with the (optional) default case.
Note: Execution does not stop at the next case label! Use break; to break out
of the switch
135
Example: switch
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(void)
{
int c;
while((c=getchar())!=EOF){
switch(c)
{
case \n: printf("\\n"); break;
case \t: printf("\\t"); break;
case \r: printf("\\r"); break;
default:
if(isprint(c))
{ putchar(c); }
else
{ printf("\\%03o",c); }
break;
}
}
return EXIT_SUCCESS;
}
136
137