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