You are on page 1of 102

Algorithms and Programming I

U.L.B. - March 16, 2000

Algorithms and Programming


I
First Year University Studies in Computer Science

B. Mareschal
Campus Plaine - Building NO
Level 3 - Office 2.N.3.214
Phone: 650.5884
e-mail: bmaresc@ulb.ac.be
Summary :
0. Introduction
Algorithms and Programming Modules
Course Organisation
1. Computing & Programming Concepts
Computers, Programming, Languages
2. Introduction to C Programming
Simple Programs, Memory Concepts, Arithmetic in C
2.5 DOS, Windows & the C++ Compilers
Operating Systems, Basic Commands,
Borland C++ and C++ Builder Compilers
3. Structured Program Development
Algorithms, Problem Solving Techniques, Control Structures
4. Program Control
More Control Structures, Logical Operators
5. Functions
6. Arrays
7. Pointers
8. Characters and Strings
9. Formatted Input/Output
-1-

Algorithms and Programming I

U.L.B. - March 16, 2000

0. Introduction
The 'Algorithms and Programming' Modules :
Algorithms and Programming I (B. Mareschal)
Basic programming skills using the C language.
Algorithms and Programming II (M. Dehon)
Advanced programming : structures, pointers, lists, sets, files,
Methods of Programming (D. Leemans)
Stacks, queues, recursion, backtracking, trees, graphs,

Course Organisation :
Textbook(s) :

H.M. Deitel and P.J. Deitel,


C How to Program (2nd edition),
Prentice Hall, 1994, 926p.
Other Reference Books :
Cf. list of references on next page
Time Schedule :
Tuesday Wednesday Thursday Friday
8-10
10-12
Theory
14-16
16-18

Theory

Exercises

Exercises Exercises

Evaluation :

Homeworks (programs)
Exam. in January (Alg.&Pr. I and II)
Computer Room : NO Building, level 4.
-2-

Algorithms and Programming I

U.L.B. - March 16, 2000

Useful references
Textbooks
(http://www.deitel.com)
H. M. Deitel & P. J. Deitel
nd
C How to Program (2 edition)
Prentice Hall, 1994, 926p., ISBN 0-13-226119-7

B. Gottfried
Programming with C (2nd edition)

Schaums Outline Series, McGraw-Hill, 1996, 532p., ISBN 0-07-024035-3

R. Johnsonbaugh & M. Kalin (http://condor.depaul.edu/~mkalin)


C for Scientists and Engineers
Prentice Hall, 1997, 793p., ISBN 0-02-361136-7

K. B. Rojiani
Programming in C with Numerical Methods for Engineers
Prentice Hall, 1996, 1130p. ISBN 0-13-726498-4

H. Schildt
C++ The Complete Reference (2nd edition)
Osborne, McGraw-Hill, 1995, 671p., ISBN 0-07-882123-1

Compilers
K. Reisdorph & K. Henderson
Teach Yourself Borland C++ Builder in 14 days

Borland Press, Sams Publishing, 1997, 526p., ISBN 0-672-31051-1

Language Reference
B. W. Kernighan & D. M. Ritchie
The C Programming Language (2nd edition)
Prentice Hall, 1989, 274p., ISBN 0-13-110362-8.

B. Stroustrup
The C++ Programming Language (3rd edition)
Addison Wesley Series in Computer Science, 1997, 928p., ISBN 0-201-88954-4.

Algorithms
L. Ammeraal
Algorithms and Data Structures in C++
Wiley, 1996, 352p., ISBN 0-471-96355-0

R. Sedgewick
Algorithms in C

Addison Wesley, 1990, 657p., ISBN 0-201-51425-7

R. Sedgewick
Algorithms in C++

Addison Wesley, 1992, 656p., ISBN 0-201-51059-6


-3-

Algorithms and Programming I

U.L.B. - March 16, 2000

1. Computing & Programming Concepts


Programming ?
A few definitions :

Programming :
Planning, scheduling or performing a task or an event.
Computer :
Programmable device that can store, retrieve and process data.
Computer Programming :
Process of planning a sequence of steps for a computer to
follow.
Computer Program :
List of instructions to be performed by a computer.

The process of writing a program :


Two phases
Problem-Solving Phase :
1 Analysis and Specification :
What is the problem ? What do we want to do ?
2 General solution (Algorithm) :
Define the sequence of steps to be used to solve the problem.
3 Verify :
Does the solution really solve the problem ?
Implementation Phase :
1 Specific solution (Program) :
Translation of the general solution into a computer language.
2 Test :
Check for errors and eventually make corrections.
-4-

Algorithms and Programming I

U.L.B. - March 16, 2000

A third phase

Maintenance Phase :
1 Use :
Use the program.
2 Maintain :
Modify the program if necessary : new requirements, errors.

Program Life Cycle :

Problem-Solving
Analysis
and
Specification
General Solution
(Algorithm)

Implementation

Maintenance

Specific Solution
(Program)

Use

Test

Maintain

Verify

More definitions ...

Algorithm :
Step-by-step procedure for solving a problem in a finite
amount of time.
Examples :
recipes, instructions, ...
-5-

Algorithms and Programming I

U.L.B. - March 16, 2000

Programming Language :
Set of rules, symbols and special words used to construct a
program.
Problem-Solving
Algorithm
Implementation

Coding

Program

Documentation :
Written text and comments that make a program easier for
others to understand, use and modify.
Development of programming languages :
Machine language
+1300042774
+1400593419
+1200274027

Assembly language
LOAD
ADD
STORE

BASEPAY
OVERPAY
GROSSPAY

High level language


GrossPay = BasePay
+ OverTimePay

Machine Language :
Language made up of binary-coded instructions, that is used
directly by the computer.
Assembly Language :
Low-level programming language in which mnemonics are
used to represent the different machine language instructions.
Assembler :
Program that translates an assembly language program into
machine code.
High-level Language :
-6-

Algorithms and Programming I

U.L.B. - March 16, 2000

Closer to English and human thought, easier to use, less


machine-dependent.
Examples : Fortran (1954-57), Cobol (1959), Pascal (1971),
Modula-2, C (1972), C++, APL, Ada (1980), (Basic), ...

Compiler :
Program used to translate a high-level language into machine
code.
Input = program in high-level language = source program.
Output = machine language program
= object program.
Compilation Execution

Main types of instructions found in a programming


language :
- transfer of data,
- input and output of data (from/to I/O devices),
- storage and retrieval of data from memory and secondary
storage,
- comparison of data ( = ?, ?),
- arithmetic operations (+, , x, ).

Main structures found in programming languages :


- sequence of statements (instructions),
- selection of different statements according to some
conditions,
- repetition of statements (loop) while certain conditions are
met,
- functions or subprograms.
-7-

Algorithms and Programming I

U.L.B. - March 16, 2000

What is a Computer ?

Five main components :

Memory Unit :
Internal data storage in a computer (RAM).

Central Processing Unit (CPU) :


Part of the computer that executes the instructions stored in
memory. Includes two subparts :
Arithmetic and Logic Unit (ALU) :
Performs the arithmetic and logical operations.
Control Unit :
Controls the sequence of the instructions.

-8-

Algorithms and Programming I

U.L.B. - March 16, 2000

Input/Output (I/O) devices :


Parts of the computer that accept data to be processed (input)
and display the results of the processing (output).

Peripheral devices :
- additional I/O devices, secondary storage devices, ...

-9-

Algorithms and Programming I

U.L.B. - March 16, 2000

Problem-Solving Techniques

Ask questions :
Gather information about the problem to solve.

Look for things that are familiar :


Do not reinvent the wheel.

Solve by analogy :
Adapt solutions from similar problems.

Means-Ends analysis :
Consider the actions possible to solve the problem.

Divide and Conquer :


Break up large problems into smaller, easier ones.

Building blocks approach :


Look for existing solutions for sub-problems..

Merging solutions :
Combine existing solutions.

- 10 -

Algorithms and Programming I

U.L.B. - March 16, 2000

2. Introduction to C Programming
A first program in C
C code :
/* A first program in C */
main()
{
printf(Welcome to
}

C !\n);

Output :
Welcome to C !

Analysis :
/* A first program in C */

/*

and */ indicate the beginning and the end of a comment.

main()

The main() function indicates the beginning of the program.


Every C program contains it and starts executing at this
function.

- 11 -

Algorithms and Programming I

U.L.B. - March 16, 2000

The left brace { indicates the beginning of the body of the


main() function. A corresponding right brace must end the
body of the function.
printf(Welcome to

C !\n);

This is a statement. It instructs the computer to print the string


of characters enclosed between the double quotes. printf() is
a pre-defined function included in the C standard library.
\n is not printed, it is an escape sequence that instruct the
computer to position the cursor to the beginning of the next
line (newline). \ is an escape character.
Common escape sequences :
\n
new line,
\\
prints a backslash,
\
prints a double quote.
Other examples of the printf() statement :
main()
{
printf(Welcome );
printf(to C !\n);
printf(Welcome\nto\nC ! \n);
}

Each C statement is terminated by a semi-colon ;


}

The right brace } indicates the end of the body of the main()
function.

- 12 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Second program : Adding two integers


C code :
/* Addition program */
#include <stdio.h>
main()
{
int integer1, integer2, sum;
printf(Enter first integer :\n);
scanf(%d, &integer1);
printf(Enter second integer :\n);
scanf(%d, &integer2);
sum = integer1 + integer2;
printf(Sum is %d\n, sum);
return 0;

/* declaration */
/*
/*
/*
/*
/*

prompt */
read integer1 */
promt */
read integer2 */
assignment */
/* print sum */

/* indicates successful program termination */

Output :
Enter first integer :
23
Enter second integer :
54
Sum is 77

- 13 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Analysis :
#include <stdio.h>

This is a directive to the C preprocessor.


Used to include the standard I/O header file.
int integer1, integer2, sum;

This is a declaration :

are the names of variables, i.e.


locations in memory where values can be stored for use by a
program.
int determines the type of the variables, i.e. the kind of data
they will hold, in this case integer values.
All variables must be declared before they can be used.
Declarations are placed after the left brace of the function,
before any executable statement.
Variable names must be valid identifiers : a series of letters,
digits and underscore ( _ ) characters that doesnt begin with a
digit. Up to 31 characters are recognized.
Warning : C is case sensitive.
integer1, integer2, sum

- 14 -

Algorithms and Programming I

U.L.B. - March 16, 2000

scanf(%d, &integer1);

Call to the standard function scanf to obtain a value from the


user (keyboard), with two arguments :
Format control string : %d
The conversion specifier %d indicates the type of data that
should be input :
% is an escape character and d stands for decimal integer
read one decimal integer from keyboard.
Second argument : &integer1
& is the address operator. &integer1 gives the location in
memory (address of the variable integer1) where the value
should be stored.
sum = integer1 + integer2;

Assignment statement :
The expression on the right side of the assignment operator =
is computed.
The result is assigned to the variable on the left side.
= reads as gets , not equals .
Both = and + are binary operators (with two operands).
printf(Sum is %d\n, sum);

Other form of the printf statement, with two arguments :


Format control string including a conversion specifier.
Value to be printed (could be an expression as well).
return 0;

Indicates that the program executed successfully by returning


the value 0 to the operating system.
- 15 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Memory Concepts

Variable names correspond to locations in the computers


memory (RAM).
Each variable has a name, a type and a value.
integer1

23

Variables are not initialised automatically : value undefined


after the declaration !
A new values overwrites the previous one (destructive readin).

Arithmetic in C

Arithmetic operators : 5 binary operators


Operation
Addition
Subtraction
Multiplication
Division
Modulus

C Operator

Example

x + y

t - 2

2 * Pi * Radius

x / t

a % b

Integer division yields an integer result :


7 / 4 1
- 16 -

Algorithms and Programming I

U.L.B. - March 16, 2000

The modulus operator is an integer operator (integer operands


only) :
7 % 4 3

34 % 7 6

Parentheses can be used in arithmetic expressions :


a * ( b + c )

Operator precedence : Determines the sequence of evaluation


in complex expressions.
1. (Sub-)expressions within parentheses are evaluated first.
2. Multiplications, divisions and modulus operations are
evaluated next, from left to right.
3. Additions and subtractions are evaluated last, from left to
right.

Some examples :
m = (a + b + c + d + e) / 5;
m = a + b + c + d + e

5;

y = m * x + b;
z = p * r % q + w / x - y;
k = 12 * (a * (b + c) + c * (d + e))

- 17 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Equality and Relational Operators


Standard Operator
Equality
=

Relational
>
<

C Operator

Example

==

x == y

!=

x != y

>

x > y

<

x < y

>=

x >= y

<=

x <= y

Equality operators have a lower precedence level than the


relational operators.

All these operators associate from left to right.

In C, False correspond to 0 and True to any nonzero


value.

Example (using the if control structure) :

- 18 -

Algorithms and Programming I

U.L.B. - March 16, 2000

C code :
#include <stdio.h>
main()
{
int num1, num2;
printf(Enter two integers : );
scanf(%d%d, &num1, &num2);
if (num1 == num2)
printf(%d is equal to %d\n, num1, num2);
if (num1 != num2)
printf(%d is not equal to %d\n, num1, num2);
if (num1 < num2)
printf(%d is less than %d\n, num1, num2);
if (num1 > num2)
printf(%d is greater than %d\n, num1, num2);
if (num1 <= num2)
printf(%d is less than or equal to %d\n,
num1, num2);
if (num1 >= num2)
printf(%d is greater than or equal to %d\n,
num1, num2);
return 0;
}

Summary of the Precedence Levels


- 19 -

Algorithms and Programming I

U.L.B. - March 16, 2000

From highest to lowest

Associativity
left to right
left to right
left to right
left to right
left to right
right to left

( )
*

<

<=

>

>=

== !=
=

Reserved Keywords in the C language


auto
const
double
float
int
short
struct
unsigned

break
continue
else
for
long
signed
switch
void

case
default
enum
goto
register
sizeof
typedef
volatile

- 20 -

char
do
extern
if
return
static
union
while

Algorithms and Programming I

U.L.B. - March 16, 2000

2.5 DOS, Windows and the Borland C++


Compiler
Using a PC :

Structure :
1 Central Unit
- CPU
- Disk drives (floppy, hard, CD-Rom)
- Expansion slots (disk controller, video, I/O,
network, modem, ...)
2 Keyboard
3 Monitor
4 Mouse, scanner, digitizer, joystick, ...
5 Printer, plotter, ...

Boot :
1 Turn computer on !
2 Memory check.
3 Loading drivers (network, mouse, CD-Rom,
memory manager, ...).
4 DOS prompt or Windows.

Operating system :
Program(s) responsible for the I/O management. Provides
services to the programs and a user interface.
Examples :
MS-DOS, OS/2, Windows 3.1, Windows 95/98, Unix, ...
- 21 -

Algorithms and Programming I

U.L.B. - March 16, 2000

The DOS operating system :

File organisation :
- Drives : refer to physical devices (diskette drive, hard disk,
CD-Rom drive, network server, ...) or logical devices (RAM
disk, ...)
Drives are named using letters :
A:

B:

C:

D:

...

- Files : Names of up to 8 characters, plus a (up to) 3


characters extension.
Examples :
TEST1.PAS
DUMP.TXT

TEST1.EXE
EMPLOYEE.DB

- Directories : refer to a group of files and/or sub-directories,


designated by a name (similar to file names).
Hierarchical structure of the directories :
root directory
C:\PROGRAMS.DIR sub-directory of the root
C:\PAYROLL.PAS file of the root
C:\PROGRAMS.DIR\EDIT.EXE
file of the PROGRAMS.DIR
directory
C:\

C:\DATA\SALES\REGIONAL\BRUSSELS.DAT
C:BRUSSELS.DAT

file of the current directory

Some useful DOS commands :


DIR
- Directories :
COPY
- Files :
FORMAT
- Format :
TYPE
- View and edit files :
MORE
- Others :
- 22 -

CD

MD

REN

DEL

PRINT

EDIT

MEM

CHKDSK

RD

MOVE

Algorithms and Programming I

U.L.B. - March 16, 2000

The Windows 3.11 operating system :

Graphical User Interface : On top of MS-DOS.

Starting Windows : Type

Program Manager : Used to start programs.


Program groups represented by icons within windows.

Using the mouse :


Buttons.
Clicking.
Double-clicking.
Dragging.

Windows :
Control menu.
Minimize and Maximize buttons.
Resizing and deplacing.
Menus.

Exiting Windows : From the File menu of Program


Manager.

WIN

at the DOS prompt.

The Borland C++ compiler :


Borland C++ 4.0 4.5 5.02 C++ Builder
- 23 -

Algorithms and Programming I

U.L.B. - March 16, 2000

3. Structured Program Development


Using Pseudocode

Informal language, helpful for developing algorithms.


Written in English.
Describe actions only.
Easy to translate in C.

Using Flowcharts

Graphical representation of an algorithm.


Actions are represented by rectangles.
The sequence of the actions is represented by arrows.
Oval symbols indicate the beginning and end of an algorithm.
Small circles indicate the beginning and end of a portion of an
algorithm.
Diamonds indicate that a decision is to be made.

false

grade = 12

print "Failed"

true

print "Passed"

- 24 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Structured Programming

Normally, sequential execution of the statements in a


program.

Transfer control must be possible to deviate from the


sequential execution (selections, repetition of instructions, ...)

First possibility : the goto statement.

if grade 12 go to A
print Failed
go to B
A: print Passed
B: ...

A: print Press C to continue


read character from keyboard
if character C go to A
continue ...

difficult to read and to maintain, error prone.

Structured programming (1970s) :

if grade 12 then
print Failed`
else
print Passed

goto-less

programming

do
print Press C to continue
read character from keyboard
while character C

control structures.
- 25 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Control Structures
Sequence, Selection and Repetition

Sequence structure :
Normal behaviour, one statement after the other in the order in
which they are written.

Selection structures :
1 Single-selection structure :

if

2 Double-selection structure :

if/else

3 Multiple-selection structure :

switch

Repetition structures :
1 while
2

do/while

for

Combination of control structures :


1 Stacking (building blocks approach).
2 Nesting (structures within structures).

- 26 -

Algorithms and Programming I

U.L.B. - March 16, 2000

The if Structure

Pseudocode :
If students grade is greater than or equal to 12
Print Passed

C code :
if (grade >= 12)
printf(Passed\n);

Remark : Proper indentation makes a program easier to read.

The if/else Structure

Pseudocode :
If students grade is greater than or equal to 12
Print Passed
else
Print Failed

C code :
if (grade >= 12)
printf(Passed\n);
else
printf(Failed\n);

Remark : conditional operator ? (ternary)


printf(%s\n, grade >= 12 ? Passed : Failed);

- 27 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Nested if/else structures :


Pseudocode :
If students grade greater than or equal to 18
Print La Plus Grande Distinction
else
If students grade greater than or equal to 16
Print Grande Distinction
else
If students grade greater than or equal to 14
Print Distinction
else
If students grade greater than or equal to 12
Print Satisfaction
else
Print Ajournement
C code :

if (grade >= 18)


printf(LPGD\n);
else
if (grade >= 16)
printf(GD\n);
else
if (grade >= 14)
printf(D\n);
else
if (grade >= 12)
printf(S\n);
else
printf(A\n);

if (grade >= 18)


printf(LPGD\n);
else if (grade >= 16)
printf(GD\n);
else if (grade >= 14)
printf(D\n);
else if (grade >= 12)
printf(S\n);
else
printf(A\n);

- 28 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Use of compound statements :


A compound statement is a series of statements enclosed by
braces :
{
printf(Failed\n);
printf(Try again next year.\n);
}

Compound statements can replace single statements in control


structures :
if (grade >= 12)
{
printf(Passed\n);
printf(Congratulations.\n);
}
else
{
printf(Failed\n);
printf(Try again next year.\n);
}

- 29 -

Algorithms and Programming I

U.L.B. - March 16, 2000

The while Structure

Example :
Find the first power of 2 larger than 1000.

Pseudocode :
Set product equal to 2
while product is less than or equal to 1000
multiply product by 2

C code :
product = 2;
while (product <= 1000)
product = 2 * product;

A more complete version :


#include <stdio.h>
main()
{
int product, power;
product = 2;
power = 1;
while (product <= 1000)
{
product = 2 * product;
power = power + 1;
}
printf(2 to the power %d = %d\n, power, product);
return 0;
}

- 30 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Formulating algorithms - I

Problem :
The grades of a class of ten students are available. Determine
the class average.

Pseudocode :
Set total to 0.
Set grade counter to 1.
While grade counter is less than or equal to 10 :
Input the next grade.
Add the grade to the total.
Add 1 to the grade counter.
Set the class average equals to the total divided by 10.
Print the class average.

Remarks :
1 counter-controlled repetition
The number of repetitions is known (10) and is controlled by a
counter (variable).
2 initialisation of the variables.

C code :
/* Class average calculation I */
#include <stdio.h>
main()
{
int counter, grade, total, average;
- 31 -

Algorithms and Programming I

U.L.B. - March 16, 2000

total = 0;
counter = 1;
while (counter <= 10) {
printf(Enter grade : );
scanf(%d, &grade);
total = total + grade;
counter = counter + 1;
}
average = total / 10;
printf(Class average is %d\n, average);
return 0;
}

Remarks :
1 Integer division integer average !
2 Checking data input :
while (counter <= 10) {
grade = 21;
while (grade > 20) {
printf(Enter grade : );
scanf(%d, &grade);
}
total = total + grade;
counter = counter + 1;
}

- 32 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Formulating algorithms - II

Problem :
Determine the class average for an arbitrary number of
students (not known in advance).

Solution :
Use a sentinel value, i.e. a special value that indicate that all
the data have been entered.
For grades, the sentinel should be outside of the 0-20 range.
When the user enters the sentinel value, the input process
stops.

Pseudocode :
Top-down approach. (stepwise refinement)
- top level : overall function of the program :
Determine the class average.
- 1st refinement : main tasks to perform :
Initialize variables.
Input, sum and count the grades.
Calculate and print the class average.

- 33 -

Algorithms and Programming I

U.L.B. - March 16, 2000

- 2nd refinement :
Initialize total to 0.
Initialize counter to 0.
Input the first grade.
While the user has not entered the sentinel :
Add this grade to the running total.
Add 1 to the counter.
Input the next grade.
If the counter is not equal to 0 :
Set the average equals to the total divided by the counter.
Print the average.
else :
Print No grades were entered.
Sufficient refinement for translation to C language.

C code :
/* Class average II */
#include <stdio.h>
main()
{
float average;
/* floating point data type */
int counter, grade, total;

- 34 -

Algorithms and Programming I

U.L.B. - March 16, 2000

total = 0;
counter = 0;
printf(Enter grade (-1 to end) : );
scanf(%d, &grade);
while (grade != -1) {
total = total + grade;
counter = counter + 1;
printf(Enter grade (-1 to end) : );
scanf(%d, &grade);
}
if (counter != 0) {
average = (float) total / counter; /*type cast*/
printf(Class average is %.2f\n, average);
}
else
printf(No grades were entered.\n);
return 0;
}

Remarks :
1 New data type, for floating point (real) numbers.
2 Type cast to ensure that average is computed correctly.
3 Conversion specifier %.2f prints a floating point value with
two decimal digits to the right of the decimal point.

- 35 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Formulating algorithms - III

Problem :
We have to analyze the results of a test for a group of 10
students, as follows :
1. Input the results (either 1: passed or 2: failed).
2. Count the number of results of each type.
3. Display a summary of the results : number of students who
passed and number of students who failed.
4. If more than 8 students passed, print a warning message.

Remarks :
1. 10 students counter-controlled loop.
2. Data are either 1 or 2.
3. Two counters needed : passes and failures.

- 36 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Pseudocode : Top-down approach


- top level :
Analyze test results.
- 1st refinement :
Initialize variables.
Input the ten results and count passes and failures.
Print a summary and decide whether warning message
should be printed.
- 2nd refinement :
Initializes passes to 0.
Initializes failures to 0.
Initialize student counter to 1.
While student counter is less than or equal to 10 :
Input the next test result.
If the student passed
Add 1 to passes.
else
Add 1 to failures.
Add 1 to student counter.
Print number of passes.
Print number of failures.
If more than 8 students passed :
Print warning message.
- 37 -

Algorithms and Programming I

U.L.B. - March 16, 2000

C code :
/* Test results analysis */
#include <stdio.h>
main()
{
int passes = 0, failures = 0, student = 1, result;
while (student <= 10) {
printf(Enter result (1:pass, 2:fail) : );
scanf(%d, &result);
if (result == 1)
passes = passes + 1;
else
failures = failures + 1;
student = student + 1;
}
printf(Passed : %d\n, passes);
printf(Failed : %d\n, failures);`
if (passes > 8)
printf(Course too easy!\n);
return 0;
}

Remark :
Variables can be initialized whithin the declaration statement.

- 38 -

Algorithms and Programming I

U.L.B. - March 16, 2000

More Assignment Operators

First example :

x = x + 5

Allowed with other binary operators :


+=

Advantage : faster.

Second example :
x = x + 1

x += 5

-=

*=

/=

%=

x++

or

++x

Unary increment and decrement operators :


1 Preincrement : increment first, then evaluate
++x

(--x)

2 Postincrement : evaluate first, then increment


x++

(x--)

Examples :
x = 2;
printf(%d\n,
printf(%d\n,
printf(%d\n,
y = x-- + 2;
printf(%d\n,
printf(%d\n,

x++);
x);
++x);

Output :
2
3
4

y);
x);

6
3

y = ++x + 2 * x;

- 39 -

Algorithms and Programming I

U.L.B. - March 16, 2000

4. Program Control
Repetition Structures :
Counter-controlled vs Sentinel-controlled

Counter-controlled repetition :
- definite repetition : number of iterations known in advance,
- use of a counter variable that is incremented at each
iteration.

Sentinel-controlled repetition :
- indefinite repetition : number of iterations not known in
advance,
- use of a sentinel value that indicates the end of the data.

- 40 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Counter-controlled repetition

Requires :
1 A control variable,
2 The initial value of the conrol variable,
3 The increment (decrement) of the control variable at each
iteration,
4 The condition that tests for the final value of the control
variable.

Example :
/* Prints numbers from 1 to 10 */
#include <stdio.h>
main()
{
int counter = 1; /* control var. decl. & init. */
while (counter <= 10) {
/* condition */
printf("%d\n", counter);
++counter;
/* increment */
}
return 0;
}

Remarks :
1 Variables can be initialized within their declaration.
2 More concise form :
#include <stdio.h>
main()
{
int counter = 0;
while (++counter <= 10)
printf("%d\n", counter);
return 0;
}

- 41 -

Algorithms and Programming I

The

U.L.B. - March 16, 2000

for

Repetition Structure

Especially designed for counter-controlled repetition :


for ( initialization; condition; increment)
loop_body;

(mostly) equivalent to :
initialization;
while (condition) {
loop_body;
increment;
}

Example :
/* Prints numbers from 1 to 10 */
#include <stdio.h>
main()
{
int counter;
for (counter = 1; counter <= 10; counter++)
printf("%d\n", counter);
return 0;
}

Remarks :
1 The three expression in the for structure are optional.
2 Multiple, comma-separated, expressions can be used as
initialization and increment.
3 The increment may be negative (decrement).

- 42 -

Algorithms and Programming I

U.L.B. - March 16, 2000

4 Flowchart :

initialization

condition

true

loop_body

false

Some other examples :


1 Use of expressions :
x = 2; y = 10;
for (j = x; j <= 4 * x * y; j += y / x)
printf("%d\n");

is equivalent to :
for (j = 2; j <= 80; j += 5)
printf("%d\n");

2 From 1 to 100 in increments of 1 :


for (i = 1; i <= 100; i++)

3 From 100 to 1 in increments of 1 :


for (i = 100; i >= 1; i--)

4 From 7 to 77 in steps of 7 :
for (i = 7; i <= 77; i += 7)

- 43 -

increment

Algorithms and Programming I

U.L.B. - March 16, 2000

5 From 20 to 2 in steps of 2 :
for (i = 20; i >= 2; i -= 2)

6 Sum all even integers from 2 to 100 :


#include <stdio.h>
main()
{
int sum = 0, number;
for (number = 2; number <= 100; number += 2)
sum += number;
printf("Sum is %d\n", sum);
return 0;
}

equivalent to :
int sum, number;
for (sum = 0, number = 2; number <= 100;
sum += number, number += 2);

7 Calculate compound interest :


1000 BEF invested during 10 years on a savings account that
yields 5 percent annual interest. Corresponding amount of
money at the end of each year (1 to 10) ?
#include <stdio.h>
#include <math.h>
main()
{
int year;
double amount, principal = 1000.0, rate = 0.05;
printf("%4s%21s\n", "Year", "Amount on deposit");
- 44 -

Algorithms and Programming I

U.L.B. - March 16, 2000

for (year = 1; year <= 10; year++) {


amount = principal * pow(1.0 + rate, year);
printf("%4d%21.2f\n", year, amount);
}
return 0;
}

Output :
Year
1
2
3
4
5
6
7
8
9
10

Amount on deposit
1050.00
1102.50
1157.62
1215.51
1276.28
1340.10
1407.10
1477.46
1551.33
1628.89

Remarks :
1 Library math.h : includes function pow :
pow(a, b) returns a to the power b where a and b are double.
2 double : floating-point data type with higher precision than
float.
3 Both arguments of pow are of type double and year is of
type int. Automatically converted.
4 Would be better to use int for monetary amounts
(precision).

- 45 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Numbers and Precision

Computers memory :
Sequence of storage places. To each place is associated an
address (index).
1

15

16

10

17
18
H
e
25
26
27
28
2.357412e012

19
l
29

20
l
30

137
11

12

13

14

21
o

22

23

24

Bits, bytes and words :


- Fundamental data unit : 0-1 bit (binary digit)
- Byte : sequence of eight (23) bits.
- Word : 2 bytes (16 bits),
- Double-word : 4 bytes (32 bits).

Decimal representation of numbers :

base 10 digits 0-9

235 = 2102 + 3101 + 5100

Binary representation of numbers :

base 2

digits 0-1

235 = 111010112 =
127 + 126 + 125 + 024 + 123 + 022 + 121 + 120
- 46 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Octal representation of numbers :

base 8

digits 0-7

235 = 3538 = 382 + 581 + 380

Hexadecimal representation of numbers : base 16 digits 0-F


0 1 2 3 4 5 6 7 8 9 A B C D E F
235 = EB16 = 14161 + 11160

Representation of data in memory : binary


- on 1 byte :
128 64

32

16

largest positive integer :


128 64

255

32

16

for signed numbers : twos complement notation


1 The leftmost bit indicates whether the number is positive or
negative : 0: positive, 1: negative.
2 To convert a number (change sign) :
- negate each bit ( 0 1 and 1 0 ),
- add 1 to the result :
21 = 000101012

-21 = 111010102 + 000000012 = 111010112


3 Maximum and minimum values :
- minimum :
100000002 = -128
- maximum :
011111112 = 127
- 47 -

Algorithms and Programming I

U.L.B. - March 16, 2000

- on 2 bytes :
...

...

...

...

...

1024

512 256 128

largest positive integer :


...

...

...

...

...

1024

32

16

64

32

16

65535

512 256 128

64

Limited range and limited precision.


Possible overflow errors.
Possible rounding errors with floating point numbers.

C Data types :
Type

16-bit

32-bit

Bytes

Range

Bytes

Range

unsigned
char
char

0 to 255

0 to 255

-128 to 127

-128 to 127

short int

-32768 to 32767

-32768 to 32767

unsigned int

0 to 65535

0 to 4294967295

int

-32768 to 32767

-2147483648 to 2147483647

enum

-32768 to 32767

-2147483648 to 2147483647

unsigned
long
long

0 to 4294967295

0 to 4294967295

-2147483648 to 2147483647

-2147483648 to 2147483647

float

3.4 10-38 to 3.4 10+38

3.4 10-38 to 3.4 10+38

double

1.7 10-308 to 1.7 10+308

1.7 10-308 to 1.7 10+308

long double

10

3.4 10-4932 to 3.4 10+4932

10

3.4 10-4932 to 3.4 10+4932

near (pointer)

far (pointer)

- 48 -

Algorithms and Programming I

The

do/while

U.L.B. - March 16, 2000

Repetition Structure

Syntax :
do {
loop_body;
} while (condition);

Contrarily to the while structure, the condition is tested after


the loop body has executed.

The loop body is always executed at least once.

Example : Print the ten first positive integers on a single line.


#include <stdio.h>
main()
{
int counter = 1;
do {
printf(%d , counter);
} while (++counter <= 10);
return 0;
}

Remark : Use of braces (not required, but useful to avoid


confusion with while).

- 49 -

Algorithms and Programming I

The

switch

U.L.B. - March 16, 2000

Multiple-Selection Structure

Example : Counting letter grades (A,B,C,D,F) for a class of


students.
#include <stdio.h>
main()
{
int grade;
int aCount = 0, bCount = 0, cCount = 0, dCount = 0,
fCount = 0;
printf(Enter the letter grades.\n);
printf(Enter the EOF character to end input.\n);
while ( (grade = getchar()) != EOF ) {
switch (grade) {
case A: case a:
++aCount;
break;
case B: case b:
++aCount;
break;
case C: case c:
++aCount;
break;
case D: case d:
++aCount;
break;
case F: case f:
++aCount;
break;
case \n: case :
break;
default:
printf(Incorrect letter entered.\n);
printf(Enter a new grade.\n);
break;
}
}
printf(\nTotals for each letter grade : \n);
- 50 -

Algorithms and Programming I

printf(A:
printf(B:
printf(C:
printf(D:
printf(F:

U.L.B. - March 16, 2000

%d\n,
%d\n,
%d\n,
%d\n,
%d\n,

aCount);
bCount);
cCount);
dCount);
fCount);

return 0;
}

Remarks :
- Multiple-selection according to the value of an integer (or
character) expression.
- getchar() reads one character from the keyboard and returns
it. Characters are read one at a time after the user presses the
Enter key. Different from scanf : one character at a time,
including blanks, newline , ...
- Characters correspond to 1-byte integers can be used
either way :

printf(The character (%c) has the value %d.\n, a, a);

- Character constants are enclosed by single quotes.


- EOF (End Of File) correspond to a system dependent
keystroke (for DOS : ctrl-z).
- break is used to exit the structure (not required, but ...).
- cases are just labels.
- default is optional.

gotos

and labels :

(contrary to structured programming)

i = 0;
again:
printf(%d\n, i++);
if (i <= 10) goto again;

- 51 -

Algorithms and Programming I

The

break

U.L.B. - March 16, 2000

and

continue

Statements

Used to alter the flow of control. Rather contrary to structured


programming use with care.
When executed within a while, for, do/while or switch
structure :
- break causes the immediate exit from the structure,
- continue skips the remaining statements in the body of the
structure and continues with the loop.
Examples :
#include <stdio.h>
main()
{
int x;
for (x = 1; x <= 10; x++) {
if (x == 5)
break;
printf(%d , x);
}
printf (\nBroke out of loop at
return 0;
}

== %d\n, x);

#include <stdio.h>
main()
{
int x;
for (x = 1; x <= 10; x++) {
if (x == 5)
continue;
printf(%d , x);
}
printf (\Used continue to skip printing 5\n);
return 0;
}

- 52 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Logical Operators
AND, OR and NOT
Operator :
in C :

AND

OR

NOT

&&

||

A && B

0
0
0
0

0
0
0
0

0
0
0
1

A || B

0
0
0
0

0
1
1
1

0
0
0

Examples :
if (gender ==1 && age >= 65)
++seniorFemales;
if semesterAverage >= 90 || finalExam >= 90)
printf(Student grade is A\n);
if (!(grade == sentinelValue))
printf(The next grade is %f\n, grade);

which is equivalent to :
if (grade != sentinelValue)
printf(The next grade is %f\n, grade);

- 53 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Precedence Levels (completed)


From highest to lowest

Associativity
left to right
right to left
left to right
left to right
left to right
left to right
left to right
left to right
right to left
right to left
left to right

( )
++

--

-(unary)
*

<

(type)

<=

>

>=

== !=
&&
||
?:
=

+=

-=

*=

/=

%=

Caution:
Confusing == (equality) and

Example 1 :
if (payCode == 4)
printf(You get a bonus !);
if (payCode = 4)
printf(You get a bonus !);

Example 2 :
x = 1;
x == 1;

- 54 -

(assignment)

Algorithms and Programming I

U.L.B. - March 16, 2000

5. Functions

Modularity : Divide and Conquer


- Construct a large program from smaller pieces (modules).
- Divide the program into logically consistent parts.
Facilitates program development and maintenance.
Allows reusability of modules.

In C :

Functions

- Standard functions :
printf

scanf

from the C standard library :


pow

getchar

- User-defined functions : written by the programmer.

Function call :
- Specifies the function name as well as arguments
(information that is passed to the function).
printf(%d, number);

pow(2.5, 2);

- Usually the function returns a piece of information to the


calling function.
ch = getchar();

result = pow(2.5, 2);

Local variables :
Variables that are declared within a function. They are known
only within the function.

- 55 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Math Library Functions

Header file :
#include <math.h>

All math functions return a value of type double.

Main functions available in the math library :


(x and y are of type double)
Function
sqrt(x)
exp(x)

Description
square root of x
exponential

log(x)

natural logarithm

log10(x)

base 10 logarithm

fabs(x)

absolute value

ceil(x)

smallest integer x

floor(x)

largest integer x

pow(x,y)

x raised to power y

fmod(x,y)

remainder of x / y
sine of x (radians)
cosine of x
tangent of x

sin(x)
cos(x)
tan(x)

- 56 -

Example
sqrt(25.0) : 5.0
exp(1.0) : 2.718282
exp(2.0) : 7.389056
log(2.718282) : 1.0
log(7.389056) : 2.0
log10(1.0)
: 0.0
log10(10.0) : 1.0
log10(100.0) : 2.0
fabs(12.5) : 12.5
fabs(-5.0) : 5.0
ceil(7.3) : 8.0
ceil(-1.5) : -1.0
floor(7.3) : 7.0
floor(-1.5) : -2.0
pow(4, 3)
: 64.0
pow(9, 0.5) : 3.0
fmod(14, 2.5) : 1.5
sin(0.0) : 0.0
cos(0.0) : 1.0
tan(0.0) : 0.0

Algorithms and Programming I

U.L.B. - March 16, 2000

Function Definition

Example 1 :
/* Prints the squares of integers 1 to 10 */
#include <stdio.h>
int square(int);

/* function prototype */

main()
/* main function */
{
int x;
for (x=1; x <= 10; x++)
printf(%d , square(x));
printf(\n);
return 0;
}
int square(int y)
{

/* function definition */

return y * y;
}

2 parts :
1 Function prototype : useful for checking syntax,
2 Function defintion : general format :
return_value_type function_name(parameter_list)
{
declarations
statements
}

- 57 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Function definition :
- function_name is any valid identifier.
- return_value_type indicates the data type of the result
returned to the caller. Two special cases :
- void indicates that no value is returned by the function,
- int is assumed if no return_value_type is specified.
- parameter_list is a comma-separated list containing the
declarations of the parameters :
- each parameter is declared separately (type),
- void is used if there are no parameters,
- int is assumed if no type is specified.
- The braces determine the function body. It is a block
(compound statement including declarations).

Function call :
- Using the function_name followed by a comma-separated
list of arguments.
- A copy of the actual arguments value is passed to the called
function and is associated to the corresponding parameter in
the function The actual argument value cannot be
modified by the function (security: avoid side effects).
Example of potential side effect :
int ipower(int a, int b) /* computes a to the power b */
{
int c = a;
while (b > 1) {
c *= a;
b--;
}
return c;
}

- 58 -

Algorithms and Programming I

U.L.B. - March 16, 2000

- Control returns to the calling function (next statement) when


either the function end is reached (closing brace) or when a
return statement is executed :
return;
return expression;
(no returned value) or
- Parameters and local variables values are temporary :
available only during one function call, destroyed when the
function returns.

Example 2 :
/* Finds the maximum of three integers */
#include <stdio.h>
int maximum(int, int, int); /* prototype */
main()
{
int a, b, c;
printf(Enter three integers : );
scanf(%d%d%d, &a, &b, &c);
printf(The maximum is : %d\n, maximum(a, b, c));
return 0;
}
int maximum(int x, int y, int z)
{
int max = x;
if (y > max)
max = y;
if (z > max)
max = z;
return max;
}

Function prototype : Borrowed from C++.

- 59 -

Algorithms and Programming I

U.L.B. - March 16, 2000

- Tells the compiler the type of data returned by a function, the


number, types and order of the parameters.
Can be used to check the validity of function calls.
- Without prototype, function calls are not checked by the
compiler errors !
- A function prototype needs only to mention the parameters
data types (not their names).
- A function call that doesnt match the prototype causes a
syntax error.

Coercion of arguments :
- Example : math function expect double arguments,
but sqrt(4) is still valid and returns 2.0 : the integer value is
first converted to double.
- Type conversions should be done according to C promotion
rules to avoid the loss of data : toward highest level.
int

double : OK

int : truncation !
- From highest to lowest type :
double

Data Type

in printf :

in scanf :

long double
double
float
unsigned long int
long int
unsigned int
int
short
char

%Lf
%f
%f
%lu
%ld
%u
%d
%hd
%c

%Lf
%lf
%f
%lu
%ld
%u
%d
%hd
%c

- C promotion rules are automatically used in mixed-type


expressions.
- 60 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Header files :
Contains the function prototypes of all the functions in a
library, as well as data types and constants definitions.

Some useful standard library header :


Header file

Description
Character handling functions
Floating point size limits
Integer size limits
Math library functions
Standard I/O functions
Conversions text/numbers, ...
String processing functions
Time and date functions

ctype.h
float.h
limits.h
math.h
stdio.h
stdlib.h
string.h
time.h

User-defined header files :


#include "square.h"

Call by Value vs Call by Reference

Call by value :
A copy of the argument's value is passed to the called
function. Changes made to the copy do not affect the original
variable's value. No side effects.

Call by reference :
- 61 -

Algorithms and Programming I

U.L.B. - March 16, 2000

The called function can directly modify the value of the


original arguments in the calling function. Danger: possible
side effects.

In C :
Always call by value.
But call by reference can be simulated : Cf. arrays and
pointers.

Random Number Generation

The rand function :


Returns a "randomly" generated integer between 0 and
RAND_MAX (defined in stdlib.h, on 16 bit systems: 32767)

Example 1 : Simulate 20 rolls of a die.


#include <stdio.h>
#include <stdlib.h>
main()
{
int i;
for (i = 1; i <= 20; i++) {
printf("%10d", 1 + (rand() % 6));
if (i % 5 == 0)
printf("\n");
}
return 0;
}

- 62 -

Algorithms and Programming I

Example 2 :

U.L.B. - March 16, 2000

Simulate 6000 rolls and count the frequencies.

#include <stdio.h>
#include <stdlib.h>
main()
{
int face, roll, frequency1 = 0, frequency2 = 0,
frequency3 = 0, frequency4 = 0,
frequency5 = 0, frequency6 = 0;
for (roll = 1; roll <= 6000; roll++) {
face = 1 + rand() % 6;
switch (face) {
case 1:
++frequency1;
break;
case 2:
++frequency2;
break;
case 3:
++frequency3;
break;
case 4:
++frequency4;
break;
case 5:
++frequency5;
break;
case 6:
++frequency6;
break;
}
}
printf("%s%13s\n", "Face", "Frequency");
printf("
1%13d\n", frequency1);
printf("
2%13d\n", frequency2);
printf("
3%13d\n", frequency3);
printf("
4%13d\n", frequency4);
printf("
5%13d\n", frequency5);
printf("
6%13d\n", frequency6);
return 0;
- 63 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Pseudo-random numbers :
- Each time Example 2 is run, it generates the same sequence
of random numbers.
- Pseudo-random numbers are actually computed, using an
appropriate recurrence formula, so that they appear to be
random.
- The sequence of numbers generated can be changed by
modifying the seed of the generator : using the srand function.
- Important to be able to reproduce a given situation for
debugging a program.
- To produce a different sequence of numbers each time the
program is run :
srand(time(NULL));

Example 1 : Simulate 20 rolls of a die (2nd version).


#include <stdio.h>
#include <stdlib.h>
main()
{
int i;
unsigned seed;
printf(Enter seed : );
scanf(%u, &seed);
srand(seed);
for (i = 1; i <= 20; i++) {
printf("%10d", 1 + (rand() % 6));
if (i % 5 == 0)
printf("\n");
}
return 0;
}

- 64 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Lets Play Craps

Rules :
The player rolls two dices.
If the sum of the points obtained is 7 or 11, the player wins.
If the sum is 2, 3 or 12, the player loses.
In all other cases, the sum becomes the point of the player.
The player rolls the two dices until either he obtains his point
(win) or obtains a 7 (lose).

C program :
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int rollDice(void);
main()
{
int gameStatus, sum, point;
srand(time(NULL));
sum = rollDice();
switch(sum) {
case 7: case 11:
gameStatus = 1; /* win */
break;
case 2: case 3: case 12:
gameStatus = 2; /* lose */
break;
default:
gameStatus = 0;
point = sum;
printf(Point is %d\n", point);
break;
}
while (gameStatus == 0) {
- 65 -

Algorithms and Programming I

U.L.B. - March 16, 2000

sum = rollDice();
if (sum == point)
gameStatus = 1; /* win */
else
if (sum == 7)
gameStatus = 2; /* lose */
}
if (gameStatus == 1)
printf(Player wins\n");
else
printf(Player loses\n");
return 0;
}
int rollDice(void)
{
int die1, die2, locSum;
die1 = 1 + rand() % 6;
die2 = 1 + rand() % 6;
locSum = die1 + die2;
printf(Player rolled %d + %d = %d\n", die1, die2,
locSum);
return locSum;
}

- 66 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Storage Classes

Identifiers : Variable names, function names.

Attributes related to variables : name, type, value, ...

Other attributes : storage class, storage duration, scope,


linkage.

Storage class : Four storage classes are defined in C :


autoregister

extern

static

determine storage duration, scope and linkage.

Storage duration : period during which the identifier exists in


memory.

Scope : where the identifier can be referenced in a program.

Linkage : for multiple source files programs.

register
Automatic storage duration : auto
- Variables created when the block in which they are declared
is entered, and destroyed when the block is exited.
- Local variables are are automatic by default (hence auto is
rarely used).
- register asks the compiler to store a variable in a high
speed processor register (if possible). Becomes unnecessary
with modern optimizing compilers.
- 67 -

Algorithms and Programming I

U.L.B. - March 16, 2000

extern
static
Static storage duration :
- Variables that exist during the whole execution of the
program.
- static is used with local variables :
void printCounter(void)
{
static int count = 1;
printf(Call number %d\n", count++);
}

- extern is used with external identifiers. It is the default for


global variables and function names.

Scope Rules

Labels (Cf. switch and goto) have function scope : can be


used anywhere in the function in which they appear.

An identifier defined outside of any function has file scope :


can be used in all functions from the point at which it is
declared until the end of the file.

An identifier declared inside a block has block scope : can be


used within the block only (Cf. local variables, function
parameters)

Identifiers used in function prototypes (not required) have


function-prototype scope : ignored by the compiler.
- 68 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Example :
#include <stdio.h>
void a(void);
void b(void);
void c(void);
int x = 1;
main()
{
int x = 5

/* global variable */

/* local variable */

printf(x = %d\n", x);


{
int x = 7;
printf(x = %d\n", x);
}
printf(x = %d\n", x);
a();
b();
c();
a();
b();
c();
printf(x = %d\n", x);
return 0;
}
void a(void)
{
int x = 25;
printf(x = %d\n", x);
++x;
printf(x = %d\n", x);
}
void b(void)
{
static int x = 50;
printf(x = %d\n", x);
++x;
printf(x = %d\n", x);
}
void c(void)
{
printf(x = %d\n", x);
x *= 10;
printf(x = %d\n", x);
}

- 69 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Recursion

In C : functions can call themselves recursive functions.

Caution : Complex topic. Recursion can often be replaced by


more efficient iterative structures.

Principle :
- A general problem has to be solved.
- The solution is known for the simplest case(s) (base case(s)).
- The problem can be divided into two sub-problems : one
(simple) whose solution is known and another one that cannot
be solved directly but is a simpler version of the original
problem.

Example 1 : Computing the factorial of a nonnegative integer.


#include <stdio.h>
long factorial(long);
main()
{
int i;
for (i = 1; i <= 10; i++)
printf(%2d! = %ld\n", i, factorial(i));
return 0;
}
long factorial(long number)
{
if (number == 1)
return 1;
else
return (number * factorial(number - 1));
}

- 70 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Example 2 :
The Fibonacci series.
0
1
1
2
3
5
8
13 21 34 ...
- Starts with 0 and 1.
- Each subsequent number in the series is the sum of the two
previous ones.
#include <stdio.h>
long fibonacci(long);
main()
{
long result, number;
printf(Enter an integer : );
scanf(%ld, &number);
result = fibonacci(number);
printf(Fibonacci(%ld) = %ld\n", number, result);
return 0;
}
long fibonacci(long n)
{
if (n == 0 || n == 1)
return n;
else
return fibonacci(n - 1) + fibonacci(n - 2);
}

Problems related to recursion : Large number of function calls


- more processor time required,
- more memory required (multiple copies of local variables).

- 71 -

Algorithms and Programming I

U.L.B. - March 16, 2000

6. Arrays

Array :
- Data structure consisting of related data items of the same
type.
- A sequence of memory locations that are accessed using the
same name and that can contain the same type of data.
- Each location is accessed by specifying its position number
in the array (starting with 0).

Example : Integer array, called c, with 12 elements :

Using arrays :

C[0]

34

C[1]

C[2]

-1

C[3]

-2

C[4]

12

C[5]

-1

C[6]

28

C[7]

C[8]

11489

C[9]

C[10]

C[11]

52

name[subscript_expression]

printf(%d\n, c[3]);
c[10] = 45;
c[n + 1] = 0;
for (i=0; i < 12; i++)
printf(%d , c[i]);

- 72 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Declaring arrays :
element_type array_name[number_of_elements];

Examples :
int c[12];
int b[100], x[27];

Initializing an array :
- using a for loop :
#include <stdio.h>
main()
{
int n[10], i;
for (i = 0; i < 10; i++)
n[i] = 0;
printf(%s%13s\n, Element, Value);
for (i = 1; i < 10; i++)
printf(%7d%13d\n, i, n[i]);
return 0;
}

- in the array declaration : (compile time only)


#include <stdio.h>
main()
{
int i, n[10] = {32, 45, 12, 1, 34, 0, 1, 9, 41, 12};
printf(%s%13s\n, Element, Value);
for (i = 1; i < 10; i++)
printf(%7d%13d\n, i, n[i]);
return 0;
}

- also :
- 73 -

Algorithms and Programming I

U.L.B. - March 16, 2000

int n[10] = {0};


int a[5] = {1, 2, 3, 4, 5}
int b[] = {1, 2, 3, 4, 5, 6}

- using the #define preprocessor directive :


#include <stdio.h>
#define SIZE 10
main()
{
int s[SIZE], j;
for (j = 0; j < SIZE; j++)
s[j] = 2 + 2 * j;
printf(%s%13s\n, Element, Value);
for (i = 1; i < SIZE; i++)
printf(%7d%13d\n, i, n[i]);
return 0;
}

SIZE is a symbolic constant. It is replaced by 10 (a


replacement text, not an integer number) wherever it appears
in the program, before compilation.
Makes the program more scalable.

- 74 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Application 1 : Analysis of survey data.


Forty student rate the quality of food in the cafeteria on a 1 to
10 scale (1: very bad, 10: excellent). Summary of the data ?
#include <stdio.h>
#define STUDENTS 40;
#define VALUES 11;
main()
{
int answer, rating;
int responses[STUDENTS];
int frequency[VALUES] = {0}
printf(Enter the %d grades : \n, STUDENTS);
for (answer = 0; answer < STUDENTS; answer++)
scanf(%d, &responses[answer]);
for (answer = 0; answer < STUDENTS; answer++)
++frequency[responses[answer]];
printf(%s%17s\n, Rating, Frequency);
for (rating = 1; rating < VALUES; rating++)
printf(%6d%17d\n, rating, frequency[rating]);
return 0;
}

Remarks :
- Element number 0 of array frequency is not used.
- No array bounds checking potential errors !

- 75 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Application 2 : Printing a histogram.


#include <stdio.h>
#define SIZE 10
main()
{
int n[SIZE] = {19, 3, 15, 7, 11, 9, 13, 5, 17, 1};
int i, j;
printf(%s%13s%17s\n, Element, Value,
Histogram);
for (i = 0; i < SIZE; i++) {
printf(%7d%13d
, i, n[i]);
for (j = 1; j <= n[i]; j++)
printf(*);
printf(\n);
}
return 0;
}

Application 3 : Dice rolling (revisited).


#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 7;
main()
{
int face, roll, frequency1[SIZE] = {0};
srand(time(NULL));
for (roll = 1; roll <= 6000; roll++) {
face = 1 + rand() % 6;
++frequency[face];
}
printf("%s%13s\n", "Face", "Frequency");
for (face = 1; face < SIZE; face++)
printf("%4d%13d\n", face, frequency[face]);
return 0;
}

- 76 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Character arrays

In C : string = array of characters.

Declaration and initialisation :


char string1[] = hello;

The size of the array is determined by the compiler :


5 characters + a special string termination character:
\0 indicates the end of the string.

All strings end with the string termination character.


Always reserve a place for it.

Other equivalent declaration :


char string1[] = {h, e, l, l, o, \0};

Individual characters can be accessed or modified directly :


if (string1[5] == \0)
length = 5;
string1[0] = H;

Strings can be read using scanf :


char string2[20];
scanf(%s, string2);

- string2 can store strings up to 19 characters (+ terminating


null character).
- No & in scanf ! (Cf. later)
Array name = address of the first element of the array.
- No check of the length of the array that is read !
- scanf reads characters until the first blank character.

- 77 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Example :
#include <stdio.h>
main()
{
char string1[20], string2[] = Good bye !;
int i;
printf(Enter a string : );
scanf(%s, string1);
printf(string1 is : %s\nstring2 is : %s\n
string1 with spaces :\n,
string1, string2);
for (i = 0; string1[i] != \0; i++)
printf(%c , string1[i]);
printf(\n);
return 0;
}

A typical run :
Enter a
string1
string2
string1
H e l l

string : Hello there


is : Hello
is : Good bye
with spaces :
o

Static Arrays

Useful for local variables :


Not created and deleted every time the function is called.
Reduces program execution time.

- 78 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Passing Arrays to Functions

Example :
int hourlyTemperatures[24];
...
modifyArray(hourlyTemperatures, 24);

Arrays are passed using simulated call by reference.


The called function can modify the actual arguments in the
calling function !

Usually, the number of elements in the array is also passed to


the function.

Name of array = address of first element :


#include <stdio.h>
main()
{
char array[5];
printf(
array = %p\n&array[0] = %p\n,
array, &array[0]);
return 0;
}

Output :
array = FFF0
&array[0] = FFF0

Function header :
void modifyArray(int b[], int size)

Function prototype :
void modifyArray(int [], int);

- 79 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Example :
#include <stdio.h>
#define SIZE 5
void modifyArray(int [], int);
void modifyElement(int);
main()
{
int a[SIZE] = {0, 1, 2, 3, 4};
int i;
printf(Original array:\n);
for (i = 0; i < SIZE; i++)
printf(%3d, a[i]);
printf(\n);
modifyArray(a, SIZE);
printf(Modified array:\n);
for (i = 0; i < SIZE; i++)
printf(%3d, a[i]);
printf(Original value of a[3]: %d\n, a[3]);
modifyElement(a[3]);
printf(Modified value of a[3]: %d\n, a[3]);
return 0;
}
void modifyArray(int b[], int size)
{
int j;
for (j = 0; j < size; j++)
b[j] *= 2;
}
void modifyElement(int e)
{
printf(Value in modifyElement: %d\n, e *= 2);
}

- 80 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Using const :
Prevents the modification of array values in a function.
makes the array a constant in the function body,
any attempt to modifiy an element of the array results in a
compile time error.
Example :
#include <stdio.h>
void tryToModifyArray(const int []);
main()
{
int a[] = {10, 20, 30};
tryToModifyArray(a);
printf(%d %d %d\n, a[0], a[1], a[2]);
return 0;
}
void tryToModifyArray(const int b[])
{
b[0] /= 2;
/* error ! */
b[1] /= 2;
/* error ! */
b[2] /= 2;
/* error ! */
}

- 81 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Sorting Arrays

Either ascending ( smallest element first) or descending


largest element first).

One of the most important computing applications (sorting


customers by name, by account number, sorting sales figures,
...).

The exchange sort :


At each step, a pair of components are swapped in the list.

Principle :
1 Find the smallest (largest) component in the list and
exchange it with the first component.
2 Repeat the procedure with the remaining components
(starting with the second one), until all are ordered.
void exchangeSort(int a[], int size)
{
int hold, pass, place, minIndex;
for (pass = 0; pass < size - 1; pass++)
{
minIndex = pass;
for (place = pass + 1; place < size; place++)
if (a[place] < a[minIndex])
minIndex = place;
hold = a[minIndex];
a[minIndex] = a[pass];
a[pass] = hold;
}
}

- 82 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Calling the function :


...
#define SIZE 10
...
int x[SIZE];
...
exchangeSort(x, SIZE);
...

The bubble sort :


Several passes are made through the array. On each pass,
successive pairs of elements are compared : if a pair is in
decreasing order, their value are swapped, otherwise they are
not changed.
After one pass, the largest element has reached the last
position in the array.
void bubbleSort(int a[], int size)
{
int hold, pass, j;
for (pass = 1; pass < size; pass++)
for (j = 0; j < size - 1; j++)
if (a[j] > a[j+1]) {
hold = a[j];
a[j] = a[j+1];
a[j+1] = hold;
}
}

Still relatively slow, especially for large arrays.

- 83 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Searching Arrays

Determine whether an array contains a value that matches a


certain key value.

Linear search :
Compare sequentially each element of the array with the key.
#include <stdio.h>
#define SIZE 100
int linearSearch(int [], int, int);
main()
{
int a[SIZE], x, searchKey, element;
for (x = 0; x < SIZE; x++)
a[x] = 2 * x;
printf(Enter search key: );
scanf (%d, &searchKey);
element = linearSearch(a, searchKey, SIZE);
if (element == -1)
printf(Value not found !\n);
else
printf(Value found at position: %d\n, element);
return 0;
}

- 84 -

Algorithms and Programming I

U.L.B. - March 16, 2000

int linearSearch(int array[], int key, int size)


{
int n;
for (n = 0; n < size; n++)
if (array[n] == key)
return n;
return -1;
}

On average, the number of comparisons required will be


half the size of the array.
OK only for small or for unsorted arrays.

Binary search : for sorted arrays.


Faster than the sequential search.
Principle of successive approximations :
(Cf. look up a word in the dictionary)
- the list is divided in half,
- the search is limited one half of the list,
- the division is repeated until the item is found or appears not
to be in the list.
In the worst case, the number of comparisons required will
be :
10 for searching 1,024 (= 210) elements,
20 for searching 1,048,576 (= 220) elements,
30 for searching 1,073,741,824 (= 230) elements.

- 85 -

Algorithms and Programming I

U.L.B. - March 16, 2000

#include <stdio.h>
#define SIZE 100
int binarySearch(int [], int, int);
main()
{
int a[SIZE], x, searchKey, element;
for (x = 0; x < SIZE; x++)
a[x] = 2 * x;
printf(Enter search key: );
scanf (%d, &searchKey);
element = binarySearch(a, searchKey, SIZE);
if (element == -1)
printf(Value not found !\n);
else
printf(Value found at position: %d\n, element);
return 0;
}
int binarySearch(int array[], int key, int size)
{
int low, high, middle;
low = 0;
high = size - 1;
while (low <= high) {
middle = (low + high) / 2;
if (key == array[middle])
return middle;
else if (key < array[middle])
high = middle - 1;
else
low = middle + 1;
}
return -1;
}

- 86 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Multiple-Subscripted Arrays

Two-dimensional arrays :
Useful for representing tables.
Example : Integer array a with three rows and four columns :
Column 0

Column 1

Column 2

Column 3

a[0][0]

a[0][1]

a[0][2]

a[0][3]

a[1][0]

a[1][1]

a[1][2]

a[1][3]

a[2][0]

a[2][1]

a[2][2]

a[2][3]

a[0][0]

a[0][1]

a[0][2]

a[1][0]

a[1][1]

a[1][2]

a[1][3]

a[2][1]

a[2][2]

a[2][3]

Row 0
Row 1
Row 2

Storage in memory :
a

a[0]

a[1]
a[0][3]
a[2]
a[2][0]

Declaration :
int a[3][4];

Initialization :
int
int
int
int

b[2][2]
c[2][2]
d[2][2]
e[2][2]

=
=
=
=

{{1, 2}, {3, 4}};


{{1}, {3, 4}};
{1, 2, 3, 4};
{1, 2};
- 87 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Example 1 :
#include <stdio.h>
void printArray(int [][3]);
main()
{
int array1[2][3] = { {1, 2, 3}, {4, 5, 6} },
array2[2][3] = { 1, 2, 3, 4, 5 },
array3[2][3] = { {1, 2}, {4} };
printf(array1:\n);
printArray(array1);
printf(array2:\n);
printArray(array2);
printf(array3:\n);
printArray(array3);
return 0;
}
void printArray(int a[][3])
{
int i, j;
for (i = 0; i <= 1; i++) {
for (j = 1; j <= 2; j++)
printf(%d , a[i][j]);
printf(\n);
}
}

- 88 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Example 2 :
#include <stdio.h>
#define STUDENTS 3
#define EXAMS 4
int minimum(int [][EXAMS], int, int);
int maximum(int [][EXAMS], int, int);
float average(int [], int);
void printArray(int [][EXAMS], int, int);
main()
{
int student,
studentGrades[STUDENTS][EXAMS] =
{{77, 68, 86, 73},
{96, 87, 89, 78},
{70, 90, 86, 81}};
printf(The array is:\n);
printArray(studentGrades, STUDENTS, EXAMS);
printf(\n\nLowest grade: %d\nHighest grade: %d\n,
minimum(studentGrades, STUDENTS, EXAMS),
maximum(studentGrades, STUDENTS, EXAMS));
for (student = 1; student < STUDENTS; student++)
printf(Average grade for student %d : %.2f\n,
student,
average(studentGrades[student], EXAMS));
return 0;
}
int minimum(int grades[][EXAMS], int pupils, int tests)
{
int i, j, lowGrade = 100;
for (i = 0; i < pupils; i++)
for (j = 0; j < tests; j++)
if (grades[i][j] < lowGrade)
lowGrade = grades[i][j];
return lowGrade;
}
int maximum(int grades[][EXAMS], int pupils, int tests)
- 89 -

Algorithms and Programming I

U.L.B. - March 16, 2000

{
int i, j, highGrade = 100;
for (i = 0; i < pupils; i++)
for (j = 0; j < tests; j++)
if (grades[i][j] > highGrade)
highGrade = grades[i][j];
return highGrade;
}
float average(int setOfGrades[], int tests)
{
int i, total = 0;
for (i = 0; i < tests; i++)
total += setOfGrades[i];
return (float) total / tests;
}
void printArray(int grades[][EXAMS], int pupils,
int tests)
{
int i, j;
printf(
[0] [1] [2]
for (i = 0; i < pupils; i++) {
printf(\nstudentGrades[%d] ,i);
for (j = 0; j < tests; j++)
printf(-5d, grades[i][j]);
}
}

Up to 12 array subscripts are allowed :


fun[x][y1][t][2][z][a1][a2][y2][v][w][m][p]

- 90 -

[3]);

Algorithms and Programming I

U.L.B. - March 16, 2000

7. Pointers
Pointer Variables

Definition : Variable whose value is a memory address (of an


other variable).

Declaration : using the indirection operator * :


Example : pointer to an integer variable
int *countPtr, count;
count = 7;
countPtr = &count;

&countPtr

&count

312412

432180

432180

......

Initialisation :
Either to 0 to NULL (defined in stdio.h) or to a valid address.

Assigning a value to a pointer variable : using the & operator.

Indirection operator : (or dereferencing operator)


Returns the value of the object to which a pointer points :
printf(%d, *countPtr);

- 91 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Example :
#include <stdio.h>
main()
{
int a, *aPtr;
a = 7;
aPtr = &a;
printf(Address of a
printf(Value of aPtr
printf(Value of a
printf(Value of *aPtr

:
:
:
:

%p\n,
%p\n,
%d\n,
%d\n,

&a);
aPtr);
a);
*aPtr);

return 0;
}

Output :
Address of a
Value of aPtr
Value of a
Value of *aPtr

:
:
:
:

FFF4
FFF4
7
7

Calling Functions by Reference

Simulated, using pointers (avoid overhead of call by value):


- the addresses of the arguments are passed to the function
(as in scanf),
- the indirection operator is used in the function to access the
actual argument.

- 92 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Example 1 :
- call by value :
#include <stdio.h>
int cubeByValue(int);
main()
{
int number = 5;
number = cubeByValue(number);
printf(Cube is : %d\n, number);
return 0;
}
int cubeByValue(int n)
{
return n * n * n;
}

- call by reference :
#include <stdio.h>
void cubeByReference(int *);
main()
{
int number = 5;
cubeByReference(&number);
printf(Cube is : %d\n, number);
return 0;
}
void cubeByReference(int *nPtr)
{
*nPtr = *nPtr * *nPtr * *nPtr;
}

- 93 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Example 2 : new version of the bubble sort :


#include <stdio.h>
#define SIZE 10
void bubbleSort(int *, int);
main()
{
int i,
a[SIZE] = {2, 6, 4, 8, 10, 12, 89, 68, 45, 37};
printf(Original order: \n);
for (i = 0; i < SIZE; i++)
printf(%4d, a[i]);
bubbleSort(a, SIZE);
printf(\nSorted in ascending order: \n);
for (i = 0; i < SIZE; i++)
printf(%4d, a[i]);
printf(\n);
return 0;
}
void bubbleSort(int *array, int size)
{
int pass, j;
void swap(int *, int *);
for (pass = 1; pass < size; pass++)
for (j = 0; j < size - 1; j++)
if (array[j] > array[j+1])
swap(&array[j],&array[j+1]);
}
void swap(int *x1Ptr, int *x2Ptr)
{
int hold;
hold = *x1Ptr;
*x1Ptr = *x2Ptr;
*x2Ptr = hold;
}

- 94 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Remarks :
- use of *array instead of array[] : equivalent, array = pointer
to first element of the array
- prototype of swap inside bubbleSort : restricts proper calls of
the function to those made from bubbleSort.

Pointer Expressions and Pointer Arithmetic

Limited set of available operators :


++

--

Examples :

+=

-=

(with 4-byte integers)

int v[10], *vPtr;


vPtr = &v[0];

/* or vPtr = v; */

vPtr += 2;

/* adds 2 * 4 to the value of vPtr */


/* hence vPtr == v[2] */

vptr--;

/* subtracts 1 * 4 to vPtr */

Pointers and Arrays

Pointers and arrays can be used almost interchangeably.

Array name = constant pointer.

Pointers can be used instead of array subscripting (more


efficient).
- 95 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Example 1 :
int b[5], *bPtr;
bPtr = b;

/* or bPtr = &b[0]; */

...

*(bPtr + 3) /* equivalent to b[3] */


/* pointer/offset notation */
...

*(b + 3)

/* also equivalent to b[3] */

...

bPtr[1]

/* equivalent to b[1] */

...

b += 3;

/* invalid */

Example 2 :
#include <stdio.h>
main()
{
int i, offset, b[] = {10, 20, 30, 40};
int *bPtr = b;
printf(Using subscript notation :\n);
for (i = 0; i <= 3; i++)
printf(b[%d] = %d\n, i, b[i]);
printf(Using pointer/offset notation with b :\n);
for (offset = 0; offset <= 3; offset++)
printf(*(b + %d) = %d\n, offset, *(b + offset));
printf(Using pointer subscript notation :\n);
for (i = 0; i <= 3; i++)
printf(bPtr[%d] = %d\n, i, bPtr[i]);
printf(Using pointer/offset notation :\n);
for (offset = 0; offset <= 3; offset++)
printf(*(bPtr + %d) = %d\n, offset,
*(bPtr + offset));
return 0;
}

- 96 -

Algorithms and Programming I

Example 3 :

U.L.B. - March 16, 2000

Copying strings.

#include <stdio.h>
void copy1(char *, const char *);
void copy2(char *, const char *);
main()
{
char string1[10], *string2 = Hello,
string3[10], string4[10] = Good Bye;
copy1(string1,string2);
printf(string1 = %s\n, string1);
copy2(string3,string4);
printf(string3 = %s\n, string3);
return 0;
}
void copy1(char *s1, const char *s2);
{
/* array notation */
int i;
for (i = 0; s1[i] = s2[i]; i++) ;
}
void copy2(char *s1, const char *s2);
{
/* pointer notation */
for ( ; *s1 = *s2; s1++, s2++) ;
}

Remarks :
- use of const,
- use of the null string termination character.

- 97 -

Algorithms and Programming I

U.L.B. - March 16, 2000

8. Characters and Strings


Characters

Character constant : Integer value represented as a character


enclosed in single quotes.
t

\n

Value of a character constant : index of the character in the


machines character set (ASCII table for PCs).

Character handling library :

Cf. Fig. 8.1

#include <ctype.h>

Strings

String constant : Series of characters written in double


quotation marks.
This is a string

123.45

In C :
- Array of characters, ending with the null character (\0).
- Accessed using a pointer to the first character.
- Value of a string = address of its first character.

String conversion functions : Cf. Fig. 8.5


#include <stdlib.h>

- 98 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Additional I/O Functions

Cf. Fig. 8.12


#include <stdio.h>

Example 1 :
#include <stdio.h>
main()
{
char sentence[80];
void reverse(char *);
printf(Enter a line of text:\n);
gets(sentence);
printf(\Line printed backwards:\n);
reverse(sentence);
return 0;
}
void reverse(char *s)
{
if (s[0] == \0)
return;
else {
reverse(&s[1]);
putchar(s[0]);
}
}

- 99 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Example 2 :
#include <stdio.h>
main()
{
char c, sentence[80];
int i = 0;
puts(Enter a line of text:);
while ((c = getchar()) != \n)
sentence[i++] = c;
sentence[i] = \0;
puts(The line entered was:)
puts(sentence);
return 0;
}

String handling library : Cf. Fig. 8.17 and 8.20


#include <string.h>

Additional functions are also available.

- 100 -

Algorithms and Programming I

U.L.B. - March 16, 2000

9. Formatted Input/Output

- 101 -

Algorithms and Programming I

U.L.B. - March 16, 2000

Whats Next ?

Structures, Unions, Enumerations.

File processing.

Data structures :

Object Oriented Programming and C++.

- Linked Lists,
- Stacks,
- Queues,
- Trees, ...

- 102 -

You might also like