You are on page 1of 102

Algorithms and Programming I U.L.B.

- March 16, 2000


- 1 -
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
Algorithms and Programming I U.L.B. - March 16, 2000
- 2 -
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 Theory Exercises
16-18 Exercises Exercises
Evaluation : Homeworks (programs)
Exam. in January (Alg.&Pr. I and II)
Computer Room : NO Building, level 4.
Algorithms and Programming I U.L.B. - March 16, 2000
- 3 -
Useful references
Textbooks
H. M. Deitel & P. J. Deitel (http://www.deitel.com)
C How to Program (2
nd
edition)
Prentice Hall, 1994, 926p., ISBN 0-13-226119-7
B. Gottfried
Programming with C (2
nd
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 (2
nd
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 (2
nd
edition)
Prentice Hall, 1989, 274p., ISBN 0-13-110362-8.
B. Stroustrup
The C++ Programming Language (3
rd
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
Algorithms and Programming I U.L.B. - March 16, 2000
- 4 -
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.
Algorithms and Programming I U.L.B. - March 16, 2000
- 5 -
A third phase
Maintenance Phase :
1 Use :
Use the program.
2 Maintain :
Modify the program if necessary : new requirements, errors.

Program Life Cycle :


Analysis
and
Specification
General Solution
(Algorithm)
Verify
Problem-Solving
Specific Solution
(Program)
Test
Implementation
Use
Maintain
Maintenance



More definitions ...

Algorithm :
Step-by-step procedure for solving a problem in a finite
amount of time.
Examples :
recipes, instructions, ...
Algorithms and Programming I U.L.B. - March 16, 2000
- 6 -
Programming Language :
Set of rules, symbols and special words used to construct a
program.

Implementation
Program
Problem-Solving
Algorithm
Coding

Documentation :
Written text and comments that make a program easier for
others to understand, use and modify.

Development of programming languages :

Machine language Assembly language High level language
+1300042774
+1400593419
+1200274027
LOAD BASEPAY
ADD OVERPAY
STORE GROSSPAY
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 :
Algorithms and Programming I U.L.B. - March 16, 2000
- 7 -
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.
Algorithms and Programming I U.L.B. - March 16, 2000
- 8 -
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.

Algorithms and Programming I U.L.B. - March 16, 2000
- 9 -
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, ...


Algorithms and Programming I U.L.B. - March 16, 2000
- 10 -
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.


Algorithms and Programming I U.L.B. - March 16, 2000
- 11 -
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.
Algorithms and Programming I U.L.B. - March 16, 2000
- 12 -
{
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.
Algorithms and Programming I U.L.B. - March 16, 2000
- 13 -
Second program : Adding two integers

C code :

/* Addition program */
#include <stdio.h>

main()
{
int integer1, integer2, sum; /* declaration */

printf(Enter first integer :\n); /* prompt */
scanf(%d, &integer1); /* read integer1 */
printf(Enter second integer :\n); /* promt */
scanf(%d, &integer2); /* read integer2 */
sum = integer1 + integer2; /* assignment */
printf(Sum is %d\n, sum); /* print sum */

return 0; /* indicates successful program termination */
}


Output :

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


Algorithms and Programming I U.L.B. - March 16, 2000
- 14 -
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 :
integer1, integer2, sum 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.

Algorithms and Programming I U.L.B. - March 16, 2000
- 15 -
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.
Algorithms and Programming I U.L.B. - March 16, 2000
- 16 -
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 read-
in).



Arithmetic in C

Arithmetic operators : 5 binary operators

Operation C Operator Example
Addition
+ x + y
Subtraction
- t - 2
Multiplication
* 2 * Pi * Radius
Division
/ x / t
Modulus
% a % b

Integer division yields an integer result :
7 / 4 1
Algorithms and Programming I U.L.B. - March 16, 2000
- 17 -

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))

Algorithms and Programming I U.L.B. - March 16, 2000
- 18 -
Equality and Relational Operators

Standard Operator C Operator Example
Equality

=
== x == y

!= x != y
Relational

>
> 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) :

Algorithms and Programming I U.L.B. - March 16, 2000
- 19 -
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

Algorithms and Programming I U.L.B. - March 16, 2000
- 20 -
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 break case char
const continue default do
double else enum extern
float for goto if
int long register return
short signed sizeof static
struct switch typedef union
unsigned void volatile while



Algorithms and Programming I U.L.B. - March 16, 2000
- 21 -
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, ...
Algorithms and Programming I U.L.B. - March 16, 2000
- 22 -
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 TEST1.EXE
DUMP.TXT 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 :
C:\ 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:\DATA\SALES\REGIONAL\BRUSSELS.DAT
C:BRUSSELS.DAT file of the current directory
Some useful DOS commands :
- Directories : DIR CD MD RD
- Files : COPY REN DEL
- Format : FORMAT
- View and edit files : TYPE PRINT EDIT
- Others : MORE MEM CHKDSK MOVE
Algorithms and Programming I U.L.B. - March 16, 2000
- 23 -
The Windows 3.11 operating system :

Graphical User Interface : On top of MS-DOS.

Starting Windows : Type WIN at the DOS prompt.

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.


The Borland C++ compiler :

Borland C++ 4.0 4.5 5.02 C++ Builder
Algorithms and Programming I U.L.B. - March 16, 2000
- 24 -
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.

grade = 12
print "Failed" print "Passed"
false
true

Algorithms and Programming I U.L.B. - March 16, 2000
- 25 -

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) : goto-less programming

if grade 12 then
print Failed`
else
print Passed
do
print Press C to continue
read character from keyboard
while character C

control structures.
Algorithms and Programming I U.L.B. - March 16, 2000
- 26 -
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

3 for

Combination of control structures :
1 Stacking (building blocks approach).

2 Nesting (structures within structures).
Algorithms and Programming I U.L.B. - March 16, 2000
- 27 -
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);
Algorithms and Programming I U.L.B. - March 16, 2000
- 28 -
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);
Algorithms and Programming I U.L.B. - March 16, 2000
- 29 -
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);
}


Algorithms and Programming I U.L.B. - March 16, 2000
- 30 -
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;
}
Algorithms and Programming I U.L.B. - March 16, 2000
- 31 -
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;
Algorithms and Programming I U.L.B. - March 16, 2000
- 32 -
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;
}

Algorithms and Programming I U.L.B. - March 16, 2000
- 33 -
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.

Algorithms and Programming I U.L.B. - March 16, 2000
- 34 -
- 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;

Algorithms and Programming I U.L.B. - March 16, 2000
- 35 -
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.

Algorithms and Programming I U.L.B. - March 16, 2000
- 36 -
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.
Algorithms and Programming I U.L.B. - March 16, 2000
- 37 -
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.
Algorithms and Programming I U.L.B. - March 16, 2000
- 38 -

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.
Algorithms and Programming I U.L.B. - March 16, 2000
- 39 -
More Assignment Operators

First example :
x = x + 5 x += 5

Allowed with other binary operators :
+= -= *= /= %=

Advantage : faster.

Second example :
x = x + 1 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, x++);
printf(%d\n, x);
printf(%d\n, ++x);
y = x-- + 2;
printf(%d\n, y);
printf(%d\n, x);

y = ++x + 2 * x;
Output :
2
3
4

6
3

?
Algorithms and Programming I U.L.B. - March 16, 2000
- 40 -
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.

Algorithms and Programming I U.L.B. - March 16, 2000
- 41 -
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;
}
Algorithms and Programming I U.L.B. - March 16, 2000
- 42 -
The 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).
Algorithms and Programming I U.L.B. - March 16, 2000
- 43 -
4 Flowchart :
initialization
increment loop_body condition
false
true


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)

Algorithms and Programming I U.L.B. - March 16, 2000
- 44 -
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");
Algorithms and Programming I U.L.B. - March 16, 2000
- 45 -

for (year = 1; year <= 10; year++) {
amount = principal * pow(1.0 + rate, year);
printf("%4d%21.2f\n", year, amount);
}

return 0;
}

Output :
Year Amount on deposit
1 1050.00
2 1102.50
3 1157.62
4 1215.51
5 1276.28
6 1340.10
7 1407.10
8 1477.46
9 1551.33
10 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).
Algorithms and Programming I U.L.B. - March 16, 2000
- 46 -
Numbers and Precision

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

1 2 3 4 5 6 7 8 9 10
137
11 12 13 14 15 16 17 18 19 20
H e l l
21 22 23 24 25 26 27 28 29 30
o 2.357412e012

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

Decimal representation of numbers : base 10 digits 0-9

235 = 210
2
+ 310
1
+ 510
0


Binary representation of numbers : base 2 digits 0-1

235 = 11101011
2
=
12
7
+ 12
6
+ 12
5
+ 02
4
+ 12
3
+ 02
2
+ 12
1
+ 12
0

Algorithms and Programming I U.L.B. - March 16, 2000
- 47 -
Octal representation of numbers : base 8 digits 0-7
235 = 353
8
= 38
2
+ 58
1
+ 38
0


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 = EB
16
= 1416
1
+ 1116
0


Representation of data in memory : binary
- on 1 byte :
128 64 32 16 8 4 2 1
1 1 1 0 1 0 1 1

largest positive integer : 255
128 64 32 16 8 4 2 1
1 1 1 1 1 1 1 1

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 = 00010101
2

-21 = 11101010
2
+ 00000001
2
= 11101011
2

3 Maximum and minimum values :
- minimum : 10000000
2
= -128
- maximum : 01111111
2
= 127
Algorithms and Programming I U.L.B. - March 16, 2000
- 48 -
- on 2 bytes :
... ... ... ... ...
1024
512 256 128 64 32 16 8 4 2 1
0 0 0 0 0 0 0 0 1 1 1 0 1 0 1 1

largest positive integer : 65535
... ... ... ... ...
1024
512 256 128 64 32 16 8 4 2 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

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
1
0 to 255
1
0 to 255
char
1
-128 to 127
1
-128 to 127
short int
2
-32768 to 32767
2
-32768 to 32767
unsigned int
2
0 to 65535
4
0 to 4294967295
int
2
-32768 to 32767
4
-2147483648 to 2147483647
enum
2
-32768 to 32767
4
-2147483648 to 2147483647
unsigned
long
4
0 to 4294967295
4
0 to 4294967295
long
4
-2147483648 to 2147483647
4
-2147483648 to 2147483647
float
4
3.4 10
-38
to 3.4 10
+38

4
3.4 10
-38
to 3.4 10
+38

double
8
1.7 10
-308
to 1.7 10
+308

8
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)
2
-
4
-
far (pointer)
4
-
4
-
Algorithms and Programming I U.L.B. - March 16, 2000
- 49 -
The do/while 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).
Algorithms and Programming I U.L.B. - March 16, 2000
- 50 -
The switch 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);
Algorithms and Programming I U.L.B. - March 16, 2000
- 51 -
printf(A: %d\n, aCount);
printf(B: %d\n, bCount);
printf(C: %d\n, cCount);
printf(D: %d\n, dCount);
printf(F: %d\n, 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;
Algorithms and Programming I U.L.B. - March 16, 2000
- 52 -
The break 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 == %d\n, x);
return 0;
}

#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;
}
Algorithms and Programming I U.L.B. - March 16, 2000
- 53 -
Logical Operators

AND, OR and NOT

Operator : AND OR NOT
in C :
&& || !

A B A && B
0 0 0
0 0 0
0 0 0
0 0 1

A B A || B
0 0 0
0 0 1
0 0 1
0 0 1

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);
Algorithms and Programming I U.L.B. - March 16, 2000
- 54 -
Precedence Levels (completed)

From highest to lowest Associativity
( )
left to right
++ -- -(unary) (type)
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


Caution:
Confusing == (equality) and = (assignment)

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

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

Example 2 :
x = 1;

x == 1;
Algorithms and Programming I U.L.B. - March 16, 2000
- 55 -
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 : from the C standard library :
printf scanf 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.
Algorithms and Programming I U.L.B. - March 16, 2000
- 56 -
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 Description Example
sqrt(x)
square root of x
sqrt(25.0) : 5.0
exp(x)
exponential
exp(1.0) : 2.718282
exp(2.0) : 7.389056
log(x)
natural logarithm
log(2.718282) : 1.0
log(7.389056) : 2.0
log10(x)
base 10 logarithm
log10(1.0) : 0.0
log10(10.0) : 1.0
log10(100.0) : 2.0
fabs(x)
absolute value
fabs(12.5) : 12.5
fabs(-5.0) : 5.0
ceil(x)
smallest integer x
ceil(7.3) : 8.0
ceil(-1.5) : -1.0
floor(x)
largest integer x
floor(7.3) : 7.0
floor(-1.5) : -2.0
pow(x,y)
x raised to power y
pow(4, 3) : 64.0
pow(9, 0.5) : 3.0
fmod(x,y)
remainder of x / y
fmod(14, 2.5) : 1.5
sin(x)
sine of x (radians)
sin(0.0) : 0.0
cos(x)
cosine of x
cos(0.0) : 1.0
tan(x)
tangent of x
tan(0.0) : 0.0
Algorithms and Programming I U.L.B. - March 16, 2000
- 57 -
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
}
Algorithms and Programming I U.L.B. - March 16, 2000
- 58 -
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;
}

Algorithms and Programming I U.L.B. - March 16, 2000
- 59 -
- 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; (no returned value) or return expression;
- 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++.
Algorithms and Programming I U.L.B. - March 16, 2000
- 60 -
- 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
double int : truncation !
- From highest to lowest type :
Data Type in printf : in scanf :
long double %Lf %Lf
double %f %lf
float %f %f
unsigned long int %lu %lu
long int %ld %ld
unsigned int %u %u
int %d %d
short %hd %hd
char %c %c
- C promotion rules are automatically used in mixed-type
expressions.
Algorithms and Programming I U.L.B. - March 16, 2000
- 61 -

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
ctype.h
Character handling functions
float.h
Floating point size limits
limits.h
Integer size limits
math.h
Math library functions
stdio.h
Standard I/O functions
stdlib.h
Conversions text/numbers, ...
string.h
String processing functions
time.h
Time and date functions

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 :
Algorithms and Programming I U.L.B. - March 16, 2000
- 62 -
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;
}

Algorithms and Programming I U.L.B. - March 16, 2000
- 63 -
Example 2 : 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;
Algorithms and Programming I U.L.B. - March 16, 2000
- 64 -
}

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;
}
Algorithms and Programming I U.L.B. - March 16, 2000
- 65 -
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) {
Algorithms and Programming I U.L.B. - March 16, 2000
- 66 -
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;
}

Algorithms and Programming I U.L.B. - March 16, 2000
- 67 -
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 :
auto register 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.

Automatic storage duration : auto register
- 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.
Algorithms and Programming I U.L.B. - March 16, 2000
- 68 -
Static storage duration : extern static
- 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.
Algorithms and Programming I U.L.B. - March 16, 2000
- 69 -

Example :
#include <stdio.h>

void a(void);
void b(void);
void c(void);

int x = 1; /* global variable */

main()
{
int x = 5 /* 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);
}
Algorithms and Programming I U.L.B. - March 16, 2000
- 70 -
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));
}
Algorithms and Programming I U.L.B. - March 16, 2000
- 71 -
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).
Algorithms and Programming I U.L.B. - March 16, 2000
- 72 -
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 :

C[0] 34
C[1] 0
C[2] -1
C[3] -2
C[4] 12
C[5] -1
C[6] 28
C[7] 2
C[8] 11489
C[9] 0
C[10] 0
C[11] 52

Using arrays : 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]);
Algorithms and Programming I U.L.B. - March 16, 2000
- 73 -
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 :
Algorithms and Programming I U.L.B. - March 16, 2000
- 74 -
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.
Algorithms and Programming I U.L.B. - March 16, 2000
- 75 -
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 !
Algorithms and Programming I U.L.B. - March 16, 2000
- 76 -
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;
}
Algorithms and Programming I U.L.B. - March 16, 2000
- 77 -
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.
Algorithms and Programming I U.L.B. - March 16, 2000
- 78 -
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 string : Hello there
string1 is : Hello
string2 is : Good bye
string1 with spaces :
H e l l o

Static Arrays

Useful for local variables :
Not created and deleted every time the function is called.

Reduces program execution time.
Algorithms and Programming I U.L.B. - March 16, 2000
- 79 -
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);

Algorithms and Programming I U.L.B. - March 16, 2000
- 80 -
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);
}
Algorithms and Programming I U.L.B. - March 16, 2000
- 81 -
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 ! */
}
Algorithms and Programming I U.L.B. - March 16, 2000
- 82 -
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;
}
}

Algorithms and Programming I U.L.B. - March 16, 2000
- 83 -
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.
Algorithms and Programming I U.L.B. - March 16, 2000
- 84 -
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;
}
Algorithms and Programming I U.L.B. - March 16, 2000
- 85 -
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 (= 2
10
) elements,
20 for searching 1,048,576 (= 2
20
) elements,
30 for searching 1,073,741,824 (= 2
30
) elements.

Algorithms and Programming I U.L.B. - March 16, 2000
- 86 -
#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;
}
Algorithms and Programming I U.L.B. - March 16, 2000
- 87 -
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
Row 0
a[0][0] a[0][1] a[0][2] a[0][3]
Row 1
a[1][0] a[1][1] a[1][2] a[1][3]
Row 2
a[2][0] a[2][1] a[2][2] a[2][3]

Storage in memory :


a a[0]


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

a[1]

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

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




Declaration :
int a[3][4];

Initialization :
int b[2][2] = {{1, 2}, {3, 4}};
int c[2][2] = {{1}, {3, 4}};
int d[2][2] = {1, 2, 3, 4};
int e[2][2] = {1, 2};
Algorithms and Programming I U.L.B. - March 16, 2000
- 88 -
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);
}
}

Algorithms and Programming I U.L.B. - March 16, 2000
- 89 -
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)
Algorithms and Programming I U.L.B. - March 16, 2000
- 90 -
{
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] [3]);
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]
Algorithms and Programming I U.L.B. - March 16, 2000
- 91 -
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
......
7


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

Algorithms and Programming I U.L.B. - March 16, 2000
- 92 -
Example :
#include <stdio.h>

main()
{
int a, *aPtr;

a = 7;
aPtr = &a;

printf(Address of a : %p\n, &a);
printf(Value of aPtr : %p\n, aPtr);
printf(Value of a : %d\n, a);
printf(Value of *aPtr : %d\n, *aPtr);

return 0;
}

Output :
Address of a : FFF4
Value of aPtr : FFF4
Value of a : 7
Value of *aPtr : 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.

Algorithms and Programming I U.L.B. - March 16, 2000
- 93 -
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;
}
Algorithms and Programming I U.L.B. - March 16, 2000
- 94 -
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;
}
Algorithms and Programming I U.L.B. - March 16, 2000
- 95 -
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).
Algorithms and Programming I U.L.B. - March 16, 2000
- 96 -
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;
}
Algorithms and Programming I U.L.B. - March 16, 2000
- 97 -
Example 3 : 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.
Algorithms and Programming I U.L.B. - March 16, 2000
- 98 -
8. Characters and Strings


Characters

Character constant : Integer value represented as a character
enclosed in single quotes.
t 1 ; $ \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>

Algorithms and Programming I U.L.B. - March 16, 2000
- 99 -

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]);
}
}

Algorithms and Programming I U.L.B. - March 16, 2000
- 100 -
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.
Algorithms and Programming I U.L.B. - March 16, 2000
- 101 -
9. Formatted Input/Output



Algorithms and Programming I U.L.B. - March 16, 2000
- 102 -

Whats Next ?

Structures, Unions, Enumerations.

File processing.

Data structures : - Linked Lists,
- Stacks,
- Queues,
- Trees, ...

Object Oriented Programming and C++.

You might also like