Sei sulla pagina 1di 153

Lebanese University Faculty of Sciences

Lebanese University
Faculty of Sciences

I1101 E
Imperative
Programming in C
Department of Applied Mathematics

Spring Semester
2019 - 2020
I1101

Copyright Reserved for the Lebanese University ©2019-2020

This material is only for academic use by the students at the Faculty of Sciences in the Lebanese
University, it should not be distributed for purchase or photocopy anywhere under the threat of legal
prosecution.

2019-2020© ‫حقوق الطبع والنشر محفوظة للجامعة اللبنانية‬

‫إ ن هذه النسخة موضوعة بتصرف طالب كلية العلوم في الجامعة اللبنانية و لهدف اكاديمي فقط ال غير وعليه يمنع توزيع اي نسخة‬
.‫(ورقية او الكترونية) الي جهة اخرى او التصوير والبيع في كافة المكتبات تحت طائلة المالحقة القانونية‬
Imperative Programming in C

Version 1.1
Copyright © 2019-2020 Version 1.1

Copying prohibited

All rights reserved. No part of this publication may be reproduced or transmitted in any
form or by any means, electronic or mechanical, including photocopying and recording, or
by any information storage or retrieval system, without the prior written permission of the
publisher.

This booklet is translated from the French course of Faber Frédéric.

Mistakes may occur. If, while reading, you come across any mistakes with the text or the
codes, please, don’t hesitate to send it to us by using the contact form available on the
following link http://www.antoun.me/contacts.php
Contents

1 INTRODUCTION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.1 Historical 7
1.2 K&R-C 7
1.3 ANSI-C 7
1.4 C++ 8
1.5 Advantages 8
1.6 Disadvantages 8

2 THE ENVIRONMENT AND LIBRARIES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11


2.1 Description of the Microsoft Visual Studio environment 11
2.2 Select the ANSI-C compiler 16
2.3 Libraries of predefined functions 17
2.3.1 Using function libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.3.2 #include . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.3.3 Files identification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

3 BASIC CONCEPTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.1 Hello C ! 19
3.2 The components of a C program 19
3.2.1 The functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.2.2 The main function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.2.3 The variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.2.4 Identifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.2.5 Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

3
3.3 Discussion of the ’Hello World’ example 23

4 BASIC TYPES, OPERATORS AND EXPRESSIONS . . . . . . . . . . . . . . . . . . . . . . . . 26


4.1 Simple types 26
4.2 The declaration of simple variables 29
4.3 Standard operators 33
4.4 Expressions and instructions 36
4.5 Operator priorities 37
4.6 Standard arithmetic functions 41
4.7 Type conversions 42

5 READ AND WRITE DATA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46


5.1 Formatted data writing 46
5.2 Formatted data reading 50
5.3 Writing a character 53
5.4 Reading a character 54

6 Alternative structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
6.1 Block of instructions 57
6.2 if - else 57
6.3 if without else 59
6.4 if - else if - ... - else 60
6.5 Break et Continue 62
6.6 switch 64
6.7 Conditional operators 66

7 Repetitive structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
7.1 while 71
7.2 do - while 73
7.3 for 74
7.4 Choice of the repetitive structure 77

8 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
8.1 Uni-dimensional arrays 85
8.2 Two-dimensional arrays 89
9 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
9.1 Declaration and storage 103
9.2 Constant strings 104
9.3 Initializing strings 105
9.4 Access to the string elements 106
9.5 Alphabetical and lexicographic precedence 106
9.6 Working with strings 107
9.7 Array of strings 113

10 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
10.1 Modularisation de programmes 119
10.2 The notion of blocks and the scope of identifiers 121
10.3 Declaration and definition of functions 124
10.4 Return a result 132
10.5 Parameters of a function 135
10.6 Functions / modules in C 139
1. INTRODUCTION

1.1 Historical 7

1.2 K&R-C 7

1.3 ANSI-C 7

1.4 C++ 8

1.5 Advantages 8

1.6 Disadvantages 8

1.1 Historical
Between the 1980s and 2000s, no programming language could boast of a growth in popu-
larity comparable to that of C and his brother C++. It was only around the year 2000 when
the C language had to pass its first place to the Java language - one of its grandsons. Even
in 2020 1 , C is still in second place in the popularity ranking, surrounded by Java, C++, C#
and PHP which are all in sort of derivatives of C.
The C language finds its sources in 1972 in the Bell Laboratories: To develop a portable
version of the UNIX operating system, Dennis M. Ritchie designed this structured program-
ming language, but very ’close’ to the machine.

1.2 K&R-C
In 1978, the duo Brian W. Kernighan / Dennis M. Ritchie published the classic definition
of the C language (known as the K&R-C standard) in a book called ’The C Programming
Language’.

1.3 ANSI-C
The success of the following years and the development of C compilers by other houses made
it necessary to define an updated and more precise standard. In 1983, the American National
Standards Institute (ANSI) commissioned a commission to develop ’an explicit and machine-
independent definition for language C’, which should still retain the spirit of the language.
The result was the ANSI-C standard. The second edition of the book ’The C Programming
Language’, published in 1988, fully respects the ANSI-C standard and has since become the
’bible’ of programmers in C.

1 https://www.tiobe.com/tiobe-index/

7
8 1.4. C++

1.4 C++
In 1983 a group of AT&T developers led by Bjarne Stroustrup created the C++ language. The
goal was to develop a language which would keep the advantages of ANSI-C (portability,
efficiency) and which would also allow object oriented programming. Since 1990 there has
been a draft for an ANSI-C++ standard. Meanwhile AT&T has developed two C++ compilers
which respect the new determinations of ANSI and which are considered as quasi-standards
(AT&T-C++ Version 2.1 [1990] and AT&T-C ++ Version 3.0 [1992]) .

1.5 Advantages
The great success of the C language can be explained by the following advantages; It is a(n)
... language:

1. universal: C is not oriented towards a field of special applications, such as FORTRAN


(scientific and technical applications) or COBOL (commercial applications or process-
ing large amounts of data).

2. compact: C is based on a limited core of functions and operators, which allows the
formulation of simple, but efficient expressions.

3. modern: It is a structured, declarative and recursive language; it offers control and


declaration structures comparable to those of the other major languages of this time
(FORTRAN, ALGOL68, PASCAL).

4. near the machine: as C was first developed to program the UNIX operating system,
it offers operators that are very close to those of machine language and functions that
allow easy access and direct to the internal functions of the computer (eg memory
management).

5. rapid: as C allows the use of expressions and operators which are very close to machine
language, it is possible to develop efficient and rapid programs.

6. machine independent: although C is a language close to the machine, it can be used on


any system with a C compiler. In the beginning C was mainly the language of working
systems under UNIX, today C has become the standard programming language in the
field of microcomputers.

7. portable: respecting the ANSI-C standard, it is possible to use the same program on
any other system (other hardware, other operating system), simply by recompiling it.

8. extensible: C doesn’t just consist of standard functions; the language is animated by


libraries of private functions or delivered by numerous development houses.

1.6 Disadvantages
Of course, nothing is perfect. Let’s take a quick look at the flip side:

1. Efficiency and comprehensibility: In C, we have the possibility of using compact and


efficient expressions. On the other hand, our programs must remain understandable
Chapter 1. INTRODUCTION 9

for ourselves and for others. As we will see in the following examples, these two re-
quirements can contradict each other.

Example 1.1 The following two lines print the first N elements of an array A[],
by inserting a space between the elements and starting a new line after each tenth
digit:
f o r ( i =0; i <n ; i ++)
p r i n t f ("%6d%c " , a [ i ] , ( i %10==9)? ’\n ’ : ’ ’);
This notation is very practical, but rather intimidating for a beginner. The other
variant is more readable, but it does not take advantage of the advantages of the
C language:
f o r ( I =0; I <N; I=I +1)
{
p r i n t f ("%6d " , A[ I ] ) ;
i f ( ( I %10) == 9 )
printf ("\n " ) ;
else
printf (" " ) ;
}

Example 1.2 The copytab() function copies the elements of a character string
T [] into another character string S[]:
void copytab ( char S [ ] , char T [ ] )
{
int I ;
I =0;
while ( T [ I ] != ’ \ 0 ’ )
{
S [ I ] = T[ I ] ;
I = I +1;
}
S[ I ] = ’\0 ’;
}
This definition of the function is valid in C, but in practice it would never be pro-
grammed thus. Using the possibilities of C, an experienced programmer prefers
the following solution:
void copytab ( char * S , char *T )
{
while ( * S++ = *T+ + ) ;
}
The second formulation of this function is elegant, compact, efficient and the
machine language translation provides very fast code ...; but although this way of
solving problems is the normal case in C, it is not so easy to follow the reasoning.
10 1.6. Disadvantages

Conclusions Of course, in the two examples above, the ’short’ formulations represent
the right style in C and are far preferable to the other two. So we find that:

• efficient programming in C requires a lot of experience and is not easily accessible


to beginners.
• without comments or explanations, the programs can become incomprehensible,
therefore unusable.

2. Portability and function libraries


The limits of portability
Portability is one of the most important advantages of C: by writing programs that
comply with the ANSI-C standard, we can use them on any machine with an ANSI-
C compiler. On the other hand, the directory of ANSI-C functions is quite limited.
If a programmer wishes to use a specific function of the machine (eg using a special
graphics card), he is assisted by a host of ’prefabricated’ functions, but he must be
aware that he risks losing portability . Thus, it becomes obvious that the advantages of
a portable program must be paid for by the restriction of the means of programming.

3. Programming discipline
The dangers of C
Here we come to a crucial point: C is a near-machine language, therefore dangerous
and although C is a structured programming language, it does not force us to adopt
a certain programming style. In a certain sense, everything is allowed and the temp-
tation to program ’spaghetti code’ is great. (Even the ’goto’ command, so feared by
purists is not lacking in C). The programmer therefore has many freedoms, but also
responsibilities: he must see to it that he adopts a clean, solid and understandable
programming style.

As the C language is introduced, this manual will contain some recommendations regarding the use
of the different programming means. It is impossible to give universal rules on this subject, but the
following two tips are valid for all programming languages: If, after reading only the comments of
a program, you do not understand how it works, then throw it away! (rule not written in the IBM
house)
Practice defensive programming ...
2. THE ENVIRONMENT AND LIBRARIES

2.1 Description of the Microsoft Visual Studio


environment 11

2.2 Select the ANSI-C compiler 16

2.3 Libraries of predefined functions 17


2.3.1 Using function libraries
2.3.2 #include
2.3.3 Files identification

For practical work in C, use a compiler and an easy-to-use editor. As an example, we describe
here the use of the Microsoft Visual Studio environment. This program offers us a comfortable
and fast programming surface. Any other compiler that allows programming according to the
ANSI-C standard does the trick as well.

2.1 Description of the Microsoft Visual Studio environment


Microsoft Visual Studio is a full implementation of the C++ AT&T standard (Version 2.1).
The Microsoft Visual Studio compiler is capable of producing ’pure’ C code according to
the Kernighan & Ritchie definition or according to the ANSI-C standard. On the other hand,
Microsoft Visual Studio offers us a whole series of libraries, which (sometimes at the expense
of portability) allow us to exploit the capacities of the PC.

11
12 2.1. Description of the Microsoft Visual Studio environment

To compile and run a C program using Visual Studio, follow these steps:

1. Launch Microsoft Visual Studio

2. Select FILE » New » Project

3. Select Visual C++ then Win32 Console Application option. Change the project name
if you want.
Chapter 2. THE ENVIRONMENT AND LIBRARIES 13

4. Click "OK". Click "Next >"

5. Make sure that Console Application is selected. Disable all other options and check
the "Empty project" box.
14 2.1. Description of the Microsoft Visual Studio environment

6. Click on "Finish".The project screen is shown below:

7. On the right side, under "Solution Explorer", right click on "Source Files". Select Add
» New Item.

You can activate Solution explorer from the VIEW tab


Chapter 2. THE ENVIRONMENT AND LIBRARIES 15

8. The dialog box is illustrated below:

9. Modify the file name of Source.cpp to any name with the extension .c. In this example,
I changed it to Main.c

10. Type your C program in the left panel. Then click on "Save"

11. Select the ANSI-C compiler (see next section)


16 2.2. Select the ANSI-C compiler

12. To compile the program, click on BUILD » Build Solution

You can quickly test if your code compiles by pressing the F7 key

13. The output screen will display the following results

Remember that the exe file is located under Projects\projectname\Debug\projectname.exe

14. To run the program, you can press Control-F5 or by clicking Debug –> Start Without
Debugging in the menu bar.

2.2 Select the ANSI-C compiler


As we use the Microsoft Visual Studio environment to compile programs corresponding to
the ANSI-C standard, we must first change the default compilation mode:

• Before running your project, you must tell Visual Studio that you have written C code;
otherwise, Visual Studio will assume that you have written C ++ code and things will
Chapter 2. THE ENVIRONMENT AND LIBRARIES 17

go wrong.
• Click Project –> Properties. Expand Configuration Properties, then expand C/C++.
Click on Advanced. Replace Compiler with Compile As to Compile as C Code (/TC)
and click OK.

2.3 Libraries of predefined functions


2.3.1 Using function libraries
Practice in C requires the use of function libraries. These libraries are available in their
precompiled form (extension: .LIB). To be able to use them, we must include header files
(header files - extension .H) in our programs. These files contain ’prototypes’ of the func-
tions defined in the libraries and create a link between the precompiled functions and our
programs.

2.3.2 #include
The #include instruction inserts the header files specified as arguments into the program
text at compile time.

2.3.3 Files identification


When programming in C, we therefore work with different types of files which are identified
by their extensions:
*.C source files
*.OBJ compiled files (object versions)
*.EXE compiled and linked files (executable versions)
*.LIB precompiled function libraries
*.H header files

Example 2.1 We have written a program which uses predefined mathematical and
graphical functions. To be able to use these functions, the program needs the libraries:
• MATHS.LIB
• GRAPHICS.LIB
We must therefore include the corresponding header files in the source code of our
program using the instructions:
18 2.3. Libraries of predefined functions

#include <math.h>
#include <graphics.h>
After compilation, the precompiled library functions will be added to our program to
form an executable version of the program.

Figure 2.1: Function libraries and compilation


3. BASIC CONCEPTS

3.1 Hello C ! 19

3.2 The components of a C program 19


3.2.1 The functions
3.2.2 The main function
3.2.3 The variables
3.2.4 Identifiers
3.2.5 Comments

3.3 Discussion of the ’Hello World’ example 23

Before you can understand or even write programs, you must know the composition of pro-
grams in the programming language. In this chapter we will discuss a small program by
highlighting the basic structures of a C program.

3.1 Hello C !
Let’s follow the tradition and start discovering C with the inevitable ’hello world’ program.
This program does nothing but print the following words on the screen:

# i n c l u d e < s t d i o . h>
i n t main ( )
/* Our f i r s t program i n C */
{
p r i n t f ( " h e l l o , world \n " ) ;
return 0;
}

In the following, we will discuss the details of this implementation.

3.2 The components of a C program


Programs in C are mainly composed of functions and variables. For practice, it is therefore
essential to familiarize yourself with the fundamental characteristics of these elements.

3.2.1 The functions


In C, the main program and the subroutines are defined as functions. There are no special
structures for the main program or procedures (as in Pascal or in algorithmic language).
The main program being also a ’function’, we must be interested from the start in the
definition and characteristics of functions in C.

19
20 3.2. The components of a C program

Definition of a function in C

<ResType> <FunctName> (<Par1Type> <Par1Name> ,


<Par2Type> <Par2Name> , . . . )
{
<local declarations >
<instructions >
}

In C, a function is defined by:

• a declarative line which contains:

– <ResType> - the type of the function result


– <FunctName> - the name of the function
– <Par1Type> <Par1Name>, <Par2Type> <Par2Name>, ... the types and names of
the function parameters

• an instruction block delimited by curly braces { }, containing:

– <local declarations> - declarations of local data (i.e. data that is only known
within the function)
– <instructions> - the list of instructions that defines the action to be performed

Result of a function By definition, any function in C provides a result whose type must
be defined. If no type is explicitly defined, C assumes by default that the result type is int
(integer).
The return of the result is generally done at the end of the function by the instruction return.
The type of a function that does not provide a result is declared as void (empty).

Parameters of a functionn The definition of the parameters (arguments) of a function is


placed in parentheses ()behind the name of the function. If a function does not need param-
eters, the parentheses remain empty or contain the word void. The minimal function which
does nothing and which produces no result is then:

void dummy ( ) { }

Instructions In C, all simple instructions are terminated with a semicolon; (even if it is in


the last position in an instruction block).

p r i n t f ( " h e l l o , world \n " ) ;


Chapter 3. BASIC CONCEPTS 21

3.2.2 The main function


The main function is the main function of programs in C: It must be found in all programs.
Executing a program automatically calls the main function.

Definition of the main function in C

i n t main ( )
{
<d e c l a r a t i o n s >
<instructions >
return 0;
}

Main Result In principle, any program should return a value as an error code to its envi-
ronment. Therefore, the result type of main is always int. In general, the type of the main
function is not declared explicitly, since it is the default type. We will end our programs
with the instruction:

return 0;

which indicates to the environment that the program ended successfully, without anoma-
lies or fatal errors.

parameters of main
• If the list of parameters for themain function is empty, it is customary to declare it with
().

• If we use predefined functions (for example:printf), we must precede the definition


of main by the corresponding #include instructions.

It is possible to pass arguments from the command line to a program. In this case, the list of parameters must
contain the corresponding declarations. In our course, we are not going to use command line arguments.
Thus the list of parameters of the main function will be empty (void) in all our examples and we can use the
following declaration which makes use of the default values:

main ( . . . ) { . . . }

3.2.3 The variables


Variables contain the values that are used during program execution. Variable names are
arbitrary identifiers. The different types of simple variables and the admissible operators
are discussed in the next chapter.
22 3.2. The components of a C program

3.2.4 Identifiers
The names of functions and variables in C are made up of a series of letters and numbers.
The first character must be a letter. The symbol ’_’ is also considered a letter.

• The set of usable symbols is therefore: 0,1,2,...,9,A,B,...,Z,_,a,b,...,z

• The first character must be a letter (or the symbol ’_’)

• C distinguishes between upper and lower case, as follows: ’Name_of_variable’ is dif-


ferent from ’name_of_variable’

• There is no limit to the length of identifiers, but C distinguishes ’only’ the first 31
characters.

• It is not recommended to use the symbol ’_’ as the first character for an identifier, as it is often used
to define the global variables of environment C.
• The standard says that the validity of external names (eg function names or global variables) can be
limited to 6 characters (even without taking uppercase and lowercase) by the implementation of the
compiler, but all modern compilers distinguish at least 31 characters so that we can generalize that
in practice the above rules apply to all identifiers.

Example 3.1
Correct identifiers: Incorrect identifiers:
name1 1name
name_2 name.2
_name_3 -name-3
Name_of_variable Name of variable
deuxieme_choix deuxième_choix
mot_francais mot_français

Exercise 3.1 Which of the following identifiers are accepted by C?


function-1 _AVERAGE_of_MONTH_ 3rd_day
lower_bound. lim_supérieure __A_
_ a 3

3.2.5 Comments
A comment on one or multiple lines always begins with the two symbols ’/*’ and ends with
the symbols ’*/’. It is prohibited to use nested comments.

Example 3.2
/* This is a correct comment */
/* This is /* obviously */ forbidden */

A comment on one line only always starts with the two symbols //.
Chapter 3. BASIC CONCEPTS 23

Example 3.3
// This is a comment on one line only !

3.3 Discussion of the ’Hello World’ example


Let’s take the ’Hello World’ program and find the peculiarities of a C program.

# i n c l u d e < s t d i o . h>
i n t main ( )
/* Our f i r s t program i n C */
{
p r i n t f ( " h e l l o , world \n " ) ;
return 0;
}

Discussion
• The main function does not receive data, so the list of parameters is empty.

• The main function provides a numeric error code to the environment, so the type of
the result is int and does not need to be declared explicitly.

• The program contains no variables, so the declaration block is empty.

• The main function contains two instructions:

– the call to the function printf with the argument "hello, world \n";
Effect: Display the character string "hello world \n".
– the command return with the argument 0;
Effect: Return the value 0 as an error code to the environment.

• The argument of the function printf is a character string indicated between the quotes.
Such a string of characters is called a constant string.

• The symbol sequence ’\n’ at the end of the string "hello, world \n" is the C notation for
’line feed’. In C, there are several pairs of symbols that control the display or printing
of text. These escape sequences are always preceded by the escape character ’\’.

printf and the <stdio.h> library The printf function is part of the standard function
library <stdio.h> which manages data input and output. The first line of the program:

# i n c l u d e < s t d i o . h>

instructs the compiler to include the header file ’STDIO.H’ in the program text. The file
’STDIO.H’ contains the information necessary to be able to use the functions of the standard
library <stdio.h>.
24 3.3. Discussion of the ’Hello World’ example

Exercise 3.2 Modify the ’hello world’ program so as to obtain the same result on the
screen by using the printf function several times.

Exercise 3.3 Below, you find a simple program in C. Try to distinguish and classify
as much as possible the elements that make up this program (comments, variables,
declarations, instructions, etc.)

# i n c l u d e < s t d i o . h>
/* This program c a l c u l a t e s the sum o f 4 i n t e g e r numbers
e n t e r e d on the keyboard .
*/
i n t main ( )
{
i n t NUMBER, SUM, COUNTER;

// I n i t i a l i z a t i o n o f v a r i a b l e s
SUM = 0 ;
COUNTER = 0 ;
/* Reading the data */
while (COUNTER < 4 )
{
/* Read the upcoming number */
p r i n t f ( " Enter an i n t e g e r : " ) ;
s c a n f ("% i " , &NUMBER) ;
/* Add the number o t the r e s u l t */
SUM += NUMBER;
/* Increment the c o u n t e r */
COUNTER++;
}
/* Display the r e s u l t */
p r i n t f ( " The sum i s : %i \n " , SUM ) ;
return 0;
}

Exercise 3.4 Experiment with the escape sequences you find in the table below and
fill in the empty columns.
Chapter 3. BASIC CONCEPTS 25

escape sequences description


\n new line
\t
\b
\r
\"
\\
\0
\a
4. BASIC TYPES, OPERATORS AND EXPRESSIONS

4.1 Simple types 26

4.2 The declaration of simple variables 29

4.3 Standard operators 33

4.4 Expressions and instructions 36

4.5 Operator priorities 37

4.6 Standard arithmetic functions 41

4.7 Type conversions 42

Vocabulary summary
Variables and constants are the main data that can be handled by a program. The declara-
tions introduce the variables that are used, fix their type and sometimes also their starting
value. Operators control the actions of the data values. To produce new values, variables and
constants can be combined using operators in expressions. The type of data determines the set
of admissible values, the number of bytes to be reserved in memory and the set of operators
that can be applied to it.
Motivation
The great flexibility of C allows us to use operands of different types in the same calculation.
This advantage can turn into a terrible trap if we do not correctly predict the side effects
of such an operation (automatic type conversions, rounding, etc.). A careful study of this
chapter can therefore help to avoid sometimes ’inexplicable’ phenomena ...

4.1 Simple types


Sets of numbers and their representation In mathematics, we distinguish various sets of
numbers:

• the set of integer numbers IN,

• the set of relative integers ZZ,

• the set of rationals Q,

• the set of real IR.

In mathematics the order of magnitude of numbers is unlimited and rationals can be


expressed without loss of precision.
A computer can only easily process whole numbers of limited size. It uses the binary
system to calculate and save these numbers. It is only through calculation and representation
tricks that the computer obtains correctly approximated values of very large integers, reals
or rationals with an infinite decimal part.

26
Chapter 4. BASIC TYPES, OPERATORS AND EXPRESSIONS 27

The programmer’s work Even a programmer using C should not know all the details of
coding and calculation methods, he should still be able to:

• choose a numeric type appropriate to a given problem;


i.e.: find an optimum of precision, calculation time and space to reserve in memory

• choose an appropriate type for the display on the screen

• predict the type resulting from an operation between different numeric types;
i.e.: know the automatic type transformations that C performs during calculations.

• predict and optimize the accuracy of intermediate results during a complex calcula-
tion;
i.e.: change the order of operations if necessary or force the computer to use a more
suitable type (casting).

Example 4.1 Suppose that the mantissa of the chosen type has only 6 decimal places
(which is very realistic for the float type):
(1.00001 ∗ 108 + 850) − 1 ∗ 108 = 1.00001 ∗ 108 − 1 ∗ 108 = 1000 8

(1.00001 ∗ 108 − 1 ∗ 108 ) + 850 = 1000 + 850 = 1800 4

Integer types Before we can use a variable, we need to look at two characteristics of its
numeric type:

1. the range of admissible values

2. the number of bytes that is reserved for a variable

The following table summarizes the characteristics of the integer numeric types of C:
definition description domain min domain max number of bytes
char character -128 127 1
short short integer -32768 32767 2
int / long integer / long -2147483648 2147483647 4
long long long long integer -9223372036854775808 9223372036854775807 8

• char : character
A variable of type char can contain a value between -128 and 127 and it can undergo
the same operations as variables of type short, int or long.

• int : integer
On each machine, the int type is the basic type for calculations with integers. The
coding of variables of the int type is therefore dependent on the machine. On IBM-PCs
under MS-DOS, a variable of type int is coded in two bytes.

• short : short integer


The short type is generally coded in 2 bytes. As an int variable also occupies 2 bytes on
our system, the short type only becomes necessary, if we want to use the same program
on other machines, on which the standard type of integers is not necessarily 2 bytes.
28 4.1. Simple types

• The signed/unsigned modifiers:


If we add the unsigned prefix to the definition of a type of integer variables, the vari-
able domains are moved as follows
definition description domain min domain max number of bytes
unsigned char character 0 255 1
unsigned short short integer 0 65535 2
unsigned int integer 0 4294967295 4
unsigned long long integer 0 4294967295 4

1. The calculation with integers defined as unsigned corresponds to the arithmetic modulo 2n . So, using
an unsigned short variable X, we get the following result:
Assignment : X = 65500 + 100
Result : X = 64 /* [+216 ] */

2. By default, integers of type short, int and long have a sign. The default char type is dependent on
the compiler and can be signed or unsigned. Thus, the signed attribute has only one meaning in
connection with char and can force the machine to use the representation of the characters with sign
(which is however not very usual).

3. The limit values of the different types are indicated in the header file <limits.h>.

4. In principle, we can say that


sizeof(short) <= sizeof(int) <= sizeof(long)
So on certain architecture we can have short = 2 bytes, int = 2 bytes, long = 4 bytes and on other
short = 2 bytes, int = 4 bytes, long = 4 bytes.

Rational types In computer science, rationals are often called ’floats’. This term comes
from ’floating point’ and finds its root in the traditional notation of rationals:
<+|-> <mantissa> * 10<exponent>
<+|-> is the positive or negative sign of the number
<mantissa> is a positive decimal with a single digit in front of the decimal point.
<exponent> is an integer

Example 4.2 3.14159 ∗ 100


1.25003 ∗ 10−12
4.3001 ∗ 10321
− 1.5 ∗ 103

In C, we have the choice between three types of rational: float, double and long double.
In the table below, you will find their characteristics:

1. min and max represent the positive minimum and maximum values. Negative values
can vary in the same areas.

2. mantissa indicates the number of significant digits of the mantissa.


Chapter 4. BASIC TYPES, OPERATORS AND EXPRESSIONS 29

definition precision mantissa domain min domain max number of bytes


float simple 6 3.4 * 10−38 3.4 * 1038 4
double double 15 1.7 * 10−308 1.7 * 10308 8
long double suppl. 19 3.4 * 10−4932 1.1 * 104932 10

Details of the implementation are given in the header file <float.h>.

Exercise 4.1 What numeric type(s) can you use for the following groups of numbers?
Draw up a table and mark the most economical choice:

1. 1 12 4 0 -125

2. 1 12 -4 0 250

3. 1 12 4 0 250

4. 1 12 -4 0.5 125

5. -220 32000 0

6. -3000005.000000001

7. 410 50000 2

8. 410 50000 -2

9. 3.14159265 1015

10. 2 ∗ 107 10000001

11. 2 ∗ 10−7 10000001

12. −1.05 ∗ 1050 0.0001

13. 305.122212 0 -12

4.2 The declaration of simple variables


Now that we know the main types of variables, we still need the syntax for their declaration:

Declaration of variables in C

<Type> <Var1Name>,<VarwName> , . . . , < VarNName>;

Example 4.3
int counter, X, Y;
float height, width;
double atomic_mass;
30 4.2. The declaration of simple variables

char key;
int t_squeez;

C language In general, we have the choice between several types and we must find the one
that best corresponds to the field and the values to be treated. Here are some general rules
concerning the numerical variables of the C language:

• The syntax for declarations in C. Note the semicolons at the end of declarations in C.

• integer: We have the choice between all the integer types (inclusively char) in their
signed or unsigned forms. If the numbers get too big for unsigned long, use a rational
type (eg: double)

• rational: We can choose between the three rational types by observing not only the
maximum size of the exponent, but even more the number of significant figures of the
mantissa.

• character: Any variable of type char can contain one character only. In C, you should
always be aware that this ’character’ is nothing more than a number corresponding to
a code (here: ASCII code). This number can be integrated into all kinds of algebraic or
logical operations ...

• string: In C there is no special type for strings. The means of treating character strings
will be described in the following chapters.

• boolean: In C there is no special type for boolean variables. All types of numeric vari-
ables can be used to express logical operations:

– false logical value <=> zero numeric value


– true logical value <=> any value other than zero

If the use of a Boolean variable is essential, the most natural will be to use a variable of
the type int.

Logical operations in C always return results of the type int:

– 0 for false
– 1 for true

Numerical constants In practice, we often use constant values to calculate, to initialize


variables, to compare them to variables, etc. In these cases, the computer must assign a
numeric type to the constant values. In order to be able to predict the exact result and type
of the calculations, it is important for the programmer to know the rules according to which
the computer chooses the types for the constants.
Chapter 4. BASIC TYPES, OPERATORS AND EXPRESSIONS 31

Integer constants

• Automatic type: When assigning a type to an integer constant, C generally chooses the
most economical solution.

• The type of integer constants

– If possible, integer constants get the type int.


– If the number is too large for int it will automatically have the long or long long
type.
– If the number is too large for long long, it will have the type unsigned long.
– If the number is too large for unsigned long, the program’s reaction is unpre-
dictable.

• Forced type: If we want to force the computer to use a type of our choice, we can use
the following suffixes:
suffix type example
u or U unsigned (int or long) 550u
l or L long 123456789L
ul or UL unsigned long 12092UL

Example 4.4
12345 type int
52000 type long
-2 type int
0 type int
1u type unsigned int
52000u type unsigned long
22LU Error !

• Octal and hexadecimal base: It is possible to declare integer constants using the octal
or hexadecimal base:

– If an integer constant begins with 0 (zero), then it is interpreted in octal base.


– If an integer constant begins with 0x or 0X, then it is interpreted in hexadecimal
base.

Example 4.5
decimal base octal base hexadecimal base binary representation
100 0144 0X64 1100100
255 0377 0xff 11111111
65536 0200000 0X10000 10000000000000000
12 014 0XC 1100
4040 07710 0xFC8 111111001000
32 4.2. The declaration of simple variables

The rational constants The rational constants can be indicated:


• in decimal notation, i.e. using a decimal point:
Examples 123.4 -0.001 1.0

• in exponential notation, i.e. using an exponent separated from the decimal number by
the characters ’e’ or ’E’:
Exemples 1234e-1 -1E-3 0.01E2
The computer recognizes the rational constants at the decimal point or at the exponent’s
separator (’e’ or ’E’). By default, the rational constants are of type double.

The type of rational constants


• Without suffix, the rational constants are of the double type.

• The suffix f or F forces the use of the float type.

• The suffix l or L forces the use of the long double type.

Constant characters
Constants which designate a (single) character are always indicated between apostrophes:
for example ’x’. The value of a constant character is the internal code of this character. This
code (here: the ASCII code) is machine dependent.
Constant characters can appear in arithmetic or logical operations, but in general they
are used to be compared to variables.

Escape sequences
As we have seen, the printing and display of text can be controlled using escape sequences.
An escape sequence is a couple of symbols, the first of which is the escape sign ’\’. At the time
of compilation, each escape sequence is translated into a control character in the machine
code. As the escape sequences are identical on all machines, they allow us to write portable
programs, i.e. programs that have the same effect on all machines, regardless of the character
code used.
\a bell \\ backslash
\b back cursor \? interrogation point
\t tabulation \’ apostrophe
\n new line \" quotation marks
\r back to the beginning of the line \f page break (printer)
\0 NULL \v vertical tabulator

Table 4.1: Escape sequences

The NULL character


The constant ’\0’ which has the numeric value zero (not to be confused with the character
’0’ !!) has a special meaning in the processing and storage of strings: In C the character ’\0’
defines the end of a character string.
Chapter 4. BASIC TYPES, OPERATORS AND EXPRESSIONS 33

Exercise 4.2 Complete the following table:


decimal base octal base hexadecimal base binary representation
01770
8100
0XAAAA
1001001001
1100101011111110
10000
0234

Exercise 4.3 For correctly defined constants, find the types and decimal numeric
values:
12332 23.4 345LU 34.5L -1.0
0xeba 0123l ’\n’ 1.23ul -1.0e-1
0FE0 40000 40000u 70000u 1e1f
’0’ o ’\0’ 0 ’O’
67e0 \r 01001 0.0l 0XEUL

Initialization of variables

Initialization In C, it is possible to initialize the variables when declaring them:

i n t MAX = 1023;
char TAB = ’ \ t ’ ;
f l o a t X = 1 . 0 5 e −4;

const Using the const attribute, we can indicate that the value of a variable does not change
during a program:

const int MAX = 7 6 7 ;


c o n s t double e = 2.71828182845905;
c o n s t char NEWLINE = ’ \ n ’ ;

4.3 Standard operators

Assignment in algorithmic language

<VariableName> = <Expression >;


34 4.3. Standard operators

Example 4.6

• Assignment with constant values

C Constant type
LONG = 141; (integer constant)
PI = 3.1415926; (rational constant)
NATION = ’L’; (character constant.)
• Assignment with variable values

VALUE = X1A;
LETTER = MAIL;
• Assignment with expression values

AREA = PI*pow(R,2);
AVERAGE = (A+B)/2;
UN=pow(sin(X),2)+pow(cos(X),2);
RES = 45+5*X;
GREATER = (X>Y);
CORRECT = (’a’ == ’a’);

Observations The operators and arithmetic functions used in expressions will be intro-
duced later in the chapter. We already observe that:

• there is no standard function in C to calculate the square of a value; we can refer to the
more general function pow(x, y) which calculates xy .

• the equality test in C is formulated with two signs of equality ==, the assignment with
only one =.

Known operators Before we embark on the ’specialties’ of the C language, let us first find
the operators corresponding to those that we already know in descriptive language.

• Arithmetic operators

+ addition
- subtraction
* multiplication
/ division (integer and rational!)
% modulo (rest of an integer division)
• Logical operators

&& logical and (and)


|| logical or (or)
! logical negation (not)
Chapter 4. BASIC TYPES, OPERATORS AND EXPRESSIONS 35

• Comparison operators

== equal to
!= different from
<, <=, >, >= smaller than, ...

• Logical operations
The results of comparison operations and logical operators are of the type int:

– the value 1 corresponds to the boolean value true


– the value 0 corresponds to the boolean value false

Logical operators treat any non-zero value as true and zero as false:

Example 4.7
32 && 2.3 → 1
!65.34 → 0
0||!(32 > 12) → 0

The particular operators of C

Assignment operators
In practice, we often find assignments like:i = i + 2
In C, we will rather use the more compact formulation: i+ = 2
The operator + = is an assignment operator.
For most expressions of the form:

expr1 = ( expr1 ) op ( expr2 )

there is an equivalent formulation which uses an assignment operator:

expr1 op= expr2

Assignment operators

+= add to
-= decrease by
*= multiply by
/= divide by
%= modulo

The formulation with an assignment operator is often closer to human logic:


36 4.4. Expressions and instructions

A man would say «Add 2 to I» rather than «Add 2 to I and write the result in I»
Assignment operators can help the compiler generate more efficient code because expr1 is evaluated only
once.
Assignment operators become the most interesting if expr1 is a complex expression. This can be the case if
we calculate with arrays.
The expression:

Element [ n * i + j ] = Element [ n * i + j ] * x [ j ] ;

can be formulated more efficiently and clearly:

Element [ n * i + j ] *= x [ j ] ;

Increment and decrement operators


The most frequent assignments are of the type:
I = I + 1 and I = I − 1
In C, we have two unusual operators for these assignments:

I + + ou + + I for incrementation (increase by one)


I − − ou − − I for decrement (decrease by one)
The ++ and ++ operators are used in the following cases:
• increment / decrement a variable (eg in a loop). In this case there is no difference
between the prefix notation (+ + I − − I) and the postfix notation (I + + I − −).

• increment / decrement a variable and at the same time assign its value to another
variable. In this case, we have to choose between prefix and postfix notation:

– X = I + + first passes the value from I to X and increments after


– X = I − − first passes the value from I to X and decrements after
– X = + + I increments first and passes the incremented value to X
– X = − − I decrements first and passes the decremented value to X

Example 4.8 Suppose that the value of N is equal to 5:

postfix increment: X = N++; Result: N=6 and X=5


prefix increment: X = ++N; Result: N=6 and X=6

4.4 Expressions and instructions


Expressions The formation of expressions is defined by induction:
• Constants and variables are expressions.
Chapter 4. BASIC TYPES, OPERATORS AND EXPRESSIONS 37

• The expressions can be combined with one another by operators and thus form more
complex expressions.

• Expressions can contain function calls and they can appear as parameters in function
calls.

Example 4.9

i =0
i ++
X=pow (A, 4 )
p r i n t f ( " Hello ! \ n " )
a =(5* x+10*y ) * 2
( a+b)>=100
p o s i t i o n != l i m i t

Instructions An expression like I = 0 or I + + or printf (...) becomes an instruction, if fol-


lowed by a semicolon.

Example 4.10

i =0;
i ++;
X=pow (A , 4 ) ;
p r i n t f ( " Hello ! \ n " ) ;
a =(5* x+10*y ) * 2 ;

Evaluation and Results In C all expressions are evaluated and return a value as result:
(3 + 2 == 5) returns the value 1 (true)
A = 5 + 3 returns the value 8

As assignments are also interpreted as expressions, it is possible to take advantage of the


value returned by the assignment:
((A = sin(X)) == 0.5)

4.5 Operator priorities


The order of the evaluation of the different parts of an expression corresponds in principle
to that which we know of mathematics.
38 4.5. Operator priorities

Example 4.11 Suppose for the following statement: A=5, B=10, C=1

X = 2*A+3*B+4*C ;

The computer first evaluates the multiplications: 2 ∗ A ==> 10, 3 ∗ B ==> 30, 4 ∗ C ==> 4
Then, it adds up the three results obtained: 10 + 30 + 4 ==> 44
At the end, it assigns the general result to the variable: X = 44

Operator priority We then say that multiplication takes precedence over addition and that
multiplication and addition take precedence over assignment.
If we want to force the computer to start with an operator with a lower priority, we must
(as in mathematics) surround the term in question with parentheses.

Example 4.12 In the instruction:

X = 2*A+3*B+4*C ;

the computer first evaluates the expression in parentheses, then the multiplications,
then the addition and finally the assignment. (Using the values from the example
above, the result will be 164)

Between the operators that we know so far, we can distinguish the following priority
classes:

Priority 1 (the strongest): ()


Priority 2: !++−−
Priority 3: ∗/%
Priority 4: +−
Priority 5: <<=>>=
Priority 6: ==! =
Priority 7: &&
Priority 8: ||
Priority 9 (the weakeste): =+=−=∗=/ =%=

Table 4.2: Priority classes

Evaluation of operators of the same class –> In each priority class, operators have the
same priority. If we have a series of binary operators of the same class, the evaluation is
done by going from left to right in the expression.
<– For unary operators (!, ++, -) and for assignment operators (=, + =, − =, ∗ =, / =, % =), the
evaluation is done from right to left in the expression.
Chapter 4. BASIC TYPES, OPERATORS AND EXPRESSIONS 39

Example 4.13 L’expression

10+20+30−40+50−60

will be evaluated as follows:


10+20 ==> 30
30+30 ==> 60
60-40 ==> 20
20+50 ==> 70
70-60 ==> 10

Example 4.14 For A=3 and B=4, the expression

A *= B += 5

will be evaluated as follows:

Example 4.15 For A=1 and B=4, the expression

!−−A==++!B

will be evaluated as follows:

The parentheses Parentheses are only necessary if we need to force the priority, but they
are also allowed if they do not change the priority. In the case of nested parentheses, the
evaluation is done from the inside to the outside.
40 4.5. Operator priorities

Example 4.16 Assuming again that A = 5, B = 10, C = 1 the following expression will
evaluate to 134:

X = ( ( 2 *A+3)*B+4)*C

Observe the priority of assignment operators :


X∗ = Y + 1 <=> X = X ∗ (Y + 1)
X∗ = Y + 1 is NOT equivalent to X = X ∗ Y + 1

Exercise 4.4 Evaluate the following expressions assuming


a = 20 b = 5 c = −10 d = 2 x = 12 y = 15
Note each time the value returned as a result of the expression and the values of the
variables whose content has changed.
(1) ( 5 *X) + 2 * ( ( 3 * B ) + 4 )
(2) ( 5 * ( X+ 2 ) * 3 ) * ( B+4)
(3) A == ( B=5)
(4) A += (X+5)
(5) A != (C *= ( −D) )
(6) A *= C+(X−D)
(7) A %= D++
(8) A %= ++D
(9) (X+ + ) * (A+C)
(10) A = X * ( B<C)+Y * ! ( B<C)
(11) ! ( X−D+C ) | | D
(12) A&&B||!0&&C&&!D
(13) ( ( A&&B ) | | ( ! 0 & &C))&&!D
(14) ( ( A&&B ) | | ! 0 ) & & (C&&(!D) )

Exercise 4.5 Eliminate unnecessary parentheses in expressions from the previous ex-
ercise.
Chapter 4. BASIC TYPES, OPERATORS AND EXPRESSIONS 41

4.6 Standard arithmetic functions

The following functions are predefined in the standard library <math.h>. To be able to use
them, the program must contain the line:

# i n c l u d e <math . h>

Data type The arguments and results of the arithmetic functions are of the double type.

C COMMAND EXPLANATION
exp(X) exponential function
log(X) natural logarithm for X > 0
log10(X) base 10 logarithm for X > 0
pow(X, Y ) X exponent Y
sqrt(X) square root of X for X>0
f abs(X) absolute value of X
f loor(X) round down
ceil(X) round up
f mod(X, Y ) rational remainder of X / Y (same sign as X) for X different from 0
sin(X)cos(X)tan(X) sine, cosine, tangent of X
asin(X)acos(X)atan(X) arcsin(X), arccos(X), arctan(X)
sinh(X)cosh(X)tanh(X) hyperbolic sine, cosine, tangent of X

Table 4.3: Arithmetic functions

The above list of functions lists only the most common functions. For the complete list and the predefined
constants see <math.h>.

Exercise 4.6 Try the following program and modify it so that it displays:

• AB ,

• lthe hypotenuse of a right triangle of sides A and B,

• the tangent of A using only the sin and cos functions,

• the rounded value (in minus) of A/B,

• The rounded value (in minus) to three positions behind the comma of A/B.
42 4.7. Type conversions

# i n c l u d e < s t d i o . h>
i n t main ( )
{
double A ;
double B ;
double RES ;
/* Reading A and B */
p r i n t f ( " Enter A value : ");
s c a n f ("% l f " , &A ) ;
p r i n t f ( " Enter B value : ");
s c a n f ("% l f " , &B ) ;
/* C a l c u l a t i o n */
RES = A*A ;
/* d i s p l a y the r e s u l t */
p r i n t f ( " The square o f A i s %f \n " , RES ) ;

/* C a l c u l a t i o n */
RES = B*B ;
/* d i s p l a y the r e s u l t */
p r i n t f ( " The square o f B i s %f \n " , RES ) ;
return 0;
}

4.7 Type conversions


The great flexibility of the C language makes it possible to mix data of different types in
an expression. Before calculating, the data must be converted to the same type. Most of
these conversions happen automatically, without the intervention of the programmer, who
still has to predict their effect. Sometimes it is necessary to convert data into a different
type from that which automatic conversion would choose; in this case, we have to force the
conversion using a special operator ("cast").

Automatic type conversions

Calculations and assignments If an operator has operands of different types, the values of
the operands are automatically converted to a common type. These implicit manipulations
generally convert smaller ’types’ to ’wider’ types; that way you don’t lose precision.
During an assignment, the data to the right of the equality sign is converted into the type
to the left of the equality sign. In this case, there may be a loss of precision if the type of the
destination is weaker than that of the source.

Example 4.17 Consider the following calculation:


Chapter 4. BASIC TYPES, OPERATORS AND EXPRESSIONS 43

int I = 8;
float X = 12.5;
double Y ;
Y = I * X;

To be able to multiply with X, the value of I is converted to float (the larger of the two
types). The result of the multiplication is of type float, but before being assigned to Y,
it is converted to a double. We get as result: Y = 100.00

Function calls When a function is called, the parameters are automatically converted into
the types declared in the definition of the function.

Example 4.18 During the following expressions, we witness three automatic conver-
sions:

i n t A = 200;
i n t RES ;
RES = pow (A, 2 ) ;

When the pow function is called, the value of A and the constant 2 are converted to
double, because pow is defined for data of this type. The result (double type) returned
by pow must be converted to int before being assigned to RES.

Automatic conversion rules Automatic conversions during an operation with,

1. two integers: First, the char and short types are converted to int. Then the computer
chooses the larger of the two types from the following scale: int, unsigned int,
long, unsigned long

2. an integer and a rational: The integer type is converted to the rational type.

3. two rational: The computer chooses the larger of the two types according to the fol-
lowing scale: float, double, long double

4. assignments and assignment operators: During an assignment, the result is always


converted into the type of the destination. If this type is weaker, there may be a loss of
precision.

Example 4.19 Let’s look at the conversions required during a simple division:
44 4.7. Type conversions

int X;
f l o a t A= 1 2 . 4 8 ;
char B=4;
X=A/B ;

B is converted to float (rule 2). The result of the division is of type float (value 3.12)
and will be converted to int before being assigned to X (rule 4), which leads to the
result X = 3.

The mixture of different numerical types in a calculation can encourage not to take into account the con-
version phenomena and sometimes leads to unexpected results ...

Example 4.20 In this example, we divide 3 by 4 three times and we observe that the
result does not only depend on the type of the destination, but also on the type of the
operands.

char A=3;
i n t B=4;
f l o a t C=4;
f l o a t D, E ;
char F ;
D = A/C ;
E = A/B ;
F = A/C ;

For the calculation of D, A is converted to float (rule 2) and divided by C. The result
(0.75) is assigned to D which is also of type float. We therefore obtain: D = 0.75
For the calculation of E, A is converted to int (rule 1) and divided by B. The result of
the division (type int, value 0) is converted to float (rule 4). We therefore obtain: E =
0.000
For the calculation of F, A is converted to float (rule 2) and divided by C. The result
(0.75) is translated back to char (rule 4). We therefore obtain: F = 0

Loss of accuracy When we convert a value to a type that is not precise enough or not big
enough, the value is cut without rounding and without warning ...
Example 4.21

unsigned i n t A = 70000;
/* the value o f A w i l l be : 70000 mod 65536 = 4464 */
Chapter 4. BASIC TYPES, OPERATORS AND EXPRESSIONS 45

Exercise 4.7 Let the declarations:

long A = 1 5 ;
char B = ’A ’ ; /* code ASCII : 65 */
short C = 10;

What are the type and value of each expression:


(1) C + 3
(2) B + 1
(3) C + B
(4) 3 * C + 2 * B
(5) 2 * B + (A + 10) / C
(6) 2 * B + (A + 1 0 . 0 ) / C

Forced type conversions (casting) It is possible to explicitly convert a value to any type
by forcing the transformation using the syntax:

(<Type >) <Expression >

Example 4.22 We divide two variables of the integer type. To have more precision, we
want to have a result of rational type. To do this, we convert one of the two operands
to float. Automatically C will convert the other operand to float and perform a rational
division:

char A=3;
i n t B=4;
f l o a t C;
C = ( f l o a t )A/B ;

The value of A is explicitly converted to float. The value of B is automatically converted


to float (rule 2). The result of the division (rational type, value 0.75) is assigned to C.
Result: C = 0.75

The contents of A and B remain unchanged; only the values used in the calculations are converted!
5. READ AND WRITE DATA

5.1 Formatted data writing 46

5.2 Formatted data reading 50

5.3 Writing a character 53

5.4 Reading a character 54

The standard library <stdio.h> contains a set of functions which ensure the communication
of the machine with the outside world. In this chapter, we will discuss the most important
ones:
1. printf() formatted data writing
2. scanf() formatted data reading
3. putchar() writing a character
4. getchar() reading a character

5.1 Formatted data writing


The printf function is used to transfer text, variable values or expression results to the stan-
dard output file stdout (by default the screen).

p r i n t f (" < format >" , < Expr1 >,<Expr2 > , . . . )

• "<format>" : representation format

• <Expr1>,... : variables and expressions whose values are to be represented

The "<format>" part is actually a character string which can contain:

• a text

• escape sequences

• format specifiers

– the format specifiers indicate how the values of <Expr1..N> expressions are printed.
– The "<format>" part contains exactly one format specifier for each expression
<Expr1..N>.

46
Chapter 5. READ AND WRITE DATA 47

– Format specifiers always start with the % symbol and end with one or two char-
acters that indicate the print format.
– Format specifiers involve converting a number to a string. They are also called
conversion symbols.

Example 5.1 The following instructions:

i n t A = 1234;
i n t B = 567;
p r i n t f ("% i m u l t i p l y %i i s %l i \n " , A, B , ( long )A*B ) ;

will display on the screen: 1234 multiply 567 is 699678

printf’s arguments are

• the format part : "%i multiply %i is %li"

• the variable : A

• the variable : B

• the expression : (long)A*B

The 1st specifier (%i) indicates that the value of A will be printed as an integer
==>1234
The 2nd specifier (%i) indicates that the value of B will be printed as an integer ==>
567
The 3rd specifier (%li) indicates that the value of (long)A*B will be printed as a long
integer ==> 699678

Example 5.2 The following instructions:

char B = ’A ’ ;
p r i n t f ( " The c h a r a c t e r %c has the code %i ! \ n " , B , B ) ;

will display on the screen: The character A has the code 65!

The value of B is therefore displayed in two different formats:

• %c as character: A

• %i as an integer: 65
48 5.1. Formatted data writing

SYMBOL TYPE PRINTING AS


%d ou %i int integer
%u int integer (unsigned)
%o int integer expressed in octal
%x int integer expressed in hexadecimal
%c int character
%f double rational in decimal notation
%e double rational in scientific notation
%s char* string of characters

Table 5.1: Format specifiers for printf

1. Arguments of type long Specifiers %d, %i, %u, %o, %x x can only represent values of
type int or unsigned int. A value that is too large to be encoded in two bytes is cut off
without warning if we use %d.
To be able to correctly process the arguments of the type long, it is necessary to use the
specifiers %ld, %li, %lu, %lo, %lx.
To be able to correctly process the arguments of the type long long, it is necessary to
use the specifiers %lld, %lli, %llu, %llo, %llx.

Example 5.3 long long N = 15000000000;


p r i n t f ("% l l d , %l l x " , N, N ) ; ==> 15000000000 , 37e11d600
p r i n t f ("%x " , N ) ; ==> 7e11d600
p r i n t f ("%d " , N ) ; ==> 2115098112

2. Rational arguments Specifiers %f and %e can be used to represent float or double


arguments. The mantissa of numbers represented by %e contains exactly one (non-
zero) digit in front of the decimal point. This representation is called the scientific
notation of the rationals. To be able to correctly process the arguments of the long
double type, the specifiers %Lf and %Le must be used.

Example 5.4 f l o a t N = 1 2 . 1 2 3 4 ;
double M = 12.123456789;
long double P = 1 5 . 5 ;

p r i n t f ("% f " , N ) ; ==> 12.123400


p r i n t f ("% f " , M) ; ==> 12.123457
p r i n t f ("% e " , N ) ; ==> 1.212340 e+01
p r i n t f ("% e " , M) ; ==> 1.212346 e+01
p r i n t f ("%Le " , P ) ; ==> 1.550000 e+01

3. Minimum width for integers For integers, we can specify the minimum width of the
value to display. In the field thus reserved, the numbers are justified on the right.
Chapter 5. READ AND WRITE DATA 49

Example 5.5 ( _ <=> p o s i t i o n l i b r e )


p r i n t f ("%4d " , 1 2 3 ) ; ==> _123
p r i n t f ("%4d " , 1 2 3 4 ) ; ==> 1234
p r i n t f ("%4d " , 1 2 3 4 5 ) ; ==> 12345
p r i n t f ("%4u " , 0 ) ; ==> ___0
p r i n t f ("%4X " , 1 2 3 ) ; ==> __7B
p r i n t f ("%4x " , 1 2 3 ) ; ==> __7b

4. Minimum width and precision for rationals For rationals, we can specify the min-
imum width of the value to be displayed and the precision of the number to be dis-
played. The default precision is six decimal places. Decimal places are rounded to the
nearest value.

Example 5.6 p r i n t f ("% f " , 1 0 0 . 1 2 3 ) ; ==> 100.123000


p r i n t f ("%12 f " , 1 0 0 . 1 2 3 ) ; ==> __100 .123000
p r i n t f ( " % . 2 f " , 1 0 0 . 1 2 3 ) ; ==>100.12
p r i n t f ("%5.0 f " , 1 0 0 . 1 2 3 ) ; ==> __100
p r i n t f ("%10.3 f " , 1 0 0 . 1 2 3 ) ; ==> ___100 . 1 2 3
p r i n t f ( " % . 4 f " , 1 . 2 3 4 5 6 ) ; ==> 1.2346
50 5.2. Formatted data reading

Exercise 5.1

# i n c l u d e < s t d i o . h>
main ( )
{
i n t N=10 , P=5 , Q=10 , R ;
char C= ’S ’ ;

N = 5; P = 2;
Q = N++ > P | | P++ != 3 ;
p r i n t f ( " C : N=%d P=%d Q=%d\n " , N, P , Q ) ;

N = 5; P = 2;
Q = N++ < P | | P++ != 3 ;
p r i n t f ( "D : N=%d P=%d Q=%d\n " , N, P , Q ) ;

N = 5; P = 2;
Q = ++N == 3 && ++P == 3 ;
p r i n t f ( " E : N=%d P=%d Q=%d\n " , N, P , Q ) ;

N=5; P=2;
Q = ++N == 6 && ++P == 3 ;
p r i n t f ( " F : N=%d P=%d Q=%d\n " , N, P , Q ) ;

N=C ;
printf ( "G : %c %c \n " , C, N ) ;
printf ( "H : %d %d\n " , C, N ) ;
printf ( " I : %x %x \n " , C, N ) ;
return 0;
}

• Without using the computer, find and note the results of the above program.

• Check your results using the computer.

5.2 Formatted data reading


The function scanf is the symmetrical function to printf; it offers us almost the same conver-
sions as printf, but in reverse.

s c a n f (" < format >" , <Var1Adr>,<Var2Adr > , . . . )


Chapter 5. READ AND WRITE DATA 51

• "<format>" : format for reading data

• <AdrVar1>,... : addresses of the variables to which the data will be assigned

• The scanf function receives its data from the stdin standard input file (by default the
keyboard).

• The format string determines how the received data should be interpreted.

• The correctly received data are memorized successively at the addresses indicated by
<Var1Adr>, ....

• The address of a variable is indicated by the name of the variable preceded by the &
sign.

Example 5.7 The following instructions:

i n t DAY, MONTH, YEAR


s c a n f ("% i %i %i " , &DAY, &MONTH, &YEAR ) ;

reads three relative integers, separated by spaces, tabs, or lines. Values are assigned to
the three variables DAY, MONTH, and YEAR, respectively.

scanf returns as result the number of correctly received data (type int).

SYMBOL Reading of TYPE


%d ou %i integer int*
%u integer (unsigned) int*
%o integer expressed in octal int*
%b integer expressed in hexadecimal int*
%c character char*
%s string of characters char*
%f ou %e rational in decimal or exponential notation (scientific) float*

Table 5.2: Format specifiers for scanf

The symbol * indicates that the argument is not a variable, but the address of a variable
of this type

1. The long type If we want to read long data, we have to use specifiers %ld, %li, %lu,
%lo, %lx. (Otherwise, the number is simply cut to the size of int).

2. The double type If we want to read a datum of the double type, we must use the
specifiers %le or %lf.

3. The long double type If we want to read long double data, we have to use the specifiers
%Le or %Lf.
52 5.2. Formatted data reading

4. Indication of the maximum width For all specifiers, we can specify the maximum
width of the field to be evaluated for a given datum. Numbers that pass beyond the
defined field are assigned to the next variable that will be read!

Example 5.8 Here are the instructions:


i n t A, B ;
s c a n f ("%4d %2d " , &A, &B ) ;
If we enter the number 1234567, we will get the following assignments: A = 1234
and B = 56. The number 7 will be kept for the next reading instruction

5. Signs of spacing When entering data, a sequence of spacing characters (spaces, tabs,
line feeds) is evaluated as a single space. In the format string, the symbols \t, \n, \r
have the same effect as a single space.

Example 5.9 For the instructions below


i n t DAY, MONTH, YEAR ;
s c a n f ("% i %i %i " , &DAY, &MONTH, &YEAR ) ;
the following entries are correct and equivalent:
12 4 1980
or
12 004 1980
or
12
4
1980

6. ’Special’ formats If the format string also contains other characters than space signs,
then these symbols must be entered exactly in the order shown.

Example 5.10 The following instructions


i n t DAY, MONTH, YEAR ;
s c a n f ("% i /% i /% i " , &DAY, &MONTH, &YEAR ) ;
accept entries: 12/4/1980 and 12/04/01980, but reject the entries: 12 4 1980
and 12 /4 /1980

7. Number of read values When evaluating the data, scanf will stop if the format string
has been worked to the end or if any data does not match the specified format. scanf
returns the number of correctly received and affected arguments as a result.

Example 5.11 The following instructions


i n t DAY, MONTH, YEAR, RECEIVED ;
RECEIVED = s c a n f ("% i %i %i " , &DAY, &MONTH, &YEAR ) ;
reacts in the following way (- indefinite value):
Chapter 5. READ AND WRITE DATA 53

INPUT: RECEIVED DAY MONTH YEAR


12 4 1980 ==> 3 12 4 1980
12/4/1980 ==> 1 12 - -
12.4 1980 ==> 1 12 - -
12 4 19.80 ==> 3 12 4 19

Exercise 5.2 Write a program that reads from the keyboard a date and writes the data
and the number of correctly received data on the screen.
Enter the date (DAY MONTH YEAR ) : 14 2 2020

RECEIVED DATA : 3
Day : 14
Month : 2
Year : 2020

• Test the program’s reactions to your entries. Try to enter numbers of different
formats and different sizes.

• Change the format part of the program to separate the different data by the sym-
bol ’-’.

5.3 Writing a character


The command

putchar ( ’ a ’ ) ;

transfers the character a to the standard stdout output file. The arguments of the putchar
function are either characters (that is, integers between 0 and 255).

Type of argument The putchar arguments are by definition of the type int and all the
values processed by putchar (even those of the char type) are first converted to int.

Example 5.12 char A = 225;


char B = ’ \ a ’ ;
int C = ’\ a ’ ;
putchar ( ’ x ’ ) ; /* d i s p l a y the l e t t e r x */
putchar ( ’ ? ’ ) ; /* d i s p l a y the symbol ? */
putchar ( ’ \ n ’ ) ; /* r e t u r n t o the l i n e */
putchar ( 6 5 ) ; /* d i s p l a y the symbol with */
/* the code 65 ( ASCII : ’A ’ ) */
putchar (A ) ; /* d i s p l a y the l e t t e r with */
/* the code 225 */
putchar ( B ) ; /* beep sound */
54 5.4. Reading a character

putchar (C ) ; /* beep sound */

5.4 Reading a character


A function more often used than putchar is the getchar function, which reads the next char-
acter of the stdin standard input file.

Result type The values returned by getchar are characters (0 - 255). The result type of
getchar is int. In general, getchar is used in an assignment:

int C;
C = getchar ( ) ;

getchar reads the data from the stdin buffer and provides the data only after confirmation
with ’Enter’. The <conio.h> library contains a function of the getch name that immediately
provides the next character entered on the keyboard.

The getch function is not compatible with ANSI-C and it can only be used under MS-DOS.

Exercise 5.3 Write a program that reads a character on the keyboard and displays the
character and its numeric code:

• using getchar and printf,

• using getch and printf.


Chapter 5. READ AND WRITE DATA 55

Computer Exercises

Exercise 5.1 Write a program that swaps and displays the values of three integer
variables A, B, C entered on the keyboard:
A ==> B , B ==> C , C ==> A

Exercise 5.2 Write a program that displays the quotient and the remainder of the
integer division of two integers entered on the keyboard as well as the rational quotient
of those numbers.

Exercise 5.3 Write a program that displays the resistance equivalent to three resistors
R1, R2, R3 (double type),

• if the resistors are connected in series: Rser = R1 + R2 + R3


R1∗R2∗R3
• if the resistors are connected in parallel: Rpar = R1∗R2+R1∗R3+R2∗R3

Exercise 5.4 Write a program that calculates and displays the area of a triangle whose
lengths must be entered on all three sides. Use the formula: S 2 = P ∗(P −A)∗(P −B)∗(P −
C) where A, B, C are the lengths of the three sides (type int) and P the half-perimeter
of the triangle.

Exercise 5.5 Write a program that calculates the sum of four numbers of type int
entered on the keyboard,

• using 5 variables (saving of the entered values)

• using 2 variables (loss of the entered values)

Exercise 5.6

• Write a program that calculates the inclusive price (double type) of an item from
the net price (type int) and the VAT percentage (type int) to be added. Use the
following formula, paying attention to priorities and automatic type conversions:
P T T C = P N ET + P N ET ∗ T100
VA

• Write a program that calculates the net price of an item (double type) from the in-
clusiveprice (double type) and the VAT percentage (type int) that has been added.
(Deduct the formula from the calculation given above)

Exercise 5.7 Write a program that calculates and displays the distance DIST (double
type) between two points A and B whose coordinates (XA, YA) and (XB, YB) are entered
in as integers.
56 5.4. Reading a character

Exercise 5.8 Write a program that declares two integer variables x and y. The user
must enter their values and then exchange their values (swap x and y) X takes the value
of Y, and Y takes the value of X.

Exercise 5.9 Write a program that converts the temperature from Fahrenheit to Cel-
sius.
5
C = (F − 32)
9

Exercise 5.10 Write a program that finds the square of the distance between two
points.

Additional Exercises

Exercise 5.11 Write a program that rounds a real number entered on the keyboard to
two digits after the decimal point.

Exercise 5.12 Write a program that reads a real value and displays its opposite.

Exercise 5.13 Write a program that reads and displays your first name and date of
birth on two different lines.

Exercise 5.14 Write a program that declares two integer variables. The user must
enter their values. The program then calculates their sum, their multiplication, and
displays the results.

Exercise 5.15 Write a program that reads two integer values x and y and displays the
absolute value of (x-y).
Execution example:
Enter x: -5
Enter y: 4
The absolute value obtained = 9

Exercise 5.16 During a promotion operation, a hardware component store applies a


10% discount on all components. Write a program that reads the price of a component
on the keyboard and displays the calculated price taking into account the discount.
6. Alternative structure

6.1 Block of instructions 57

6.2 if - else 57

6.3 if without else 59

6.4 if - else if - ... - else 60

6.5 Break et Continue 62

6.6 switch 64

6.7 Conditional operators 66

The control structures define the sequence in which the instructions are performed. In this
chapter, we will see how the known selection instructions work in C and we will get to know
a special pair of operators that allows us to choose between two values inside an expression.
Let us already note that the most important feature of control instructions in C is that the
’conditions’ in C can be any expressions that provide a numerical result. The value zero
corresponds to the false logical value and any value other than zero is considered true.

6.1 Block of instructions


A block of instructions is enclosed in braces containing 0 or more instructions (terminated
by ;)
Example 6.1

{}4
{ i=1; } 4
{;}4
{ i=5; k=3 } 8

6.2 if - else
The alternative structure in C

i f ( <e x p r e s s i o n > )
<block o f i n s t r u c t i o n s 1>
else
<block o f i n s t r u c t i o n s 2>

57
58 6.2. if - else

• If the <expression> provides a value other than zero, then <block of instructions 1> is
executed

• If the <expression> provides the value zero, then < block of instructions 2 > is exe-
cuted

The <expression> part can designate:

• a variable of a numeric type,

• an expression providing a numerical result.

The < block of instructions > part can refer to:

• a block of instructions enclosed in braces,

• a single statement terminated by a semicolon.

Example 6.2

if (a > b)
max = a ;
else
max = b ;

Example 6.3

DIFF = A − B ;
i f ( DIFF )
p r i n t f ( "A i s not equal t o B\n " ) ;
else
p r i n t f ( "A i s equal t o B\n " ) ;

Example 6.4

i f (A−B ) p r i n t f ( "A i s not equal t o B\n " ) ;


e l s e p r i n t f ( "A i s equal t o B\n " ) ;

Example 6.5
Chapter 6. Alternative structure 59

i f (A > B)
{
AUX = A;
A = C;
C = AUX;
}
else
{
AUX = B;
B = C;
C = AUX;
}

6.3 if without else


The else part is optional. We can use if as follows:

i f ( <e x p r e s s i o n > )
<block o f i n s t r u c t i o n s >

Since the else part is optional, expressions containing multiple if and if - else structures can lead to confu-
sion.

Example 6.6 The following expression can be interpreted in two ways:

i f (N>0)
i f (A>B )
MAX=A ;
else
MAX=B ;
i f (N>0)
i f (A>B )
MAX=A ;
else
MAX=B ;

For N=0, A=1 and B=2,

• in the first interpretation, MAX remains unchanged,

• in the second interpretation, MAX would obtain the value of B.


60 6.4. if - else if - ... - else

Without additional rules, the result of this expression would therefore be unpredictable.

Convention In C an else part is always linked to the last if which has no else part.
In our example, C would use the first interpretation.

Solution To avoid confusion and to force some interpretation of an expression, it is recom-


mended to use braces { } .

Example 6.7 To force the second interpretation of the above expression, we can write:

i f (N>0)
{
i f (A>B )
MAX=A ;
}
else
MAX=B ;

Exercise 6.1 Consider the following sequence of instructions:

i f (A>B ) p r i n t f ( " f i r s t c h o i c e \n " ) ; e l s e


i f (A>10) p r i n t f ( " second c h o i c e \n " ) ;
i f ( B<10) p r i n t f ( " t h i r d c h o i c e \n " ) ;
e l s e p r i n t f ( " f o u r t h c h o i c e \n " ) ;

1. Copy the instruction sequence using tabs to mark the if - else blocks belonging
together.

2. Determine the program responses for each of the following number pairs and
verify using the computer.

• A=10 and B=5


• A=5 and B=5
• A=5 and B=10
• A=10 and B=10
• A=20 and B=10
• A=20 and B=20

6.4 if - else if - ... - else


By combining multiple if - else structures into an expression we get a structure that is very
common to make decisions between several alternatives:
Chapter 6. Alternative structure 61

i f ( <expr1> )
<bloc1 >
e l s e i f (< expr2 >)
<bloc2 >
e l s e i f (< expr3 >)
<bloc3 >
e l s e i f (<exprN >)
<blocN>
e l s e <blocN+1>

Expressions <expr1> ... <exprN> are evaluated from top to bottom until one of them is
different from zero. The instruction block linked to it is then executed and the processing of
the command is completed.

Example 6.8

# i n c l u d e < s t d i o . h>
i n t main ( )
{
i n t A, B ;
p r i n t f ( " Enter 2 i n t e g e r s : " ) ;
s c a n f ("% i %i " , &A, &B ) ;
i f (A > B )
p r i n t f ("% i i s g r e a t e r than %i \n " , A, B ) ;
e l s e i f (A < B )
p r i n t f ("% i i s s m a l l e r than %i \n " , A, B ) ;
else
p r i n t f ("% i i s equal t o %i \n " , A, B ) ;
return 0;
}

The last part else deals with the case where none of the conditions has been fulfilled. It
is optional, but it can be used very comfortably to detect errors.

Example 6.9
62 6.5. Break et Continue

...
p r i n t f ( " Continue ( Y ) e s / (N) o ? " ) ;
g e t c h a r (C ) ;
i f (C==’Y ’ )
{
...
}
e l s e i f (C==’N’ )
p r i n t f ( " Bye Bye . . . \ n " ) ;
else
p r i n t f ( " \ aInput E r r o r ! \ n " ) ;
...

Exercise 6.2 Consider the following sequence of instructions:

i f (A>B )
i f (A>10)
p r i n t f ( " f i r s t c h o i c e \n " ) ; e l s e i f ( B<10)
p r i n t f ( " second c h o i c e \n " ) ; e l s e
i f (A==B ) p r i n t f ( " t h i r d c h o i c e \n " ) ;
e l s e p r i n t f ( " f o u r t h c h o i c e \n " ) ;

1. Rewrite the sequence of instructions using tabulators to mark the if - else blocks
belonging together.

2. For which values of A and B do we obtain the results: first choice, second choice,
... on the screen?

3. For which values of A and B do we not get an answer on the screen?

4. Save your answers and choose values for A and B yourself to check them using
the computer.

6.5 Break et Continue

The break statement is used to terminate loops or to exit from a switch. It can be used within
a for, while, do -while, or switch statement.

Example 6.10 For the following code:


Chapter 6. Alternative structure 63

int i , j ;
f o r ( i =1; i <7; i = i +1)
{
f o r ( j = i +1; j <5; j = j +1)
{
i f ( i % j ==0 ) break ;
p r i n t f ("%d " , j ) ;
}
}

2 3 4 3 4 4 will be displayed on the screen.

The continue statement is used to bypass the remainder of the current pass through a
loop. The loop does not terminate when a continue statement is encountered. Rather, the
remaining loop statements are skipped and the computation proceeds directly to the next
pass through the loop. (Note the distinction between continue and break.) The continue
statement can be included within a while, a do - while or a for statement. It is written
simply as

continue ;

without any embedded statements or expressions.

Example 6.11 For the following code:

int i ;
f o r ( i =1; i <7; i = i +1)
{
i f ( i % 2==0 ) c o n t i n u e ;
p r i n t f ("%d " , i ) ;
}

1 3 5 will be displayed on the screen.


64 6.6. switch

6.6 switch
The switch statement causes a particular group of statements to be chosen from several
available groups.
The selection is based upon the current value of an expression which is included within
the switch statement.

s w i t c h ( <expr> )
{
c a s e c o n s t a n t _ 1 : [< bloc1 >]
c a s e c o n s t a n t _ 2 : [< bloc2 >]
...
c a s e c o n s t a n t _ n : [<blocN >]
[ d e f a u l t : <blocN+1>]
}

<expr> may also be of type char, since individual characters have equivalent integer
values.

Cases should be integers constants (including characters) but not of rational types.
Chapter 6. Alternative structure 65

Example 6.12

# i n c l u d e < s t d i o . h>
i n t main ( )
{
int n;
p r i n t f ( " Enter an i n t e g e r : " ) ;
s c a n f ("%d " , &n ) ;

switch ( n )
{
c a s e 0 : p r i n t f ( " Null \n " ) ;
break ;
c a s e 1 : p r i n t f ( " One\n " ) ;
break ;
c a s e 2 : p r i n t f ( " Two\n " ) ;
c a s e 3 : p r i n t f ( " Three \n " ) ;
d e f a u l t : p r i n t f ( " Big \n " ) ;
}
p r i n t f ( " Bye " ) ;
return 0;
}

For n=0, the code displays Null Bye


For n=1, the code displays One Bye
For n=2, the code displays Two Three Big Bye
For n=3, the code displays Three Big Bye
For n=5, the code displays Big Bye
66 6.7. Conditional operators

Exercise 6.3 Give the output for each of the following inputs: 1, 4, 25.

# i n c l u d e < s t d i o . h>
i n t main ( )
{
int n;
p r i n t f ( " Enter an i n t e g e r : " ) ;
s c a n f ("%d " , &n ) ;

switch ( n )
{
c a s e 0 : p r i n t f ( " Null \n " ) ;
break ;
case 1:
c a s e 2 : p r i n t f ( " Small \n " ) ;
break ;
case 3:
case 4:
c a s e 5 : p r i n t f ( " Average \n " ) ;
break ;
d e f a u l t : p r i n t f ( " Big \n " ) ;
}
return 0;
}

6.7 Conditional operators

The C language has a somewhat exotic pair of operators that can be used as an alternative to
if - else and that has the advantage of being integrated into an expression:

<expr1> ? <expr2> : <expr3>

• If <expr1> provides a value other than zero, then the value of <expr2> is provided as
a result

• If <expr1> provides the value zero, then the value of <expr3> is provided as a result

Example 6.13 The following instructions


Chapter 6. Alternative structure 67

i f (A>B )
MAX=A ;
else
MAX=B ;

can be replaced by:

MAX = (A > B ) ? A : B ;

Employed in a rash manner, conditional operators can affect the readability of a program,
but if used with care, they provide very elegant solutions:

Example 6.14

p r i n t f ( " You have %i book%c \n " , N, (N == 1 ) ? ’ ’ : ’ s ’ ) ;

Type conversion rules also apply to conditional operators? : Thus, for an integer N of the type int and a
rational F of the float type, the expression

(N>0) ? N : F

will always provide a float result, no matter if N is larger or smaller than zero!
68 6.7. Conditional operators

Computer Exercises

Exercise 6.1 Write a program that reads an integer value x and displays whether x is
an even or odd number.

Exercise 6.2 Write a program that reads three integer values (A, B, and C) from the
keyboard and displays the larger of the three values, using:

1. if - else and a MAX help variable

2. if - else if - ... - else without help variable

3. conditional operators and a MAX help variable

4. conditional operators without any help variable

Exercise 6.3 Write a program that reads three integer values (A, B and C) on the
keyboard. Sort the values A, B and C by successive exchanges so as to obtain: val(A) ≤
val(B) ≤ val(C)
Affichez les trois valeurs.

Exercise 6.4 Write a program that reads two integer values (A and B) from the key-
board and displays the product sign of A and B without performing the multiplication.

Exercise 6.5 Write a program that reads two integer values (A and B) from the key-
board and displays the sign of the sum of A and B without performing the addition.
Use the fabs function from the <math.h> library.

Exercise 6.6 Write a program that calculates the real solutions of a second degree
equation ax2 + bx + c = 0 by discussing the formula:

−b ± b2 − 4ac
x1,2 =
2a
Use a help variable D for the discriminant value b2 − 4ac and decide using D if the
equation has one, two or no real solution. Use variables of type int for A, B and C.
Consider also the cases where the user enters null values for A; for A and B; for A, B,
and C. View the results and the necessary messages on the screen.

Exercise 6.7 Write a program that reads a real number X and displays its category:

• Category A if (0 < = X < 37)

• Category B otherwise
Chapter 6. Alternative structure 69

Exercise 6.8 A four-digit number ABCD is called Lucky if A + B = C + D.


Write a program that asks the user to enter a four-digit number n and prints whether
n is a Lucky number or not.
Example:

• The number 3719 is a Lucky number since 3 + 7 = 1 + 9

• The number 3521 is not a Lucky number since (3 + 5) != (2 + 1).

Additional Exercises

Exercise 6.9 Write a program that reads two integers X and Y , and does the following:

• X takes the value of Y if (X ≤ Y or Y is a divisor of X)

• Y takes the value of X if (X ≥ 30 and Y is a multiple of X)

Exercise 6.10 Write a C program that reads three integers a,b and c, and displays on
the screen the result of the expression ab
c if c is not null. Your program displays the
message “Wrong value of c” if c null.
Execution example:
Enter three numbers A, B and C: 3 5 10
a∗b
c = 3 ∗ 5/10 = 1.5

Exercise 6.11 Write a program that reads six real values a, b, c, u, v, w and then
displays the solution of the following equations:
a∗X +b∗Y +c = 0
u∗X +v ∗Y +w = 0

Exercise 6.12 Write a program that reads two positive integer values X and Y. The
program must then calculate and display the result of the following expression :

(X 2 + 1)( X
Y − 3)
(X − Y )(Y 2 − X)
2

Exercise 6.13 Let the mathematical function f be defined by f (x) = (2x + 3)(3x2 + 2)

• Write a program C that calculates the image by f of a number entered on the


keyboard.

• An approximation of the derivative f’ of the function f is given at each point x,


f (x+h)−f (x)
for h small enough (close to 0), by : f 0 (x) ' h

Write a C program that calculates and displays an approximation of the derivative of


f at a point x entered at the keyboard. You can enter the parameter h on the keyboard.
70 6.7. Conditional operators

Exercise 6.14 Write a program that displays the digit of the tens of a number entered
on the keyboard. Same question for the hundreds.

Exam questions

Exercise 6.15 (Section I - Partiel 2018-2019) Write a program that asks a customer
to enter the number of consumed electricity units. The program then calculates
and prints the electricity bill without VAT, and then prints it with VAT knowing that:

• For the first 50 consumed units, the customer pays 0.50$ per unit,

• for the units consumed beyond 50, the customer pays 0.75$ per unit,

• the VAT is equal to 11%.

Running example:
7. Repetitive structure

7.1 while 71

7.2 do - while 73

7.3 for 74

7.4 Choice of the repetitive structure 77

In C, we have three structures that allow us to define conditional loops:


1. the structure : while
2. the structure : do - while
3. the structure : for
Theoretically, these structures are interchangeable, i.e. it would be possible to program all
kinds of conditional loops using only one of the three structures.

7.1 while

while ( <e x p r e s s i o n > )


<block o f i n s t r u c t i o n s >

• As long as the <expression> provides a value other than zero, the <block of instruc-
tions> is executed.
• If the <expression> provides the value zero, the execution continues with the instruc-
tion that follows the block of instructions.
• The < block of instructions > can be executed zero or more times.
The <expression> part can designate:
• a variable of a numeric type,
• an expression providing a numerical result.
The <block of instructions> part can refer to:
• a block of instructions enclosed in braces,
• a single statement terminated by a semicolon.

71
72 7.1. while

Example 7.1

/* d i s p l a y numbers from 0 t o 9 */
int I = 0;
while ( I <10)
{
p r i n t f ("% i \n " , I ) ;
I ++;
}

Example 7.2

int I ;
/* d i s p l a y numbers from 0 t o 9 */
I = 0;
while ( I <10)
p r i n t f ("% i \n " , I + + ) ;
/* d i s p l a y numbers from 1 t o 10 */
I = 0;
while ( I <10)
p r i n t f ("% i \n " , ++ I ) ;

Example 7.3

/* d i s p l a y numbers from 10 t o 1 */
i n t I =10;
while ( I )
p r i n t f ("% i \n " , I − −);

Sometimes we only want to wait for a certain event, without the need for data processing. In this case, the
<block of instructions> part may be empty (notation: ; or { } ). The following line ignores all the spaces
entered on the keyboard and can be used before reading the first significant character:

w h i l e ( g e t c h ()== ’ ’ )
;
Chapter 7. Repetitive structure 73

7.2 do - while
The do - while structure is similar to the while structure, with the following difference :

• while evaluates the condition before executing the statement block,

• do - while evaluates the condition after executing the statement block. Thus the in-
struction block is executed at least once.

do
<block o f i n s t r u c t i o n s >
while ( <e x p r e s s i o n > ) ;

The <block of instructions> is executed at least once and as long as the <expression>
provides a value other than zero.
In practice, the do - while structure is not so common as while; but in some cases, it
provides a more elegant solution. A typical do - while application is data entry that must
meet a certain condition.
Example 7.4

f l o a t N;
do
{
p r i n t f ( " Enter a number between 1 and 10 : " ) ;
s c a n f ("% f " , &N ) ;
}
while (N<1 | | N> 1 0 ) ;

Example 7.5

i n t n , div ;
p r i n t f ( " Enter the number t o be d i v i d e d : " ) ;
s c a n f ("% i " , &n ) ;
do
{
p r i n t f ( " Enter the d i v i s o r : " ) ;
s c a n f ("% i " , &div ) ;
} while ( ! div ) ;
p r i n t f ("% i / %i = %f \n " , n , div , ( f l o a t ) n / div ) ;
74 7.3. for

Example 7.6 The square root calculation program:

# i n c l u d e < s t d i o . h>
# i n c l u d e <math . h>
main ( )
{
f l o a t N;
do
{
p r i n t f ( " Enter a number (>= 0 ) : " ) ;
s c a n f ("% f " , &N ) ;
}
while (N < 0 ) ;
p r i n t f ( " The square r o o t o f %.2 f i s equal t o
%.2 f \n " , N, s q r t (N ) ) ;
return 0;
}

7.3 for
The structure for in C is more general and much more powerful.

f o r ( <expr1> ; <expr2> ; <expr3> )


<block o f i n s t r u c t i o n s >

is equivalent to :

<expr1 >;
while ( <expr2> )
{
<block o f i n s t r u c t i o n s >
<expr3 >;
}

• <expr1> is evaluated once before passing the loop. It is used to initialize the data of
the loop.

• <expr2> is evaluated before each pass of the loop. It is used to decide whether the loop
is repeated or not.

• <expr3> is evaluated at the end of each pass in the loop. It is used to reset the data in
the loop.
Chapter 7. Repetitive structure 75

Most often, for is used as a counting loop:

f o r ( < i n i t . > ; <c o n d i t i o n > ; <counter > )


<block o f i n s t r u c t i o n s >

Example 7.7

int I ;
f o r ( I =0 ; I <=20 ; I ++)
p r i n t f ( " The square o f %d i s %d \n " , I , I * I ) ;

Example 7.8 In practice, the parts <expr1> and <expr3> often contain several ini-
tializations or resets, separated by commas.

int n, tot ;
f o r ( t o t =0 , n=1 ; n<101 ; n++)
t o t +=n ;
p r i n t f ( " Sum o f numbers from 1 t o 100 i s equal t o %d\n " , t o t ) ;

Example 7.9 The following example presents us with 4 different variations to achieve
the same treatment and shows us the power of the structure for. The following expres-
sions read a character on the keyboard and display its numeric code in binary notation:
76 7.3. for

/* a */
/* Using while */
i n t C, I ;
C=g e t c h a r ( ) ;
I =128;
while ( I >=1)
{
p r i n t f ("% i " , C/ I ) ;
C%=I ;
I /=2;
}

/* b */
/* Using f o r ( s u i t a b l e f o r b e g i n n e r s ) */
i n t C, I ;
C=g e t c h a r ( ) ;
f o r ( I =128 ; I >=1 ; I /=2)
{
p r i n t f ("% i " , C/ I ) ;
C%=I ;
}
/* c */
/* Using f o r ( compact code ) ( s u i t a b l e f o r e x p e r t s ) */
i n t C, I ;
C=g e t c h a r ( ) ;
f o r ( I =128 ; I >=1 ; C%=I , I /=2)
p r i n t f ("% i " , C/ I ) ;
/* d */
/* Using f o r − not recommended */
/* o v e r l o a d and misuse o f the s t r u c t u r e */
i n t C, I ;
f o r (C=g e t c h a r ( ) , I =128; I >=1 ; p r i n t f ("% i " ,C/ I ) ,C%=i , i /=2)
;
Chapter 7. Repetitive structure 77

7.4 Choice of the repetitive structure


In this chapter, we saw three different ways to program loops (while, do - while, for). Use the
structure that best reflects the idea of the program you want to carry out, while respecting
the following guidelines:

• If the statement block should not be executed if the condition is false, then use while
or for.

• If the statement block must be executed at least once, then use do - while.

• If the number of executions in the instruction block depends on one or more variables
that are changed at the end of each repetition, then use for.

• If the instruction block must be executed as long as an external condition is true (eg as
long as there is data in the input file), then use while.

The choice between for and while is often only a matter of preference or habits:

• for allows us to advantageously gather the instructions that influence the number of
repetitions at the beginning of the structure.

• while has the advantage of more exactly matching the structures of other programming
languages (while, as long as).

• for has the disadvantage of favoring the programming of structures overloaded and
subsequently illegible.

• while has the disadvantage of sometimes leading to long structures, in which one must
search for the instructions that influence the condition of repetition.
78 7.4. Choice of the repetitive structure

Computer Exercises

Exercise 7.1 Write a program that reads N whole numbers on the keyboard and dis-
plays their sum, product, and average. Choose an appropriate type for the values to
display. The number N is to enter on the keyboard. Solve this problem,

1. using while,

2. using do - while,

3. using for.

4. Which of the three variants is the most natural for this problem?

5. Complete the ’best’ of the three versions: Repeat the introduction of the number
N until N has a value between 1 and 15.
What repetitive structure do you use? Why?

Exercise 7.2 Calculate by successive subtractions the integer quotient and the remain-
der of the integer division of two integers entered on the keyboard.

Exercise 7.3 Calculate the factorial N! = 123...(N-1)N of a natural integer N respecting


that 0!=1.

1. Use while,

2. Use for.

Exercise 7.4 Calculate by successive multiplications X N of two natural numbers X


and N entered on the keyboard.

Exercise 7.5 Calculate the sum of the first N terms of the harmonic series : 1 + 12 + 13 +
... + N1

Exercise 7.6 Calculate the sum, the product and the average of a sequence of non-
zero digits entered on the keyboard, knowing that the sequence is ended by zero. Just
count the numbers (0, 1 ... 9) when entering data and beep if the data comes out of this
range.

Exercise 7.7 Calculate the countdown count of a positive number entered on the
keyboard assuming that the standard input contains a sequence of non-zero, zero-
ended digits (check if they are really digits).
Example:
Input: 1 2 3 4 0
Output: 4321
Chapter 7. Repetitive structure 79

Exercise 7.8 Calculate the number read back from a positive number entered using
the keyboard assuming that the standard input file contains the number to be inverted.
Example:
Input: 1234
Output: 4321

Exercise 7.9 Calculate for a given value X of the type float the numerical value of a
polynomial of degree n: P (X) = An X n + An−1 X n−1 + ... + A1 X + A0
The values of n, coefficients An , ..., A0 and X will be entered on the keyboard.
Use the Horner schema that avoids exponentiation operations when calculating:

Exercise 7.10 Calculate the GCD between two natural numbers using the EUCLIDE
algorithm.

Exercise 7.11 Calculate the N-th term UN of the FIBONACCI sequence that is given
by the recurrence relation: U1 = 1, U2 = 1, UN = UN −1 + UN −2 (for N>2)
Determine the rank N and the value UN of the maximum term that can be calculated
if we use for UN :

• the int type

• the long type

• the double type

• the long double type

Exercise 7.12 Display an isosceles triangle formed of stars of N lines (N is provided


on the keyboard):
Number o f l i n e s : 8

*
***
*****
*******
*********
***********
*************
***************
80 7.4. Choice of the repetitive structure

Exercise 7.13 Displays the product table for N varying from 1 to 10:
X*Y I 0 1 2 3 4 5 6 7 8 9 10
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
0 I 0 0 0 0 0 0 0 0 0 0 0
1 I 0 1 2 3 4 5 6 7 8 9 10
2 I 0 2 4 6 8 10 12 14 16 18 20
3 I 0 3 6 9 12 15 18 21 24 27 30
4 I 0 4 8 12 16 20 24 28 32 36 40
5 I 0 5 10 15 20 25 30 35 40 45 50
6 I 0 6 12 18 24 30 36 42 48 54 60
7 I 0 7 14 21 28 35 42 49 56 63 70
8 I 0 8 16 24 32 40 48 56 64 72 80
9 I 0 9 18 27 36 45 54 63 72 81 90
10 I 0 10 20 30 40 50 60 70 80 90 100

Exercise 7.14 Write a program which reads a sequence of real values filled by the user
and stops by displaying "FINISHED" when the sum of these values exceeds 100.

Exercise 7.15 Write a program which reads a positive integer value N and indicates
if N is a perfect number or not (N is a perfect number if N = the sum of its divisors
without the number itself).

Exercise 7.16 Write a program which reads a positive integer value N, calculates and
shows the result of the expression: 1 + 4 + 7 + 10 +... + N

Exercise 7.17 Write a program which reads a positive integer value n, calculates and
shows the result of the expression:
n
X i +3
i2 − 5
i=1

Exercise 7.18 Write a program which indicates if a positive number N, filled by the
user, is prime or not (N is a prime number if its only divisors are 1 and N).

Exercise 7.19 Write a program which reads a sequence of positive real numbers. The
program stops when the user fills a negative value and show the maximum of these
numbers.

Exercise 7.20 Write a C program that asks the user to enter a positive integer N, and a
real value R representing the radius of a circle C of center O(0,0). The program should
then prompt the user to enter a sequence of points’ coordinates (x and y) until the
number of points inside C is equal to N. The program should display the coordinates
of the farthest point from the center O(0,0) (among the entered points).
Chapter 7. Repetitive structure 81

Note that:

1. The distance
p between a point M(x,y) and the point O(0,0) is calculated using the
formula x2 + y 2

2. • sqrt(t) of the library math.h gives the value of t

Exercise 7.21 Write a program that reads an integer x and then prints on the screen a
triangle of x lines of stars. If we consider x=7, the algorithm must display:
*
* *
* *
* *
* *
* *
*************

Exercise 7.22 Write a program that reads a positive integer N and displays:
1
22
333
4444
...
NNNN. . . .N

Exercise 7.23

1. Write a program that takes an integer n and displays the value of Un respecting:
U1 = 1 ;
Ui
Un = n−1
P
i=1 (i−1)! for n>0 ;

2. Write a program that asks the user to enter an integer a and then prints the series
elements from U1 to Ua .
82 7.4. Choice of the repetitive structure

Exercise 7.24 An integer number is divisible by 9 if the sum of its digits is divisible
by 9.

1. Write a program that reads a positive integer, finds the number of digits of this
integer and using the criteria above, discovers if it is divisible by 9 and then
prints out the results.
Example: if the user enters 57883
The program displays :
57883 has 5 digits.
The sum of digits is : 31
It is not divisible by 9

2. Write a program that uses the criteria above to display all the positive integers
between 100 and 1000 that are divisible by

Exercise 7.25 Write a program that reads an integer N, asks the user to enter N char-
acters, calculate the length of the longest ascending sequence of characters and the
position of its first character.
Example of execution:
Enter a positive integer: 11
Enter 11 characters:
AecDklnpacD
The longest sequence is of 5 characters, it begins at the position 4

Additional Exercises

Exercise 7.26 Write a program which calculates expression N N where N is an integer


value filled by the user.

Exercise 7.27 Write a program which reads a sequence of positive integer values and
shows their multiplication and their sum when the user fills a negative number.

Exercise 7.28 Write a program which reads a positive integer value and shows its
divisors

Exercise 7.29 Write a program which reads a positive integer value N, calculates and
shows the sum of the even numbers < = N.

Exercise 7.30 Write a program which reads a positive integer value N, calculates and
shows the sum of the odd numbers < = N.

Exercise 7.31 Write a program which reads a positive integer number n, calculates
and shows the following:
1 + 1/2 + 1/3 + 1/4 + ... + 1 / n if n is divisible by 7
Chapter 7. Repetitive structure 83

n + n / 2 + n / 3 + n / 4 + ... + n / (n-1) + 1 otherwise

Exercise 7.32 Write a program which reads 10 real numbers. The program must then
show the maximum and the minimum of these numbers.

Exercise 7.33 Write a program which reads 20 real numbers and shows their sum and
their multiplication.

Exercise 7.34 Write a program which reads two positive integer values and shows
their GCD (Greatest Common Divisor) and their LCM (Least Common Multiple).

Exercise 7.35 Write a program that asks the user to enter an integer making sure
it is a positive number (a negative integer should not be accepted), and checks if this
number is ABUNDANT. A number n is said to be abundant when the sum of its divisors
(including the number itself) is greater than its double (2n).
Example: 12 is abundant since (1 + 2 + 3 + 4 + 6 + 12 > 24)

Exam questions

Exercise 7.36 (Section I - Partiel 2018-2019) The 9th complement of a positive integer
A is a positive integer B obtained by subtracting each digit in A from 9.
Write a program that asks the user to enter a positive integer (a negative number
should be ignored and the user should be asked to enter a new integer) then calculates
and prints its 9th complement.

Exemple d’exécution:

Exercise 7.37 (Section I - Partiel 2018-2019) Write a program that asks the user to
enter positive integer values. The program terminates when the user enters a negative
value by displaying on the screen the average value and the second distinct maximum
of the list of the positive even integers entered by the user.
Exemple d’exécution:
84 7.4. Choice of the repetitive structure

Exercise 7.38 (Section I - Session 2 2018-2019) Write a program that reads a positive
integer n and then displays the nth term of the following series :
U0 = 1 V0 = 0
 
Un = Vn−1 + 1 Vn = 2 × Un−1
Running example:
8. Arrays

8.1 Uni-dimensional arrays 85

8.2 Two-dimensional arrays 89

Arrays are certainly the most popular structured variables. They are available in all pro-
gramming languages and are used to solve a multitude of problems. In a first approach, the
treatment of arrays in C does not differ from that of other programming languages.
Strings are declared in C as character arrays and allow the use of a number of notations and
special functions. The special features of character tables will be dealt with separately in the
next chapter.

8.1 Uni-dimensional arrays


Definitions A (uni-dimensional) array A is a structured variable formed of an integer N of
simple variables of the same type, which are called the components of the array. The number
of components N is then the dimension of the array.

In making the connection with mathematics, we still say that "A is a vector of dimension
N"

Example 8.1 The declaration:


i n t DAYS[ 1 2 ] = { 3 1 , 2 8 , 3 1 , 3 0 , 3 1 , 3 0 , 3 1 , 3 1 , 3 0 , 3 1 , 3 0 , 3 1 } ;
defines an array of type int of dimension 12. The 12 components are initialized by the
respective values 31, 28, 31, ..., 31.
The first component of the array can be accessed by DAYS [0], the second component
by DAYS [1],. . . , at the last component by DAYS [11].

Declaration

85
86 8.1. Uni-dimensional arrays

<SimpleType> <ArrayName> [<Dimension > ] ;

Array names are identifiers that must match the known restrictions.
Example 8.2

i n t A[ 2 5 ] ;
float B[100];
int C[ 1 0 ] ;
char D[ 3 0 ] ;

Storage In C, the name of an array is the representative of the address of the first element
of the array. The addresses of the other components are calculated (automatically) relative
to this address.
Example 8.3

s h o r t A[ 5 ] = { 1 2 0 0 , 2300 , 3400 , 4500 , 5 6 0 0 } ;

If an array consists of N components and if a component needs M bytes in memory,


then the array will occupy N * M bytes.

Example 8.4 Assuming that a variable of the long type occupies 4 bytes (ie, sizeof
(long) = 4), for the array T declared by:
long T [ 1 5 ] ;
C will reserve N * M = 15 * 4 = 60 bytes in memory.

Initialization When declaring an array, we can initialize the components of the table, by
indicating the list of the respective values between braces.
Example 8.5

i n t A[ 5 ] = { 1 0 , 20 , 30 , 40 , 5 0 } ;
f l o a t B [ 4 ] = { − 1 . 0 5 , 3 . 3 3 , 87e −5 , −12.3E4 } ;
i n t C[ 1 0 ] = { 1 , 0 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 } ;

Of course, you must ensure that the number of values in the list matches the size of the
array. If the list does not contain enough values for all components, the remaining compo-
nents are initialized with zero.
Chapter 8. Arrays 87

Automatic reservation If the dimension is not specified explicitly during initialization,


then the computer automatically reserves the necessary number of bytes.
Example 8.6

i n t A [ ] = { 1 0 , 20 , 30 , 40 , 5 0 } ;
==> r e s e r v a t i o n o f 5 * s i z e o f ( i n t ) b y t e s ( i n our c a s e : 20 b y t e s )
f l o a t B [ ] = { − 1 . 0 5 , 3 . 3 3 , 87e −5 , −12.3E4 } ;
==> r e s e r v a t i o n o f 4 * s i z e o f ( f l o a t ) b y t e s ( i n our c a s e : 32 b y t e s )
int C[ ] = {1 , 0 , 0 , 1 , 1 , 1 , 0 , 1 , 0 , 1 } ;
==> r e s e r v a t i o n o f 10 * s i z e o f ( i n t ) b y t e s ( i n our c a s e : 40 b y t e s )

Example 8.7

Access to components By declaring an array by:


int A[ 5 ] ;
we have defined an array A with five components, which can be accessed by:
A[ 0 ] , A[ 1 ] , ... , A[ 4 ]

Example 8.8

Example 8.9 MAX = (A[0] >A [ 1 ] ) ? A[ 0 ] : A[ 1 ] ;


A[ 4 ] *= 2 ;

Consider an array T of dimension N


• access to the first element of the array is done by T[0]
• access to the last element of the array is done by T[N-1]
88 8.1. Uni-dimensional arrays

Displaying the content of an array The for structure is particularly suitable for working
with arrays. Most applications can be implemented simply by modifying the standard ex-
amples of display and assignment.

i n t main ( )
{
int A[ 5 ] ;
i n t I ; /* c o u nt e r */
f o r ( I =0; I <5; I ++)
p r i n t f ("%d " , A[ I ] ) ;
return 0;
}

• Before you can display the components of an array, you obviously have to assign values to them.
• Remember that the second condition in the for structure is not a stop condition, but a repeat condition!
Thus the display command will be repeated as long as I is less than 5. The loop will therefore be
executed for the indices 0,1,2,3 and 4!
• The printf command must be informed of the exact type of data to be displayed. (Here: %d or %i for
values of type int)
• To be sure that the values are properly separated when displayed, you must include at least one space
in the format string. Other possibilities:
p r i n t f ("%d\ t " , A[ I ] ) ; / * t a b u l a t o r * /
p r i n t f ("%7d " , A[ I ] ) ; / * d i s p l a y format * /

Assignment with values from outside

i n t main ( )
{
int A[ 5 ] ;
i n t I ; /* c o u n t e r */
f o r ( I =0; I <5; I ++)
s c a n f ("%d " , &A[ I ] ) ;
return 0;
}

• As scanf needs the addresses of the various components of the array, the term A[I] must be preceded
by the address operator ’&’.
Chapter 8. Arrays 89

• The scanf command must be informed of the exact type of data to be read. (Here: %d or %i to read
values of type int)

Exercise 8.1 Write a program that reads the dimension N of an integer array T (max-
imum dimension: 50 components), fills the array with values entered on the keyboard
and displays the array.
Calculate and then display the sum of the elements of the array.

Exercise 8.2 Write a program that reads the dimension N of an integer array T (max-
imum dimension: 50 components), fills the array with values entered on the keyboard
and displays the array.
Then delete all occurrences of the value 0 in the array T and tamp the remaining ele-
ments. Display the resulting array.

Exercise 8.3 Write a program that reads the dimension N of an integer array T (max-
imum dimension: 50 components), fills the array with values entered on the keyboard
and displays the array.
Then store the elements of T in the reverse order without using an auxiliary array. Dis-
play the resulting array.
Hint: Swap the elements of the array using two indices that run through the array,
starting at the beginning and at the end of the array respectively and meeting in the
middle.

Exercise 8.4 Write a program that reads the dimension N of an integer array T (max-
imum dimension: 50 components), fills the array with values entered on the keyboard
and displays the array.
Then copy all strictly positive components into a second TPOS array and all strictly
negative values into a third TNEG array. Display TPOS and TNEG arrays.

8.2 Two-dimensional arrays

In C, a two-dimensional array A is to be interpreted as an array (uni-dimensional) of dimen-


sion R, each component of which is a (one-dimensional) array of dimension C.
We call R the number of rows in the array and C the number of columns in the array. R
and C are then the two dimensions of the array. A two-dimensional array therefore contains
R * C components.
90 8.2. Two-dimensional arrays

A two-dimensional array is said to be square, if R is equal to C.


Comparing with mathematics, we can say that "A is a vector of R vectors of dimension
C", or better: "A is a matrix of dimensions R and C".
Example 8.10 Consider a one-dimensional array GRADE to memorize the grades of
20 students in a class in a assignment:
i n t GRADE[ 2 0 ] = { 4 5 , 34 , . . . , 50 , 4 8 } ;

To memorize students’ grades in 10 assignments, we can collect several of these one-


dimensional tables in a two-dimensional GRADES array:
i n t GRADES[ 1 0 ] [ 2 0 ] = { { 4 5 , 34 , . . . , 50 , 4 8 } ,
{ 3 9 , 24 , . . . , 49 , 4 5 } ,
... ... ...
{ 4 0 , 40 , . . . , 54 , 4 4 } } ;

In one line we find the notes of all students in a homework assignment. In a column,
we find all the notes of a student.

Declaration

<SimpleType> <TableName> [<DimRow>] [<DimCol > ] ;

Example 8.11

i n t A[ 1 0 ] [ 1 0 ] ;
float B[2][20];
Chapter 8. Arrays 91

int C[ 3 ] [ 3 ] ;
char D[ 1 5 ] [ 4 0 ] ;

Storage As with one-dimensional arrays, the name of a array is the representative of the
address of the first array element (ie the address of the first row of the array). The compo-
nents of a two-dimensional array are stored line by line in memory.

Example 8.12

short A[ 3 ] [ 2 ] = { { 1 , 2 },
{ 1 0 , 20 } ,
{100 , 2 0 0 } } ;

An array of R and C dimensions, consisting of components each of which needs M


bytes, will occupy R * C * M bytes in memory.

Example 8.13 Assuming that a variable of type double occupies 8 bytes (i.e.
sizeof(double) = 8), for the array T declared by:
double T [ 1 0 ] [ 1 5 ] ;
C will reserve L * C * M = 10 * 15 * 8 = 1200 bytes in memory.

Initialization When declaring an array, we can initialize the components of the array, by
indicating the list of the respective values between braces. Inside the list, the components
of each row of the array are once again enclosed in braces. To improve the readability of the
programs, we can indicate the components in several lines.

Example 8.14

i n t A[ 3 ] [ 1 0 ] = { { 0 , 1 0 , 2 0 , 3 0 , 4 0 , 5 0 , 6 0 , 7 0 , 8 0 , 9 0 } ,
{10 ,11 ,12 ,13 ,14 ,15 ,16 ,17 ,18 ,19} ,
{ 1 ,12 ,23 ,34 ,45 ,56 ,67 ,78 ,89 ,90}};

float B[ 3 ] [ 2 ] = {{ −1.05 , −1.10 } ,


{86 e −5 , 87e−5 } ,
{ −12.5 E4 , −12.3E4 } } ;

During initialization, the values are assigned line by line from left to right. We do not
necessarily have to indicate all the values: Missing values will be initialized by zero. It is
however forbidden to indicate too many values for an array.
92 8.2. Two-dimensional arrays

Example 8.15

Automatic reservation If the number of rows R is not specified explicitly during initial-
ization, the computer automatically reserves the necessary number of bytes.

Example 8.16

i n t A[ ] [ 1 0 ] = { { 0 ,10 ,20 ,30 ,40 ,50 ,60 ,70 ,80 ,90} ,


{10 ,11 ,12 ,13 ,14 ,15 ,16 ,17 ,18 ,19} ,
{ 1 ,12 ,23 ,34 ,45 ,56 ,67 ,78 ,89 ,90}};
==> r e s e r v a t i o n o f 3*10*4 = 120 b y t e s

float B [ ] [ 2 ] = {{ −1.05 , −1.10 } ,


{86 e −5 , 87e−5 } ,
{ −12.5 E4 , −12.3E4 } } ;
==> r e s e r v a t i o n o f 3*2*6 = 36 o c t e t s

Example 8.17
Chapter 8. Arrays 93

Access to components Access to a two-dimensional array in C


<NomTableau>[<Ligne >][ < Colonne >]
The elements of an array of dimensions L and C are as follows:
/ \
| A[ 0 ] [ 0 ] A[ 0 ] [ 1 ] A[ 0 ] [ 2 ] . . . A [ 0 ] [ C−1] |
| A[ 1 ] [ 0 ] A[ 1 ] [ 1 ] A[ 1 ] [ 2 ] . . . A [ 1 ] [ C−1] |
| A[ 2 ] [ 0 ] A[ 2 ] [ 1 ] A[ 2 ] [ 2 ] . . . A [ 2 ] [ C−1] |
| . . . . . . . . . . . . . . . |
| A[ L − 1 ] [ 0 ] A[ L − 1 ] [ 1 ] A[ L − 1 ] [ 2 ] . . . A[ L − 1 ] [C−1] |
\ /

In C,
• the indices in the array vary from 0 to L-1, respectively from 0 to C-1.
• the component of the Nth row and Mth column is noted: A[N − 1][M − 1]

Displaying the content of an array When working with two-dimensional arrays, we will
use two indices (eg: I and J), and the for structure, often nested, to browse the rows and
columns of the arrays.

i n t main ( )
{
int A[ 5 ] [ 1 0 ] ;
int I , J ;
/* f o r each row . . . */
f o r ( I =0; I <5; I ++)
{
/* . . . c o n s i d e r each component */
f o r ( J =0; J <10; J ++)
p r i n t f ("%7d " , A[ I ] [ J ] ) ;
/* Return t o a new l i n e */
printf ("\n " ) ;
}
return 0;
94 8.2. Two-dimensional arrays

• Before you can display the components of an array, you must assign values to them.
• To obtain well aligned columns when displaying, it is practical to indicate the minimum width of the
display in the format string. To display matrices of type int, we can use the format string "%7d":
p r i n t f ("%7d " , A[ I ] [ J ] ) ;

Assignment with values from outside

i n t main ( )
{
int A[ 5 ] [ 1 0 ] ;
int I , J ;
/* f o r each row . . . */
f o r ( I =0; I <5; I ++)
/* . . . c o n s i d e r each component */
f o r ( J =0; J <10; J ++)
s c a n f ("%d " , &A[ I ] [ J ] ) ;
return 0;
}

Exercise 8.5 Write a program that reads the R and C dimensions of a two-dimensional
array T of type int (maximum dimensions: 50 rows and 50 columns). Fill in the array
with values entered on the keyboard and display the array and the sum of all its ele-
ments.

Exercise 8.6 Write a program that reads the R and C dimensions of a two-dimensional
array T of type int (maximum dimensions: 50 rows and 50 columns). Fill in the array
with values entered on the keyboard and display the array and the sum of each row
and column using only one auxiliary variable for the sum.

Exercise 8.7 Write a program that transfers a two-dimensional array M of dimensions


R and C (maximum dimensions: 10 rows and 10 columns) into a one-dimensional
array V of size R * C.
Example:  
a b c d 
e f g h ⇒ (a b c d e f g h i j k l)


i j k l
 
Chapter 8. Arrays 95

Computer Exercises
The following exercises are divided into two series:
1. One-dimensional arrays - Vectors
2. Two-dimensional arrays - Matrices
The following exercises are to be treated according to the same scheme:
• Variable declaration
• Reading the dimensions of the arrays
• Reading array data
• Treatments
• Displaying results
Choose the appropriate maximum dimensions for the arrays.

One-dimensional arrays - Vectors


Exercise 8.1 Scalar product of two vectors
Write a program that calculates the scalar product of two integer vectors U and V (of
the same dimension).
Exemple: (3 2 − 4) ∗ (2 − 3 5) = 3 ∗ 2 + 2 ∗ (−3) + (−4) ∗ 5 = −20

Exercise 8.2 Calculation of a polynomial of degree N


Calculate, for a given float value X, the numeric value of a polynomial of degree n:
P (X) = An X n + An−1 X n−1 + ... + A1 X + A0
The values of n and the coefficients An , ..., A0 and of X will be entered by keyboard and
stored in a float array A of dimension n + 1.

1. Use the pow() function for calculation.

2. Use the Horner scheme that avoids the exponentiation operations:

Exercise 8.3 Maximum and minimum values of an array


Write a program that determines the largest and the smallest value in an array of in-
tegers A. Next, display the value, the number of appearance and the position of the
maximum and minimum values. If the array contains several maxima or minima, the
program will retain the position of the first maximum or minimum encountered.
96 8.2. Two-dimensional arrays

Exercise 8.4 Insert a value into a sorted array


An array A of dimension N + 1 contains N integer values sorted in ascending order;
the (N + 1)th value is undefined. Insert a given VAL value read from the keyboard in
the array A to obtain a sorted array of N + 1 values.

Exercise 8.5 Finding a value in an array


Problem: Search an array of integers for a VAL value entered on the keyboard. Display
the position of VAL if it is in the array, otherwise display a corresponding message. The
POS value that is used to memorize the position of the value in the array, will have the
value -1 as long as VAL was not found.
Implement two versions:

1. Sequential search: Successively compare the values of the array with the given
value.

2. Dichotomous search (’binary search’):


Condition: Array A must be sorted
Compare the searched number to the value in the middle of the array,

• if there is a tie or if the array is exhausted, stop the treatment with a corre-
sponding message.
• if the value sought precedes the current value of the array, continue the
search in the half-array to the left of the current position.
• if the desired value follows the current value of the array, continue the
search in the half-array to the right of the current position.

Write the program for the case where the array A is sorted in ascending order.

Exercise 8.6 Merge two sorted arrays


Problem: We have two arrays A and B (of respective dimensions N and M), sorted
in ascending order. Merge the elements of A and B into a third FUS array sorted in
ascending order.
Method: Use three indexes i, j and k. Compare A[i] and B[i]; replace FUS[k] with the
smaller of the two elements; advance in the array FUS and in the array that contributed
its element. When one of the two arrays A or B is exhausted, simply copy the remaining
elements of the other array into the FUS array.

Exercise 8.7 Sort by maximum selection


Problem: Sort the elements of an array A in descending order.
Method: Traverse the array from left to right using the index I. For each element A[I]
of the array, determine the PMAX position of the (first) maximum to the right of A[I]
and exchange A[I] ] and A[PMAX].
Example:
Chapter 8. Arrays 97

Exercise 8.8 Sort by propagation (bubble sort)


Problem: Sort the elements of an array A in ascending order.
Method: Starting again each time at the beginning of the table, we carry out several
times the following treatment: We propagate, by successive permutations, the largest
element of the array towards the end of the array (like a bubble that goes back to the
surface of a liquid).
Exemple:

Implement the algorithm considering that:

• The part of the array (on the right) where there were no permutations is sorted.

• If no swapping has occurred, the array is sorted.

Exercise 8.9 Write a program which fills an array of size 10. This program must
calculate and show the sum and the multiplication of its elements.

Exercise 8.10 Write a program which allows the user to fill an integer number N and
an array of size 12. This program must indicate the number of occurrence of N in the
array.
98 8.2. Two-dimensional arrays

Exercise 8.11 Write a program which fills an array of integers of size 8. This program
must show the maximum and the minimum of the elements of the array, the number
of times the maximum appears and the number of times the minimum appears in the
vector.

Exercise 8.12 Write a program which fills an array of integers of size 15. This program
must show the elements of the array which are multiple of 7.

Exercise 8.13 Write a program which declares an array of integers of size maximum
size 20, asks the user to enter its effective size (should be less than 20) and allows the
user to fill his values. This program should not accept values greater than 150. In
other words, if the user fills a value greater than 150, the program does not insert the
value in the array and asks again for a new value of the user.

Exercise 8.14 Write a program that reads the dimension N of an array of int T (maxi-
mum size: 50 components), fills the array with keyboard input values and displays the
table.
Then delete all instances of the value 0 in the array T, pack the remaining elements
and print the resulting table.

Exercise 8.15 Write a program that reads the dimension N of an array of int T (maxi-
mum size: 50 components), fills the array with keyboard input values and displays the
table.
Arrange then the array elements T in reverse order without using aid table, and dis-
play the resulting table.
Hint: Interchange the array elements using two indexes that run through the array
starting respectively at the beginning and end of the array and meet in the middle

Two-dimensional arrays - Matrices


Exercise 8.16 Zeroing the main diagonal of a matrix
Write a program that zeros the elements of the main diagonal of a given square matrix
A.

Exercise 8.17 Matrice unitaire


Write a program that constructs and displays a unitary square matrix U of dimension
N. A unitary matrix is a matrix, such that:

1 if i=j

uij =
0 if i,j

Exercise 8.18 Transposition of a matrix


Write a program that performs the transposition tA of a matrix A of dimensions N and
M into a matrix of dimensions M and N.
Chapter 8. Arrays 99

1. The transposed matrix will be stored in a second matrix B which will then be
displayed.

2. The matrix A will be transposed by permutation of the elements.

Rappel:  
  a e i 
a b c d    
t t   b f j 
A = e f g h = 


  c g k 
i j k l

d h l
 

Exercise 8.19 Multiplication of a matrix by a real


Write a program that multiplies an A matrix by a real X.
Rappel:    
a b c d  X × a X × b X × c X × d 
X × e f g h = X × e X × f X × g X × h
   
i j k l X ×i X ×j X ×k X ×l
   

1. The result of the multiplication will be memorized in a second matrix B which


will then be displayed.

2. The elements of matrix A will be multiplied by X.

Exercise 8.20 Addition of two matrices


Write a program that performs the addition of two matrices A and B of the same di-
mensions N and M.
Reminder:

a b c d  a0 b0 c0 d 0  a + a0 b + b0 c + c0 d + d 0 


     
e f g h + e0 f 0 g 0 h0  =  e + e0 f + f 0 g + g 0 h + h0 

    
  0
i j k l i j 0 k0 l 0 i + i0 j + j 0 k + k0 l + l 0
   

1. The result of the addition will be stored in a third matrix C which will then be
displayed.

2. Matrix B is added to A.

Exercise 8.21 Multiplication of two matrices


By multiplying a matrix A of dimensions R and C with a matrix B of dimensions C and
P, a matrix MULT of dimensions R and P is obtained: A (R, C) * B (C, P) = MULT (R, P)
The multiplication of two matrices is done by multiplying the components of the two
matrices rows by columns:
C
X
MU LTij = ( aik × bkj )
k=1
Write a program that performs the multiplication of two matrices A and B. The result
of the multiplication will be stored in a third matrix MULT which will then be dis-
played.
100 8.2. Two-dimensional arrays

Reminder:
   
a b c    a × p + b × r + c × t a × q + b × s + c × u 
 p q    
 e f g     e × p + f × r + g × t e × q + f × s + g × u 

h i j  ×  r s  =  h × p + i × r + j × t h × q + i × s + j × u 
     
  t u  
h l m k×p+l ×r +m×t k×q+l ×s+m×u

Exercise 8.22 Pascal’s triangle


Write a program that builds the PASCAL triangle of degree N and stores it in a square
matrix P of dimension N + 1.
Exsmple: Pascal’s triangle of degree 6:
N = 0 1
N = 1 1 1
N = 2 1 2 1
N = 3 1 3 3 1
N = 4 1 4 6 4 1
N = 5 1 5 10 10 5 1
N = 6 1 6 15 20 15 6 1
Method: Calculate and display only the values up to the main diagonal (included).
Limit the degree to enter by the user to 13. Construct the triangle line by line:

1. Initialize the first element and the element of the diagonal to 1.

2. Calculate the values between the initialized elements from left to right using the
relation: Pi,j = Pi−1,j + Pi−1,j−1

Exercise 8.23 Search for saddle point


Search in a given matrix A for elements that are both a maximum on their row and a
minimum on their column. These elements are called saddle points. Display positions
and values of all found saddle points.
Exsmples: The underlined elements are saddle points:
!
1 8 3 4 0
6 7 2 7 0
 
4 5 8 9
3 8 9 3
 
 
3 4 9 3
 
3 5 6 7 7
4 2 2 8 9
 
 
6 3 2 9 7
 
1 2 3
4 5 6
 
 
7 8 9
Method: Create two auxiliary MAX and MIN matrices of the same dimensions as A,
Chapter 8. Arrays 101

such as:
1 if A[i][j] is a maximum on row i

MAX[i][j] =
0 otherwise
1 if A[i][j] is a minimum on column j

MIN [i][j] =
0 otherwise

Exercise 8.24 To manage the availability of the rooms in his hotel, the owner asks
you to write a program that uses a array rooms[10][40] whose values are 0s and 1s.
The value of rooms[i][j] is 1 if the room j of the floor i is occupied, this value is 0 if
this room is free. Write a program that asks the user to enter the values of the array
rooms[10][40], checking that the entered values are exclusively 0s and 1s. The program
then prompts the user to enter a floor number and a room number and displays the
status (free or occupied) of this room on this floor.

Additional Exercises

Exercise 8.25 Write a program which lets the user to fill two arrays of size 10. This
program indicates if these two arrays are identical or not.

Exercise 8.26 Write a program which requires of the user to fill an array of integers
of size 15. This program must replace the elements of the array whose value are equal
to 1 or to 100 by the value 0.

Exercise 8.27 Write a program which fills an array of real (float) numbers of size 20.
The program must show the elements of the array whose index is even.

Exercise 8.28 Write a program which fills an array of real numbers of size 20. The
program must show the elements of the array whose index is multiple of 5.

Exercise 8.29 Write a program which reads an array of 7 integers then represents
them in an increasing order.

Exercise 8.30 Write a program which asks the user to enter an array of 10 integers
then re-arrange them as follows: Odd integers first, then even integers.

Exercise 8.31 Write a program that initializes each element tab[i] of a tab array passed
as a parameter to the value2i .
Write a program that reads characters equal to 0 or 1 from the keyboard and calculates
the number that these digits represent in binary. We can display in base 10 the result.
102 8.2. Two-dimensional arrays

Exam questions

Exercise 8.32 (Section I - Final Session 1 2018-2019) Write a program that:

1. reads the effective dimension N of an array (maximum dimension: 50 compo-


nents);

2. then fills two arrays A and B each with N integers entered on the keyboard;

3. then fills a third array C by the inverse summation of A and B;

4. then displays array C.

PS: the inverse summation can be calculated for each element of the array as illustrated
below:

Running example:
9. Strings

9.1 Declaration and storage 103

9.2 Constant strings 104

9.3 Initializing strings 105

9.4 Access to the string elements 106

9.5 Alphabetical and lexicographic precedence 106

9.6 Working with strings 107

9.7 Array of strings 113

There is no special type string or string in C. A string is treated as a one-dimensional array of


characters (character vector). There are still special notations and a good amount of special
functions for character array processing.

9.1 Declaration and storage


Declaration of character strings in C

char <VariableName> [< Length > ] ;

Example 9.1

char FIRSTNAME [ 2 0 ] ;
char LASTNAME[ 2 0 ] ;
char PHRASE [ 3 0 0 ] ;

Space to reserve When declaring, we must indicate the space to be reserved in memory for
the storage of the chain.
The internal representation of a string is terminated by the symbol ’\0’ (NULL). Thus, for a
text of n characters, we must expect n + 1 bytes.
Unfortunately, compiler C does not check if we have reserved a byte for the end-of-string
symbol; the error will only be noticed when running the program ...

103
104 9.2. Constant strings

Storage The name of a string is the representative of the address of the first character in
the string. To memorize a variable that must be able to contain a text of N characters, we
need N + 1 bytes in memory:
Example 9.2

char TXT[ 1 0 ] = "BONJOUR ! " ;

9.2 Constant strings


• Constant strings (string literals) are enclosed in quotation marks. The empty string is
then: ""
• In strings, we can use all escape sequences defined as constant characters:
" This \ n t e x t \ n w i l l be spread over 3 l i n e s . "

• The symbol " can be represented inside a string by the escape sequence \":
" Showing \ " quotes \ " \ n "

• The symbol ‘ can be represented inside a list of characters by the escape sequence \’ :
{ ’L’ , ’\ ’ ’ , ’ a ’ , ’ s ’ , ’ t ’ , ’u’ , ’ c ’ , ’ e ’ , ’\0 ’}

• Several constant strings which are separated by space characters (spaces, tabs or spaces)
in the program text will be joined into a single constant string during compilation:
" one " " two "
" three "

will be evaluated to
" one two t h r e e "

Thus it is possible to define very long constant character strings by using several lines
in the program text.

For the storage of the "Hello" string, C needs six (!!) bytes.
’x’ is a constant character, which has a numeric value:
For example, ’x’ has the value 120 in the ASCII code.
"x" is an array of characters that contains two characters:
the letter ’x’ and the character NULL: ’\0’
’x’ is encoded in a byte
"x" is encoded in two bytes
Chapter 9. Strings 105

9.3 Initializing strings


In general, arrays are initialized by the indication of the list of elements of the array in braces:
char CHAINE [ ] = { ’H’ , ’ e ’ , ’ l ’ , ’ l ’ , ’ o ’ , ’ \ 0 ’ } ;
For the special case of character arrays, we can use a more comfortable initialization by
simply indicating a constant string of characters:
char CHAINE [ ] = " Hello " ;
When initializing with [], the computer automatically reserves the number of bytes necessary
for the string, ie the number of characters + 1 (here: 6 bytes). We can also explicitly indicate
the number of bytes to reserve, if it is greater than or equal to the length of the initialization
string.

Example 9.3

Exercise 9.1 Which of the following strings are initialized correctly? Correct false
declarations and indicate for each string the number of bytes that will be reserved in
memory.
a) char a[] = " one \ntwo\ n t h r e e \n " ;
b) char b[12] = " one two t h r e e " ;
c) char c [] = ’ abcdefg ’ ;
d) char d[10] = ’x ’ ;
e) char e [5] = " five " ;
f) char f [] = " This " " s e n t e n c e " " i s broken " ;
g) char g[2] = { ’a ’ , ’\0 ’};
h) char h[4] = { ’ a ’ , ’b ’ , ’c ’ } ;
i) char i [4] = " ’o ’ " ;
106 9.4. Access to the string elements

9.4 Access to the string elements


Access to an element of a string can be done in the same way as access to an element of a
table. By declaring a string by:
char A [ 6 ] ;
we have defined an array A with six elements, which can be accessed by:
A[ 0 ] , A[ 1 ] , ... , A[ 5 ]

Example 9.4

9.5 Alphabetical and lexicographic precedence


Alphabetical precedence of characters The precedence of characters in the alphabet of a
machine is dependent on the character code used.
For the ASCII code, we can see the following order:
. . . ,0 ,1 ,2 , . . . , 9 , . . . ,A, B , C, ... ,Z , . . . , a , b , c , ... ,z , . . .
The special symbols (’ ,+ ,- ,/ ,{ ,] , ...) and the accented letters (é ,è ,à ,û , ...) are distributed
around the three large groups of characters (numbers, uppercase, lowercase). Their prece-
dence does not correspond to any specific order rule.

Precedence relationship From the alphabetic precedence of the characters, one can de-
duce a precedence relation ’is less than’ on the set of characters. So, we can say that
’ 0 ’ i s l e s s than ’Z ’
and note
’ 0 ’ < ’Z ’
because in the alphabet of the machine, the code of the character ’0’ (ASCII: 48) is less than
the code of the character ’Z’ (ASCII: 90).

Lexical precedence of strings Based on this alphabetic precedence relationship of char-


acters, we can define a lexicographic precedence for strings. This precedence relationship
follows the "dictionary order" and is defined recursively:

1. The empty string ”” precedes all other strings lexicographically.

2. The string A = ”a1 a2 ...ap ” (p characters) precedes the lexicographically string B =


”b1 b2 ...bm ” (m characters) if one of the following two conditions is met:

(a) 0 a01 <0 b10


(b) 0 a01 =0 b10 and ”a2 a3 ...ap ” precedes lexicographically ”b2 b3 ...bm ”
Chapter 9. Strings 107

Example 9.5

• "ABC" precedes "BCD" because ’A’<’B’

• "ABC" precedes "B" because ’A’<’B’

• "Abc" precedes "abc" because ’A’<’a’

• "ab" precedes "abcd" because "" precedes "cd"

• " ab" precedes "ab" because ’ ’ <’a‘ (the ASCII code of ’ ’ is 32, and the ASCII code
of ’a’ is 97)

Unfortunately, there are different character codes (eg ASCII, EBCDIC, ISO) and the lexicographic order is
machine dependent. Even the strcmp function which indicates the lexicographic precedence of two character
strings depends on the character code used.

Conversions and tests Taking into account the alphabetical order of the characters, one
can control the type of the character (digit, capital, lowercase).

Example 9.6

i f (C>= ’0 ’ && C<= ’9 ’) p r i n t f ( " D i g i t \n " , C ) ;


i f (C>=’A’ && C<=’Z ’ ) p r i n t f ( " UpperCase \n " , C ) ;
i f (C>=’a ’ && C<=’z ’ ) p r i n t f ( " LowerCase \n " , C ) ;

It’s easy to convert uppercase letters into lowercase letters:


i f (C>=’A’ && C<=’Z ’ ) C = C− ’A’ + ’ a ’ ;
or vice versa:
i f (C>=’a ’ && C<=’z ’ ) C = C− ’ a ’ + ’A ’ ;

The EBCDIC code is organized in zones, so that the characters of the three major groups are not coded
consecutively. (Eg: the character codes ’i’ and ’j’ differ by 8 units). The conversion methods discussed above
therefore do not work correctly in the EBCDIC code and a portable program must be written using the
functions (isalpha, islower, toupper, ...) of the library <ctype.h> which are independent character code.

9.6 Working with strings


Function libraries in C contain a series of special functions for processing strings. Unless
otherwise specified, the functions described in this chapter are portable in accordance with
108 9.6. Working with strings

the ANSI-C standard.

The functions of <stdio.h> As we have already seen, the <stdio.h> library gives us func-
tions that perform the input and output of data. Beside the printf and scanf functions we
already know, we find the two puts and gets functions, specially designed for writing and
reading strings.

• Display strings

1. printf with the format specifier %s is used to embed a string in a sentence. In ad-
dition, the %s specifier allows the indication of the minimum width of the display
field. In this field, the data is justified on the right. If a negative minimum width
is specified, the string will be left justified. A number following a point indicates
the maximum width for the display.

Example 9.7

char NOM[ ] = " h e l l o , world " ;


p r i n t f ( " : % s : " , NOM) ; −> : h e l l o , world :
p r i n t f ( " : % 5 s : " , NOM) ; −> : h e l l o , world :
p r i n t f (":%15 s : " , NOM) ; −> : h e l l o , world :
p r i n t f (":% −15 s : " , NOM) ; −> : h e l l o , world :
p r i n t f ( " : % . 5 s : " , NOM) ; −> : h e l l o :

2. puts is ideal for writing a constant string or the contents of a variable in an iso-
lated line.
Syntax: puts(< String >)
Effect: writes the string designated by <String> on stdout and causes a newline.
In practice, puts(T XT ); is equivalent to printf (”%s\n”, T XT );

Example 9.8

char TEXT [ ] = " This i s a f i r s t l i n e . " ;


puts (TEXT ) ;
puts ( " and t h i s i s another . " ) ;

• Reading strings

1. scanf with the %s specifier reads an isolated word inside a data sequence of the
same or another type.
Effect: scanf with the specifier %s reads a word from the stdin standard input file
and stores it at the address that is associated with %s.
Chapter 9. Strings 109

Example 9.9 char PLACE [ 2 5 ] ;


i n t DAY, MONTH, YEAR ;
p r i n t f ( " Enter b i r t h p l a c e and b i r t h date : \n " ) ;
s c a n f ("% s %d %d %d " , PLACE, &DAY, &MONTH, &YEAR ) ;

– The function scanf needs the addresses of its arguments:


* The names of the numeric variables (int, char, long, float, ...) must be marked with
the symbol ’&’.
* Since the name of a string is the representative of the address of the first character of
the string, it must not be preceded by the operator address ’&’ !
– The function scanf with several arguments assumes that the user knows exactly the number
and order of the data to be entered! Thus, the use of scanf for string reading is only
advisable if one is forced to read a fixed number of words at one time.

2. gets is ideal for reading one or more lines of text (eg sentences) ending in a new
line.
Syntax: gets(< String >)
Effect: gets reads a line of stdin characters and copies it to the address specified
by <String>. The return to the final line is replaced by the end-of-string symbol
’\0’.

Example 9.10

i n t MAXI = 1000;
char LIGNE [MAXI ] ;
g e t s ( LIGNE ) ;

Exercise 9.2 Write a program that reads 6 words, separated by spaces and then dis-
plays them in a line, but in reverse order. The words are stored in 6 variables M1, ...,
M6.
Exemple:
here i s a small s e n t e n c e !
! s e n t e n c e small a i s here

Exercise 9.3 Writing a program that reads a line of text (not exceeding 200 characters)
stores it in a TXT variable and then displays:

1. the length L of the string.

2. the number of ’e’ contained in the string.

3. the whole sentence backwards, without changing the content of the variable TXT.
110 9.6. Working with strings

4. the whole sentence backwards, after reversing the order of characters in TXT.

here i s a small s e n t e n c e !
! e c n e t n e s llams a s i ereh

Exercise 9.4 Write a program that reads a text TXT (less than 200 characters) and re-
moves all occurrences of the ’e’ character by packing the remaining items. The changes
will be made in the same TXT variable.
Exemple:
This l i n e c o n t a i n s some l e t t e r s e .
This l i n c o n t a i n s som l t t r s .

The functions of <string.h> The library <string.h> provides a multitude of useful func-
tions for the processing of strings. Here is a brief description of the most frequently used
functions.
In the following table, <n> represents a number of type int. The symbols <s> and <t> can
be replaced by:

• a constant string of characters

• the name of a variable declared as an array of char

Functions for processing character strings

strlen(<s>) provides the length of the string without counting the final ’\0’
strcpy(<s>, <t>) copies <t> to <s>
strcat(<s>, <t>) appends <t> to the end of <s>
strcmp(<s>, <t>) compares <s> and <t> lexicographically and provide a result:
negative if <s> precedes <t>
zero if <s> is equal to <t>
positive if <s> follows <t> <t>
strncpy(<s>, <t>, <n>) copies at most <n> characters from <t> to <s>
strncat(<s>, <t>, <n>) adds at most <n> characters from <t> to the end of <s>

Table 9.1: Functions for processing character strings

• Since the name of a string represents a fixed address in memory, we can not ’assign’ another string to
the name of an array:

You have to copy the string character by character or use the strcpy function strncpy respectively:
s t r c p y (A , " H e l l o " ) ;
Chapter 9. Strings 111

• The concatenation of strings in C is not done by the symbol ’+’ as in algorithmic language or in
Pascal. You must either copy the second string character by character or use the strcat or strncat
function.
• The strcmp function is dependent on the character code and can provide different results on different
machines.

Exercise 9.5 Write a program that asks for the user’s last name and first name and
then displays the total length of the name without counting spaces. Use the strlen
function.
Enter your f i r s t and l a s t name :
Mickey Mouse

Hello Mickey Mouse !


Your name i s made up o f 11 l e t t e r s .

Exercise 9.6 Write a program that reads two strings CH1 and CH2, compares them
lexicographically and displays the result:
Enter the f i r s t s t r i n g : ABC
Enter the second s t r i n g : abc
"ABC" p r e c e d e s " abc "

Exercise 9.7 Write a program that reads two strings CH1 and CH2 and copies the first
half of CH1 and the first half of CH2 into a third CH3. Show the result.

1. Use the special functions of <string.h>.

2. Use only the gets and puts functions.

The functions of <stdlib.h> The <stdlib.h> library contains function declarations for con-
verting numbers to strings and vice versa.

• String –> Number


The three functions defined later correspond to the ANSI-C standard and are portable.
The symbol <s> can be replaced by:

– a constant string of characters


– the name of a variable declared as an array of char

Converting strings to numbers

– atoi(<s>) returns the numeric value represented by <s> as int


– atol(<s>) returns the numeric value represented by <s> as long
– atof(<s>) returns the numeric value represented by <s> as double (!)
112 9.6. Working with strings

General rules for conversion:


– Spaces at the beginning of a string are ignored
– There is no control of the domain of the target
– The conversion stops at the first non-convertible character
– For a non-convertible string, the functions return zero

Exercise 9.8 Soient les instructions:

char STR [ 2 0 0 ] ;
puts ( " Enter a number : " ) ;
g e t s ( STR ) ;
p r i n t f ( " Entry = %s \n " , STR ) ;
p r i n t f ( " i n t e g e r = %d \n " , a t o i ( STR ) ) ;
p r i n t f ( " long = %ld \n " , a t o l ( STR ) ) ;
p r i n t f ( " double = %f \n " , a t o f ( STR ) ) ;

What are the values displayed if you enter the following strings:
a) 123
b) −123
c) − 123
d) 123.45
e) 12E3
f) 1234 f5
g) −1234567
h) 123e −02
i) −0 ,1234

• Number –> String


The ANSI-C standard does not contain functions for converting numbers to strings. If
we limit ourselves to systems running under DOS, we can still use the itoa, ltoa and
ultoa functions which convert integers to strings.
Converting numbers to strings
– itoa (<n_int>, <s>, <b>)
– ltoa (<n_long>, <s>, <b>)
– ultoa (<n_uns_long>, <s>, <b>)
Each of these three functions converts its first argument to a character string which
will then be assigned to <s>. The conversion is done in base <b>.

– <n_int> is a number of type int


– <n_long> is a number of type long
– <n_uns_long> is a number of type unsigned long
– <s> is a character string of maximum length: 17 resp. 33 byte
– <b> is the base for conversion (2 ... 36)
Chapter 9. Strings 113

The functions of <ctype.h> The functions of <ctype.h> are used to classify and convert
characters. National symbols (é, è, ä, ü, ß, ç, ...) are not considered. The functions of
<ctype.h> are independent of the character code of the machine and promote the portability
of programs. In the following, <c> represents a value of type int that can be represented as
a character.
The following classification functions provide a result of type int other than zero, if the
respective condition is met, otherwise zero.

The function: returns a value other than zero


isupper(<c>) if <c> is an uppercase (’A’ ... ’Z’)
islower(<c>) if <c> is a lowercase (’a’ ... ’z’)
isdigit(<c>) if <c> is a decimal digit (’0’ ... ’9’)
isalpha(<c>) if islower (<c>) or isupper (<c>)
isalnum(<c>) if isalpha (<c>) or isdigit (<c>)
isxdigit(<c>) if <c> is a hexadecimal digit
(’0’...’9’ or ’A’...’F’ or ’a’...’f’)
isspace(<c>) if <c> is a sign of spacing
(’ ’, ’\t’, ’\n’, ’\r’, ’\f’)

Table 9.2: Classification functions

The following conversion functions provide a value of type int that can be represented
as a character; the original value of <c> remains unchanged:

tolower(<c>) returns <c> converted to lowercase if <c> is an uppercase


toupper(<c>) returns <c> converted to uppercase if <c> is a lowercase

Table 9.3: Conversion functions

9.7 Array of strings


Often, it is necessary to memorize a sequence of words or sentences in variables. It is then
convenient to create an array of strings, which will lighten the declarations of the variables
and simplify the access to the different words (or sentences).
An array of character strings corresponds to a two-dimensional array of type char, where
each line contains a string of characters.

Declaration The statement charDAY [7][9]; reserve the space in memory for 7 words con-
taining 9 characters (including 8 significant characters).
114 9.7. Array of strings

Initialisation During the declaration it is possible to initialize all the components of the
array by constant strings of characters:
char JOUR [ 7 ] [ 1 0 ] = { "MONDAY" , "TUESDAY" , "WEDNESDAY" ,
"THURSDAY" , "FRIDAY " , "SATURDAY" ,
"SUNDAY " } ;

Storage String tables are stored line by line. The DAY variable will need 7 * 10 * 1 = 70
bytes in memory.

Access to the different components It is possible to access the different strings of a table,
simply by indicating the corresponding line.

Example 9.11 The execution of the following three statements:


char DAY[ 7 ] [ 1 0 ] = { "MONDAY" , "TUESDAY" , "WEDNESDAY" ,
"THURSDAY" , "FRIDAY " , "SATURDAY" ,
"SUNDAY " } ;
int I = 2;
p r i n t f ( " Today , i t ’ s %s ! \ n " , DAY[ I ] ) ;
will display the sentence
Today , i t ’ s WEDNESDAY !

Assignment Expressions like DAY[I] represent the address of the first element of a string.
So do not try to ’modify’ such an address by a direct assignment!

Assigning a string to a string array component is usually done using the strcpy function:

Example 9.12 The instruction


s t r c p y (DAY[ 4 ] , " F r i d a y OFF " ) ;
will change the content of the 5th component of the DAY array from "Friday" to "Friday
OFF".

Access to characters Obviously, there is always the possibility to directly access the differ-
ent characters that make up the words in the array.
Chapter 9. Strings 115

Example 9.13 The instruction


f o r ( I =0; I <7; I ++)
p r i n t f ("% c " , DAY[ I ] [ 0 ] ) ;
will display the first letters of the days of the week:
M T W T F S S

Exercise 9.9 Write a program that reads 10 words and stores them in an array of
strings. Sort the 10 words lexicographically using the strcmp and strcpy functions.
Display the sorted array. Use the direct selection sort method.

Exercise 9.10 Write a program that reads a number between 1 and 7 and displays the
name of the corresponding day of the week:

• "monday" for 1

• "tuesday" for 2

• ...

• "sunday" for 7

Use the first element of the array to memorize a small error message.

Exercise 9.11 Write a program that reads 6 words, separated by spaces and then
displays them in a line, but in reverse order. The words are stored in an array of
strings.
Example:
here i s a small s e n t e n c e !
! s e n t e n c e small a i s here
116 9.7. Array of strings

Computer Exercises
Unless specified otherwise, the following exercises are to be solved without using the special
functions of libraries <string.h>, <stdlib.h> or <ctype.h>. They serve to understand and
follow the reasoning of these functions.

Exercise 9.1 Write a program that reads two strings of characters, and indicates their
lexicographic precedence in the character code of the machine (here: ASCII code).

Exercise 9.2 Write a program that reads a string of characters CH and converts all
uppercase letters to lowercase and vice versa.
The result will be stored in the same CH variable and displayed after the conversion.

Exercise 9.3 Write a program that reads a string of characters and interprets it as a
positive integer in the decimal base. For the conversion, use the functions of <ctype.h>
and the alphabetic precedence of the characters from ’0’ to ’9’. Save the result in a
variable of type long. The conversion stops when the first character does not represent
a decimal digit. Use an OK logical indicator that specifies whether the string correctly
represents an integer and positive value.

Exercise 9.4 Write a program that reads a string s and copy s into a string t (of the
same size) in reverse order, except that a sequence of white space is squeezed to a
single space.

Exercise 9.5 Write a program that reads two strings s1 and s2, and then prints on the
screen the number of times s1 appears in s2, and the position of each occurrence of s1
in s2.

Exercise 9.6 Write an algorithm that reads a string s and a character c, prints on the
screen the number of times c appears in s and the first position of c in s .

Exercise 9.7 A palindrome string is a string that, after eliminating its spaces, reads
the same backward or forward. Example: "never odd or even".
Write a program that asks the user to enter strings until the user enter “q”, and, for
every entered string, checks if it’s a palindrome.
Sample run:
Enter a string (q to quit): starcomedybydemocrats
starcomedybydemocrats is a palindrome

Enter a string (q to quit): starcomedybyrepublicans


starcomedybyrepublicans is not a palindrome

Enter a string (q to quit): q


Chapter 9. Strings 117

Exercise 9.8 Write a program that deletes the first occurrence of an DEL string in a
STR string.
Examples:
PHON ALPHONSE ALSE
EI PIERRE PIERRE
T TOTALEMENT OTALEMENT
HELLO HELLO

Exercise 9.9 Write a program that replaces the first occurrence of a string STR1 with
the string STR 2 in a string STR. Use an END string to save the string during the
replacement.
Examples:
PHON OY ALPHONSE ALOYSE
IE EI PIERRE PEIRRE
IE ARTE PIERRE PARTERRE
EI IE PIERRE PIERRE
TOT FIN TOTALEMENT FINALEMENT
TTT HELLO HELLO

Exercise 9.10 Write a program that replaces all occurrences of a string STR1 with the
string STR2 in a string STR. Use a END to save the string during the replacement.
Examples:
PHON OY ALPHONSE ALOYSE
AN ONT BANANE BONTONTE
T Y TOTALEMENT YOYALEMENY
TTT HELLO HELLO
L HELLO HEO

Additional Exercises

Exercise 9.11 Write a program which asks the user to enter a text (char array) then
prints it in reverse order.

Exam questions

Exercise 9.12 (Section I - Session 1 2018-2019) Write a program that reads a string
STR from the keyboard and then adds the reverse of STR to its end (i.e. STR should
contain the original string and its reverse).
You may assume that the size of the string STR is big enough to hold the string and its
reverse.
The usage of any function of the string.h library is not allowed.
Running example:
118 9.7. Array of strings

Exercise 9.13 (Section I - Session 2 2018-2019) Write a program that reads two strings
STR1 and STR2, then appends them in a third string STR3 without using any predefined
function from the string.h library.
Each of the 3 strings can contain 20 characters at maximum.
The program should test if the third string can hold the concatenation.
In the positive case, print STR3. In the negative case, print the error message
"Impossible to concatenate both strings.".
Running example:
10. Functions

10.1 Modularisation de programmes 119

10.2 The notion of blocks and the scope of identifiers 121

10.3 Declaration and definition of functions 124

10.4 Return a result 132

10.5 Parameters of a function 135

10.6 Functions / modules in C 139

The structuring of programs in subprograms is done in C using functions. We have already


used predefined functions in standard libraries (printf of <stdio.h>, strlen of <string.h>,
pow of <math.h>, etc.). In this chapter, we will discover how we can define and use our own
functions.

10.1 Modularisation de programmes


So far, we have solved our problems using predefined functions and a single new function:
the main function main(). For more complex problems, we thus obtain long lists of in-
structions, little structured and therefore not very comprehensible. In addition, it is often
necessary to repeat the same sequence of commands in the text of the program, which leads
to a waste of internal and external memory.

Modularity and its advantages Most programming languages allow us to subdivide our
programs into simpler and more compact subroutines, functions or procedures. With these
structures we can modularize our programs to obtain more elegant and efficient solutions.

Modules In this context, a module refers to a data and instruction entity that provides a
solution to a (small) well defined part of a more complex problem. A module can use other
modules, send them data and receive results in return. All the modules thus connected must
then be able to solve the global problem.

Advantages Here are some advantages of a modular program:


• Better readability
• Reduced risk of errors
• Possibility of selective tests
• Concealing methods: When using a module you only need to know its effect, without
having to deal with the details of its realization.

119
120 10.1. Modularisation de programmes

• Reusing existing modules: It is easy to use modules that you have written yourself or
that have been developed by other people.

• Ease of maintenance : A module can be changed or replaced without having to touch


the other modules of the program.

• Fostering teamwork: A program can be developed as a team by delegation of the pro-


gramming of the modules to different people or groups of people. Once developed, the
modules can constitute a common basis of work.

• Hierarchy of modules: A program can first be solved globally at the main module
level. Details can be reported to sub-ordered modules which can also be subdivided
into sub-modules and so on. In this way, we get a hierarchy of modules. Modules can
be expanded from top to bottom in the hierarchy (’top-down-development’) or from
bottom to top (’bottom-up-development’).

Example 10.1 Examples of modularization in C: Display a rectangle of stars

The following program displays on the screen a rectangle of length L and height H,
consisting of ’*’:

# i n c l u d e < s t d i o . h>
i n t main ( )
{
/* P r o t o t y p e s o f f u n c t i o n s c a l l e d from main */
void RECTANGLE( i n t L , i n t H ) ;
/* D e c l a r a t i o n o f l o c a l v a r i a b l e s i n main */
i n t L , H;
/* Treatments */
p r i n t f ( " Enter the l e n g t h (>= 1 ) : " ) ;
s c a n f ("%d " , &L ) ;
p r i n t f ( " Enter the h e i g h t (>= 1 ) : " ) ;
s c a n f ("%d " , &H ) ;
/* Display a r e c t a n g l e o f s t a r s */
RECTANGLE( L ,H ) ;
return 0;
}

For the function to be executable by the machine, it is necessary to specify the function
RECTANGLE:
Chapter 10. Functions 121

void RECTANGLE( i n t L , i n t H)
{
/* P r o t o t y p e s o f c a l l e d f u n c t i o n s */
void LINE ( i n t L ) ;
/* D e c l a r a t i o n o f l o c a l v a r i a b l e s */
int I ;
/* Treatments */
/* Show H l i n e s with L s t a r s */
f o r ( I =0; I <H; I ++)
LINE ( L ) ;
}

In order for the RECTANGLE function to be executable by the machine, the LINE
function must be specified:

void LINE ( i n t L )
{
/* Display on the s c r e e n a l i n e with L s t a r s */
/* D e c l a r a t i o n o f l o c a l v a r i a b l e s */
int I ;
/* Treatments */
f o r ( I =0; I <L ; I ++)
printf ( " * " ) ;
printf ("\n " ) ;
}

10.2 The notion of blocks and the scope of identifiers

C functions are defined using instruction blocks. A block of instructions is framed by braces
and consists of two parts:

{
<local declarations >
<instructions >
}

This is true for all instruction blocks, not just for blocks that contain a function. Thus, the
statement block of an if, while, or for command can theoretically contain local declarations
of variables and even functions.
122 10.2. The notion of blocks and the scope of identifiers

Example 10.2 The variable I is declared inside a conditional block. If the condition
(N> 0) is not satisfied, I is not defined. At the end of the conditional block, I disap-
pears.

i f (N>0)
{
int I ;
f o r ( I =0; I <N; I ++)
...
}

Local variables Variables declared in an instruction block are only visible inside this block.
They are said to be local variables to this block.

Example 10.3 The variable NAME is defined locally in the block of the HELLO func-
tion. Thus, no other function has access to the variable NAME:

void HELLO( void ) ;


{
char NAME[ 2 0 ] ;
p r i n t f ( " Enter your name : " ) ;
g e t s (NAME) ;
p r i n t f ( " Hello %s ! \ n " , NAME) ;
}

Example 10.4 The declaration of variable I is inside a conditional statement block. It


is not visible outside this block, nor even in the function that surrounds it.

i f (N>0)
{
int I ;
f o r ( I =0; I <N; I ++)
...
}

A variable declared inside a block hides all the variables of the same name of the blocks that surround it.

Example 10.5 In the following function,


Chapter 10. Functions 123

i n t FONCTION( i n t A ) ;
{
int X;
...
X = 100;
...
while (A>10)
{
double X ;
...
X *= A ;
...
}
}

the first instruction X = 100 refers to the variable of type int declared in the outer block of the
function; the instruction X * = A acts on the variable of the double type declared in the while
loop. Inside the loop, it is impossible to access the variable X of the outer block.

It is not a good style to use variable names that hide variables declared in outer blocks; this can
easily lead to misunderstandings and mistakes.
Most C programs do not take advantage of the ability to declare variables or functions within
a loop or conditional block. In the following, we will make all our local declarations at the
beginning of the functions.

Global variables Variables declared at the beginning of the file, outside of all the functions
are available to all functions of the program. These are then global variables. In general,
global variables are declared immediately after the #include statements at the beginning of
the program.

The variables declared at the beginning of the main function main are not global variables, but they are
local to main!

Example 10.6 The STATUS variable is declared globally so that it can be used in
procedures A and B.
124 10.3. Declaration and definition of functions

# i n c l u d e < s t d i o . h>
i n t STATUS ;

void A ( . . . )
{
...
i f ( STATUS>0)
STATUS− −;
else
...
...
}

void B ( . . . )
{
...
STATUS++;
...
}

• Global variables should be used with care as they create invisible links between functions. The mod-
ularity of a program can suffer and the programmer risks losing the big picture.
• Special care must be taken not to unintentionally hide global variables with local variables of the
same name.
• The codex of defensive programming advises us to write our programs as ’locally’ as possible.

The use of global variables becomes inevitable, if

• several functions that do not call each others need the same variables, or

• Several functions of a program need the same set of variables. It would then be too
cumbersome to pass all the variables as parameters from one function to another.

10.3 Declaration and definition of functions


In general, the name of a function appears in three places in a program:

1. during the declaration

2. when defining

3. during the call


Chapter 10. Functions 125

Example 10.7 In the following program, the main function uses 2 functions:

• INPUT which reads an integer number on the keyboard and provides it as a


result. The INPUT function has no parameters.

• MAX which returns as result the maximum of two integers provided as parame-
ters.

# i n c l u d e < s t d i o . h>

i n t main ( )
{
/* P r o t o t y p e s o f used f u n c t i o n s */
i n t INPUT ( ) ;
i n t MAX( i n t N1 , i n t N2 ) ;
/* D e c l a r a t i o n o f v a r i a b l e s */
i n t A, B ;
/* Treatement while c a l l i n g f u n c t i o n s */
A = INPUT ( ) ;
B = INPUT ( ) ;
p r i n t f ( " The maximum i s %d\n " , MAX(A, B ) ) ;
return 0;
}

/* D e f i n i t i o n o f the f u n c t i o n INPUT */
i n t ENTREE( void )
{
i n t NUMBER;
p r i n t f ( " Enter an i n t e g e r : " ) ;
s c a n f ("%d " , &NUMBER) ;
r e t u r n NUMBER;
}

/* D e f i n i t i o n o f the f u n c t i o n MAX */
i n t MAX( i n t N1 , i n t N2)
{
i f (N1>N2)
r e t u r n N1 ;
else
r e t u r n N2 ;
}

Definition of a function In the definition of a function, we indicate:

• the name of the function


126 10.3. Declaration and definition of functions

• the type, number and names of the parameters of the function

• the type of result provided by the function

• local data to the function

• the instructions to be executed

<ReturnType> <FunctionNName> (<TypePar1> <NamePar1> ,


<TypePar2> <NamePar2> , . . . )
{
<local declarations >
<Statements >
}

Note that there is no semicolon behind the definition of the function parameters.

Identifiers Identifiers: The names of the parameters and the function are identifiers that
must correspond to the known restrictions. Well-chosen names can provide useful informa-
tion about their role. Thus, identifiers are also part of the documentation for a program.

If we choose a function name that already exists in a library, our function hides the predefined function.

Type of a function If a function F gives a result of the type T, we say that ’the function F is
of the type T’ or that the function F has the type T ’.

Example 10.8 The MAX function is of type int and it needs two parameters of type
int. The result of the MAX function can be integrated into other expressions.

i n t MAX( i n t N1 , i n t N2)
{
i f (N1>N2)
r e t u r n N1 ;
else
r e t u r n N2 ;
}

Example 10.9 The PI function provides a rational result of the float type. The list of
PI parameters is declared as void, that is, PI does not need parameters and it must be
called by: PI()
Chapter 10. Functions 127

f l o a t PI ( void )
{
return 3.1415927;
}

• A function can provide as a result:


– an arithmetic type,
– a pointer,
– void (the function then corresponds to a ’procedure’).
A function can not return arrays, strings, or functions. (Caution: You can, however, return a pointer
to the first element of an array or character string.)
• If a function does not provide a result, you must specify void as the result type.
• If a function has no parameters, we can declare the parameter list as (void) or simply as ().
• The default type is int; in other words: if the type of a function is not declared explicitly, it is auto-
matically of type int.
• It is forbidden to define functions within another function.
• In principle, the order of definitions in the program text does not play a role, but each function must
be declared or defined before being called.

The main function is of type int. It is executed automatically when the program is called. In place of the
definition:
i n t main ( v o i d )
we can simply write:
main ( )

Declaration of a function In C, you must declare each function before you can use it. The
declaration informs the compiler of the type of the parameters and the result of the function.
Using this data, the compiler can control whether the number and type of parameters of a
function are correct. If in the program text the function is defined before its first call, it does
not need to be declared.

Prototype of a function The declaration of a function is done by a prototype of the func-


tion which indicates only the type of the data transmitted and received by the function.

<ReturnType> <FunctionNName> (<TypePar1 > , <TypePar2 > , . . . ) ;

ou bien
128 10.3. Declaration and definition of functions

<ReturnType> <FunctionNName> (<TypePar1> <NamePar1> ,


<TypePar2> <NamePar2> , . . . ) ;

When declaring, the number and type of parameters must necessarily correspond to those of the function
definition.

Parameter names You can optionally include the parameter names in the declaration, but
they are not considered by the compiler. The names nevertheless provide interesting infor-
mation for the programmer who can deduce the role of the different parameters.

It is customary to copy (using Edit - Copy & Paste) the first line of the definition of the function as a
declaration. (Do not forget to add a semicolon at the end of the statement!)

Rules for the declaration of functions Similar to variable declarations, we can declare a
function locally or globally. The definition of functions plays a special role for the declara-
tion. In summary, we will consider the following rules:
• Local declaration: A function can be declared locally in the function that calls it (before
declaring variables). It is then available to this function.
• Global declaration: A function can be declared globally at the beginning of the pro-
gram (behind the #include statements). It is then available to all functions of the pro-
gram.
• Implicit statement by definition: The function is automatically available to all func-
tions that follow its definition.
• Multiple declaration: A function can be declared multiple times in the text of a pro-
gram, but the indications must match.

The main function does not need to be declared.

Example 10.10 Consider the following situation:


• The main function calls the FA function.
• The FA function calls the function FB.
So we get the following hierarchy:

There are many possibilities to declare and define these functions. We will retain three
variants that follow a consistent logic:
Chapter 10. Functions 129

1. Local declarations of functions and ’top-down’ definition


The top-down definition follows the hierarchy of functions: We start by defining
the main function main, followed by subroutines FA and FB. We have to explic-
itly declare FA and FB because their definitions follow their calls.

/* D e f i n i t i o n o f main */
main ( )
{
/* L o c a l d e c l a r a t i o n o f FA */
i n t FA ( i n t X , i n t Y ) ;
...
/* C a l l i n g FA */
I = FA( 2 , 3 ) ;
...
}

/* D e f i n i t i o n o f FA */
i n t FA( i n t X , i n t Y )
{
/* L o c a l d e c l a r a t i o n o f FB */
i n t FB ( i n t N, i n t M) ;
...
/* C a l l i n g FB */
J = FB ( 2 0 , 3 0 ) ;
...
}

/* D e f i n i t i o n o f FB */
i n t FB ( i n t N, i n t M)
{
...
}

This definition order has the advantage of reflecting the hierarchy of functions:
Thus the user who is only interested in the global solution of the problem has
only to read the beginning of the file. To find the details of an implementation, he
can go from top to bottom in the file. On this path, he finds all the dependencies
of the functions simply by referring to the local declarations. If there are many
dependencies in a program, the number of local declarations can still increase in
unsustainable dimensions.

2. ’Bottom-up’ definition without declarations


The bottom-up definition starts at the bottom of the hierarchy: The main func-
tion is at the end of the file. Functions that deal with the details of the problem
are defined first.
130 10.3. Declaration and definition of functions

/* D e f i n i t i o n o f FB */
i n t FB ( i n t N, i n t M)
{
...
}

/* D e f i n i t i o n o f FA */
i n t FA( i n t X , i n t Y )
{
...
/* C a l l i n g FB */
J = FB ( 2 0 , 3 0 ) ;
...
}

/* D e f i n i t i o n o f main */
main ( )
{
...
/* C a l l i n g FA */
I = FA( 2 , 3 ) ;
...
}

Since the functions are defined before their call, the declarations can be left out.
This eases the text of the program a bit, but it is much more difficult to find the
dependencies between the functions.

3. Global declaration of functions and ’top-down’ definition


By declaring all functions globally at the beginning of the program text, we are
not forced to deal with the dependency between functions. This solution is the
simplest and safest for complex programs containing a large amount of depen-
dencies. It is still recommended to define the functions in the order of their
hierarchy.
Chapter 10. Functions 131

/* Global d e c l a r a t i o n o f FA and FB */
i n t FA ( i n t X , i n t Y ) ;
i n t FB ( i n t N, i n t M) ;

/* D e f i n i t i o n o f main */
main ( )
{
...
/* C a l l i n g FA */
I = FA( 2 , 3 ) ;
...
}

/* D e f i n i t i o n o f FA */
i n t FA( i n t X , i n t Y )
{
...
/* C a l l i n g FB */
J = FB ( 2 0 , 3 0 ) ;
...
}

/* D e f i n i t i o n o f FB */
i n t FB ( i n t N, i n t M)
{
...
}

Since the functions are defined before their call, the declarations can be left out.
This eases the text of the program a bit, but it is much more difficult to find the
dependencies between the functions.

4. Conclusions
In the following, we will use the ’top-down’ definition order that best reflects the
structure of a program. Since our programs do not contain many dependencies,
we will declare the functions locally in the calling functions.

Exercise 10.1 Consider the main, PI and AREA functions defined by:
132 10.4. Return a result

# i n c l u d e < s t d i o . h>

main ( )
{
double R ;
p r i n t f ( " Enter the r a d i u s o f the c i r c l e : " ) ;
s c a n f ("% l f " , &R ) ;
p r i n t f ( " Area = %f . \n " , AREA(R ) ) ;
return 0;
}

double PI ( void )
{
r e t u r n 3.14159265;
}

double AREA( double RADIUS )


{
r e t u r n PI ( ) * RADIUS*RADIUS ;
}

1. Establish the call hierarchy for the three functions.

2. Define the functions according to the three methods by adding the missing dec-
larations.

3. What messages does the compiler provide when a function is not defined or de-
clared before its call? How can these messages be explained?

10.4 Return a result


By definition, all functions provide a result of a type that we must declare. A function can
return a value of a simple type or the address of a variable or array.
To provide a result when leaving a function, we have the return command.
The instruction

r e t u r n <e x p r e s s i o n >;

has the following effects


• evaluation of the <expression>

• automatic conversion of the result of the expression into the type of the function

• return of the result


Chapter 10. Functions 133

• termination of the function

Example 10.11 The SQUARE function of the double type calculates and provides as
a result the square of a real provided as a parameter.

double SQUARE( double X)


{
r e t u r n X*X ;
}

We can define ourselves a function TAN which calculates the tangent of a real X us-
ing the functions sin and cos of the library <math.h>. In C, you must first include
the header file of the <math.h> library to be able to use the predefined sin and cos
functions.

# i n c l u d e <math . h>

double TAN( double X)


{
i f ( c o s (X) != 0 )
r e t u r n s i n (X) / c o s (X ) ;
else
p r i n t f ( " Error ! \ n " ) ;
}

If we assume the following statements,


double X , COT;
the calls of the functions SQUARE and TAN can be integrated in calculations or ex-
pressions:
p r i n t f ( " The square o f %f i s %f \n " , X , SQUARE(X ) ) ;
p r i n t f ( " The t a n g e n t o f %f i s %f \n " , X , TAN(X ) ) ;
COT = 1 / TAN (X ) ;

void In C, there is no special structure for the definition of procedures. We can however
use a void type function.

Example 10.12 The LINE function of the void type displays L stars in a line:
134 10.4. Return a result

void LINE ( i n t L )
{
/* D e c l a r a t i o n s o f l o c a l v a r i a b l e s */
int I ;
/* Treatments */
f o r ( I =0; I <L ; I ++)
printf ( " * " ) ;
printf ("\n " ) ;
}

main In our examples, the main function has no parameters and is always of type void /
int. Typically, programs return the zero value as an error code if they complete successfully.
Values other than zero indicate a faulty or abnormal stop.
In MS-DOS, the error code returned by a program can be checked using the IF ERRORLEVEL
command ...

If we leave a function (of a different type of void) without returning a result using return, the value passed to
the calling function is undefined. The result of such an action is unpredictable. If a fatal error has occurred
within a function, it is advisable to interrupt the execution of the entire program and return a non-zero
error code to the environment to indicate that the program is not running. is not finished normally.
Seen from this angle, it is dangerous to declare the TAN function as we did above: The case of a division
by zero, is well intercepted and reported by an error message, but the execution of the program continues
’normally’ with incorrect values.

exit To remedy this dilemma, we can use the exit function that is defined in the <stdlib.h> library. exit
allows us to interrupt program execution by providing an error code to the environment. In order to locate
the error within the program, it is advantageous to display an error message that indicates the nature of the
error and the function in which it occurred.

A more robust version of TAN would look like this:

# i n c l u d e <math . h>

d o u b l e TAN( d o u b l e X)
{
i f ( c o s (X) != 0)
r e t u r n s i n (X ) / c o s (X ) ;
else
{
p r i n t f ( " \ a F u n c t i o n TAN: \ n"
" E r r o r : D i v i s i o n by z e r o ! \ n " ) ;
e x i t ( − 1 ) ; / * E r r o r Code −1 * /
}
}
Chapter 10. Functions 135

Ignore the result When calling a function, the user is free to accept the result of a function
or to ignore it.

Example 10.13 The function scanf returns the number of correctly received data as a
result. In general, we ignore this fact:

i n t DAY, MONTH, YEAR ;


p r i n t f ( " Enter the c u r r e n t date : " ) ;
s c a n f ("%d %d %d " , &DAY, &MONTH, &YEAR ) ;

We can use the scanf result as a control:

i n t DAY, MONTH, YEAR ;


i n t RES ;
do
{
p r i n t f ( " Enter the c u r r e n t date : " ) ;
RES = s c a n f ("%d %d %d " , &DAY, &MONTH, &YEAR ) ;
}
while ( RES != 3 ) ;

10.5 Parameters of a function


Parameters or arguments are the ’mailboxes’ of a function. They accept data from outside
and determine the actions and the result of the function. Technically, we can summarize the
role of parameters in C as follows: The parameters of a function are simply local variables
that are initialized by the values obtained during the call.

Overview During a call, the number and order of the parameters must necessarily corre-
spond to the indications of the declaration of the function. The parameters are automatically
converted into the types of the declaration before being passed to the function.

Example 10.14 The prototype of the pow function (library <math.h>) is declared as
follows :
double pow ( double , double ) ;
During the instructions,
i n t A, B ;
...
A = pow ( B , 2 ) ;
we are seeing three automatic conversions:
Before being passed to the function, the value of B is converted to double; the value 2
is converted to 2.0. Since pow is of the double type, the result of the function must be
converted to int before being assigned to A.
136 10.5. Parameters of a function

void Of course, there are also functions that provide their results or perform an action
without the need for data. The list of parameters then contains the void declaration or it
remains empty (e.g. double PI(void) or int INPUT()).

Parameter passing by value In C, the passing of the parameters is always done by the
value, ie. the functions only get the values of their parameters and do not have access to the
variables themselves.
The parameters of a function are to be considered as local variables which are initialized
automatically by the values indicated during a call.
Inside the function, we can therefore change the values of the parameters without influenc-
ing the original values in the calling functions.

Example 10.15 The STARS function draws a line of N stars. Parameter N is modified
inside the function:

void STARS ( i n t N)
{
while (N>0)
{
printf ( " * " ) ;
N− −;
}
printf ("\n " ) ;
}

Using N as a counter, we do not need the auxiliary index I as in the LINES function
defined above.
The TRIANGLE function calls the STARS function using the variable L as parameter:

void TRIANGLE( void )


{
int L;
f o r ( L=1; L<10; L++)
STARS ( L ) ;
}

At the time of the call, the value of L is copied into N. The variable N can thus be
decremented inside STARS, without influencing the original value of L.
Schematically, the passage of parameters can be represented in a ’grid’ of values:
Chapter 10. Functions 137

Avantages Passing by value has the advantage that we can use the parameters as well-
initialized local variables. In this way, we need fewer variables.

Passing the address of a variable To be covered in second year!!

Passing the address of a one-dimensional array Since it is impossible to pass the ’value’
of an entire array to a function, the address of an element of the array is provided.
In general, we provide the address of the first element of the array, which is given by the
name of the array.
In the list of parameters of a function, we can declare an array by the name followed by
square brackets,

<type > <name > [ ]

Example 10.16 The strlen function calculates and returns the length of a string sup-
plied as a parameter:

i n t s t r l e n ( char S [ ] )
{
i n t N;
f o r (N=0; S [N] != ’ \ 0 ’ ; S++)
N++;
r e t u r n N;
}
138 10.5. Parameters of a function

Appel During a call, the address of an array can be given by the name of the array, by a
pointer or by the address of any element of the array.

Example 10.17 After the instruction,


char CH[ ] = " Bonjour ! " ;
we can call the strlen function defined above by:
s t r l e n (CH) /* r e s u l t : 9 */
s t r l e n (&CH[ 4 ] ) /* r e s u l t : 5 */
In the last call, we see that it is possible to supply part of an array to a function, using
the address of an element inside the array as a parameter.

For a function to work properly with a non-char array, you must also provide the array dimension or the
number of elements to be treated as a parameter, otherwise the function may exit the array domain.

Example 10.18 The READARRAY function reads N integers (one-dimensional array)


and stores them from the address indicated by the PTAB. PTAB and N are provided as
parameters

void READARRAY( i n t N, i n t PTAB [ ] )


{
i n t i =0;
p r i n t f ( " Enter %d v a l u e s : \n " , N ) ;
while (N)
{
s c a n f ("%d " , PTAB[ i + + ] ) ;
N− −;
}
}

In the function call we usually use the array name


LIRE_TAB ( 4 , T ) ;
We then obtain the following grids:

Passing the address of a two-dimensional array By analogy with what we saw in the pre-
vious section, we could consider declaring the array concerned in the header of the function
Chapter 10. Functions 139

in the form A[][]. In the case of a two-dimensional array, this method does not provide
enough data, because the compiler needs the second dimension of the array to determine
the address of an element A[i][j].
One practicable solution consists in making so that the function receives explicitly the ad-
dress of the first element of the matrix and of traversing all the elements as if it were an
array with a dimension N * M.
This leads us to this function:

# i n c l u d e < s t d i o . h>
main ( )
{
/* P r o t o t y p e o f the SUM f u n c t i o n */
f l o a t SUM( f l o a t A [ ] [ ] , i n t N, i n t M) ;
float T[3][4] = {{1 , 2 , 3 , 4} ,
{5 , 6 , 7 , 8} ,
{9 ,10 ,11 ,12}};
p r i n t f ( " Sum o f elements : %f \n " ,
SUM( T , 3 , 4 ) ) ;
return 0;
}

f l o a t SUM( f l o a t A [ ] [ ] , i n t N, i n t M)
{
int I ;
float S ;
f o r ( I =0; I <N*M; I ++)
S += A[ I ] [ J ] ;
return S ;
}

10.6 Functions / modules in C

In C, there are only functions. The main function is distinguished from other functions by
two qualities:

1. It is executed when the program is called.

2. The types of the result (int) and the parameters (void) are fixed.

In C, it is forbidden to define functions inside other functions, but we can declare func-
tions locally.
140 10.6. Functions / modules in C

In C, it is allowed (but not recommended) to declare local variables at the beginning of


each block of instructions.

In C, the global variables are defined at the beginning of the file, outside of all the func-
tions. (main function variables are local to main.)

In C, the parameters are always passed by value. To be able to change the content of a
variable declared in another function, you must use a pointer as a passing parameter and
transmit the address of the variable during the call.
Chapter 10. Functions 141

Computer Exercises
Simple types
Exercise 10.1 Write a program using a float type AVERAGE function to display the
arithmetic mean of two real numbers entered on the keyboard.

Exercise 10.2 Write a function EXP that calculates the value X N for a real value X
(double type) and a positive integer value N (type int): :

1. EXP returns the value X N as result.

Write a program that tests the function using values read from the keyboard.

Exercise 10.3 Write a MIN function and a MAX function that determine the minimum
and maximum of two real numbers.
Write a program using the MIN and MAX functions to determine the minimum and
maximum of four real numbers entered on the keyboard.

Exercise 10.4 Write a program using an F function to display the table of values of

the function defined by f (x) = sin(x) + ln(x) − x where x is an integer between 1 and
10.

Exercise 10.5 Write the NUM function of the type int which obtains an integer value
N (positive or negative) of the long type as a parameter and which gives the number of
digits of N as a result.
Write a small program that tests the function NUM:
Example:
Enter an i n t e g e r number : 6457392
The number 6457392 has 7 d i g i t s .

Exercise 10.6 In mathematics, we define the factorial function as follows:


0! = 1
n! = n*(n-1)*(n-2)* ... * 1 (for n>0)
Write a FACT function of the double type which receives the value N (type int) as a
parameter and which provides the factorial of N as a result. Write a small program
that tests the FACT function.

Exercise 10.7 Write a program that builds and displays Pascal’s triangle by calculating
the binomial coefficients:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
142 10.6. Functions / modules in C

. . .
We will not use an array, ie. it will be necessary to calculate the coefficients according
to the formula below, while defining and using the adequate functions.

q p!
Cp =
q!(p − q)!

Exercise 10.8

1. Write a function int MAX (int a, int b) which returns the maximum of 2 integers;

2. Test the MAX function using a simple instruction.

3. Write a main function that enters N integers, asks the user to enter N integers
and calculates their maximum using the MAX function (without using a table!)

Exercise 10.9

1. Write a function that tests if an integer is ABUNDANT (returns 1 if yes and 0


otherwise). The integer n is abundant when the sum of its divisors (including n
itself) is greater than its double (2n). Example: 12 is abundant (1 + 2 + 3 + 4 + 6
+ 12> 24)

2. Test the function using a simple instruction;

3. Write a main function that takes 2 integers a and b and then displays the abun-
dant numbers in the interval [a, b].

One-dimensional arrays
Exercise 10.10 The function READARRAY with 2 parameters TAB and NMAX reads
and returns the dimension N and the components of an array TAB of the type int.
The dimension N must be less than NMAX. Implement the function READARRAY by
choosing the type of the parameters.
Example: For a call by
N=READARRAY( T , 1 0 ) ;
the function will behave as follows
Size of the a r r a y ( max . 1 0 ) : 11
Size of the a r r a y ( max . 1 0 ) : 4
Element [0]: 43
Element [1]: 55
Element [2]: 67
Element [3]: 79
Chapter 10. Functions 143

Exercise 10.11 Write the DISPLAYARRAY function with two parameters TAB and N
which displays N components of the array TAB of the type int.
Example: The array T read in the previous exercise will be displayed by the call:
DISPLAYARRAY( T , N ) ;
and will be presented as follows:
43 55 67 79

Exercise 10.12 Write the function SUMARRAY which calculates the sum of the N
elements of an array TAB of the type int. N and TAB are provided as parameters; the
sum is returned as the result of the long type.

Exercise 10.13 Using the functions of the previous exercises, write a program that
reads an array A with a dimension less than or equal to 100 and displays the array and
the sum of the elements of the array.

Exercise 10.14 Write a function that returns the average of the grades given in an
array.

Exercise 10.15

1. Write the function prime that checks if a number is prime or not. The function
returns 1 if the number is prime and 0 otherwise.

2. Write a function ReadArray that allows to read the value of an array of size M.
All the elements of the array should be between 10 and 100.

3. Write a main program that declares two arrays of maximum size 20. The program
should prompts the user for the effective arrays size (should be positive), read
their values using the function and then it checks if the two arrays contain the
same number of prime numbers.

Exercise 10.16

1. Write a function ArrayEqual that takes two arrays A1 and A2 of the same size
and checks if the two arrays are equal. Two arrays are equal when their same
position elements are equal.
Example:
A1 = 2,4,5,1 and A2 = 2,4,5,1 are equal
A1 = 2,4,5,1 and A2 = 2,1,4,5 are NOT equal

2. 2. Write a function ArrayReverse that takes two arrays A1 and A2 of the same
size and put the elements of A1 in A2 in reverse order.
Example: if A1 = 2,4,5,1 –> A2 = 1,5,4,2
144 10.6. Functions / modules in C

3. 3. Using the two previous functions, Write a function ArraySymmetric that takes
an array A and checks if it is symmetric. An array is symmetric if it is mirrored
according to its middle (if you read it from the end, you will have the same values
as when you read it from the beginning)
Example: array A1 = 1,2,2,1 and A2 = 1,2,3,2,1 are symmetric.

Arrays sorting
Exercise 10.17 Determine the maximum of N elements of a TAB array of integers in
two different ways:

1. MAX1 function returns the maximum value

2. the MAX2 function returns the index of the maximum element

Write a program to test the two functions.

Exercise 10.18 Write the INSERT function which places an X element inside an array
that contains N elements sorted in ascending order, so as to obtain an array with N + 1
elements sorted in ascending order. The dimension of the array is incremented in the
INSERT function.
Write a program that takes advantage of the previously written functions to test the
INSERT function.

Exercise 10.19 Write the FUSION function that constructs a FUS array sorted in as-
cending order with the elements of two arrays A and B sorted in ascending order. For
two arrays of dimensions N and M, the array FUS will have the dimension N + M.
Write a program that tests the FUSION function using two arrays read from the key-
board and sorted using any sorting algorithm.

Strings
Exercise 10.20 Write the function LENGTH which returns the length of a string of
characters CH as result.

Exercise 10.21 Write the UPPER function that converts all letters in a string to up-
percase.

Exercise 10.22 Write the function ADD having as parameters STR1 and STR2 which
copies the string STR2 to the end of the string STR1.

Exercise 10.23 Write the REVERSE function which reverses the character order of a
string.
Chapter 10. Functions 145

Exercise 10.24 Write the function NWORDS which returns as result the number of
words contained in a string of characters. Use a logical variable, the function isspace
and a helper variable N.

Exercise 10.25 Write the function EQUAL_N which returns the value 1 if the first N
characters of STR1 and STR2 are equal, otherwise the value 0. (If N is greater than the
length of STR1 or STR2, the result can be 1 or 0).

Exercise 10.26 Write a function char encrypt (char c, int k) that encrypts a character
as follows: if c is an alphabetic character, shift c by k to the right (+ k) otherwise shift
c by k to the left (-k).
Write a main function that tests the function.

Exercise 10.27 1. Write a function digitname that takes a digit and displays its
name in uppercase letters; for example if the digit is 4, the function displays
FOUR.

2. Write a C program that reads a positive integer n, and calls the above function to
display the digits of n as shown in the following above.

Exercise 10.28 Write a function called nbrofWords that has an array of characters as
parameter (string). This function must return the number of words in this string with-
out considering spaces. We suppose that the string is composed of words separated by
single blank space.
Test this function in the main function.

Two-dimensional arrays
Exercise 10.29 Write the function READ_MATRIX taking 3 parameters MAT, R, and
C which reads the components of a matrix MAT of the type int and dimensions R and
C.

Exercise 10.30 Write the function WRITE_MATRIX with 3 parameters MAT, R, and
C which displays the components of the matrix of dimensions R and C.

Exercise 10.31 Write the function SUM_MATRIX of the long type which calculates
the sum of the elements of a MAT matrix of the type int. Choose the necessary param-
eters. Write a small program that tests the function SUM_MATRIX.

Exercise 10.32 Write the function ADDITION_MATRIX which carries out the addi-
tion of the matrices following: MAT1 = MAT1 + MAT2
Choose the necessary parameters and write a small program that tests the function
ADDITION_MATRIX.
146 10.6. Functions / modules in C

Exercise 10.33 Write the MULTI_MATRIX function which multiplies the matrix
MAT1 by an integer X: MAT1 = X * MAT1
Choose the necessary parameters and write a small program that tests the
MULTI_MATRIX function.

Exercise 10.34 Write the function MULTI_2_MATRICES which performs the multi-
plication of two matrices MAT1 (dimensions R and P) and MAT2 (dimensions P and
C) in a third matrix MAT3 (dimensions R and C): MAT3 = MAT1 * MAT2
Suppose that the maximum dimensions of the three matrices are all equal to 30 rows
and 30 columns. Write a small program that tests the MULTI_2_MATRICES function.

Recursion
Exercise 10.35 Write a program that takes as input two positive integers A and B,
then calls a recursive function that finds the product of A by B using the Egyptian
method. The Egyptian method rules are:

• If B=0 then A*B=0

• If B is even then A*B = (2*A) * (B/2)

• If B is odd then A*B = A * (B-1) + A

Exercise 10.36 The Fibonacci sequence is a sequence of numbers where the first two
numbers in the sequence are 1 and 1. Then, each additional Fibonacci number is the
sum of the two previous numbers in the sequence: 1, 1, 2, 3, 5, 8, 13, 21...
U1 = 1, U2 = 1
Un = Un−1 + Un−2 for n> 2
Write a program that reads an integer N, and then calls a recursive function that cal-
culates the value number N of the Fibanacci sequence. At the end, the program prints
out the value on the screen.
Execution example :
Enter an integer : 9
The integer number 9 in the Fibonacci sequence is 34
Chapter 10. Functions 147

Additional Exercises

Exercise 10.37 The purpose of this application is to encrypt an integer number into
a text message (string).
The following replacements of digits should be made in the encryption process:
0 →0 a0 , 1 →0 b0 , 2 →0 c0 , 3 →0 d 0 , 4 →0 e0 , 5 →0 f 0 , 6 →0 g 0 , 7 →0 h0 , 8 →0 i 0 , 9 →0 j 0 .

1. Write the function voidEnCrypt(intn, charEncr[]) that generates the encrypted


value of n in the string Encr (Ex: if n = 1092 then Encr = “bajc”).

2. Write a main program that prompts the user to enter an integer value and print
the equivalent encryption string.

Exercise 10.38

1. Write a function Reduction that takes a string S and eliminates from S every se-
quence of 3 or more consecutive occurrences of the same character. The function
returns 1 if it finds at least one sequence to eliminate from S and 0 if no sequence
to eliminate.
Ex: If the string S is “aabbbacdddddf”, then after calling the function S becomes
“aaacf” and the function returns -1.
If the string S is “aabcabbdf”, then after calling the function S remains “aab-
cabbdf” and the function returns 0.

2. Write a function RecReduction that takes a string S and recursively calls the
function Reduction while there are at least one sequence to eliminate from S.
If the string is “aabbbacdddddf” then after calling the function the string be-
comes “cf”

Exercise 10.39 Consider the following sequence defined by:

2
Un−1 if

n is an even number
U0 = 1; Un =
Un−1 + n! if n is an odd number

1. Write a function that takes an integer n as parameter, and returns the corre-
sponding value of Un .

2. Write a function that takes as parameter an integer X, and prints the greatest
value of n such that Un ≤ X

Exercise 10.40

1. Write the function « int Prime(int a) » that verifies if an integer « a » is a prime


number or not.

2. Write the function « int NextPrime (int a) » that returns the smallest prime num-
148 10.6. Functions / modules in C

ber greater than « a ».


Example: NextPrime(9) should return 11.
NextPrime(11) should return 13.

3. 3. Two consecutive odd numbers that are both prime numbers are called « twin
prime numbers ». Using the two functions of parts 1 and 2, write a C program
that prints all the twin prime numbers that are < 1000. For example, the first 5
lines of the program output should be :
35
57
11 13
17 19
29 31
............

Exercise 10.41 The objective of this exercise is to propose a new algorithm to check if
a word (string without spaces) is palindrome.

1. Write the function "firstlast" that takes as parameter a word (a string without
spaces) and construct a new string by regrouping the characters as follows : the
first and the last, the second and before the last, and so one. Example : abcdefg
–> agbfced

2. Notice that if the previous function is applied on a palindrome word (example:


laval –> llaav), the generated string is composed of a pair of identical characters
(except the last character if the original string length is odd). Write the func-
tion "isPalindrom" that verifies if a word string is palindrome, using the function
"firstlast".

3. Write a main program that prompts the user to enter a string and verifies if it is
or not, using the previous functions.

Exercise 10.42 Let the mathematical function f defined by

(2x3 + 3)(x2 − 1)
f (x) = √
3x2 + 1
1. Write a C function that returns the value of f (x) for a point x passed as a param-
eter.
2. 2. An approximation of the derivative f’ of the function f is given in each point x
f (x+h)−f (x)
for h small enough (close to 0), by: f 0 (x) ' 2h
Write a function C that calculates an approximation of the derivative f’ of f at a
point x entered on the keyboard. We will pass the value of h as a parameter of
the function.
3. The second derivative of f is the derivative of the derivative. Write a function
C that calculates an approximation of the second derivative f” of f at a point
x entered on the keyboard. We will pass the value of h as a parameter of the
function.
Chapter 10. Functions 149

4. Write a C function that determines the sign of the second derivative of f as a


function of x. We can make a main program that reads x on the keyboard and
displays the result.

5. Write a C function that gives the user the choice to display the value of the func-
tion f, its first derivative or its second derivative at a point x read from the key-
board.

Exercise 10.43 A point is defined by its real coordinates (X, Y). The purpose of this
program is to allow the user to enter N distinct points, calculates and prints the small-
est distance between any two points of the sequence. Two arrays should be used to
store the points’ coordinates: X[N] (for points’ abscissa) and Y[N] (for points’ ordi-
nate) as shown in the example bellow.
Example: if N = 4, and the 4 distinct points are (1,2); (3, -2); (11, 2); (9,3), then the two
arrays X and Y will be as following:
X: 1 3 11 9
Y: 2 -2 2 3

1. Write the function intFindInRange(f loatA[], intM, f loatv), that checks if the
value v appears in the first M elements of the array A.

2. Write the function voidReadDistinctP oints(f loatX[], f loatY [], intN ), that
prompts to enter the coordinates X and Y of N distinct points: Any new entered
point that has been already entered in the sequence of points should not be
considered (Hint: use the function FindInRange).

3. Write a main program that asks the user to enter N distinct points (by storing
their coordinates in two arrays X and Y), calculates and prints the smallest dis-
tance between two points of the sequence of points.

Note:

• p
the distance between two points A(x1 , y1 ) and B(x2 , y2 ) is equal to d =
(x2 − x1 )2 + (y2 − y1 )2

• The use of the library math.h is allowed.

Exam questions

Exercise 10.44 (Section I - Session 1 2018-2019)

1. Write the function int READDIM() that reads and returns a strictly positive inte-
ger less than 50;
2. Write the function void READARRAY(int Arr[], int N) that reads N positive
integers of the array Arr;
3. Write the function void SORT(int Arr[], int N) that sorts in increasing order
150 10.6. Functions / modules in C

the array Arr;

4. Write the function int Kth(int Arr[], int N, int k) that returns

• the kth element of the array Arr if it exists ;


• -1 if it doesn’t;

5. Using all the above written functions, write a main function that displays the
kth largest element in an array (maximum size 50) of positive integers.

Running example:

Exercise 10.45 (Section I - Session 2 2018-2019)

1. Write the function int READDIM() that reads and returns a strictly positive inte-
ger less than 50;

2. Write the function void READARRAY(int Arr[], int N) that reads N integers of
the array Arr;

3. Write the function void DISPLAY(int Arr[], int N) that displays N integers
of the array Arr;

4. Write the function void REVERSE(int Arr[], int N, int M) that reverses the
order of appearance of the elements of the array Arr that are in position multiple
of M;

5. Using all the above written functions, write a main function that reads the ef-
fective dimension N of an array by calling READDIM, then fills the array using
READARRAY, then displays the array using DISPLAY, then reads a positive integer
M strictly less than N , then reverses the elements of the array that are in position
multiple of M using REVERSE, then displays the array using DISPLAY.

Running example:
Chapter 10. Functions 151

Potrebbero piacerti anche