Sunteți pe pagina 1din 267

Adriana ALBU

EDITURA

CONSPRESS

2013

Copyright 2013, Editura Conspress


EDITURA CONSPRESS
este recunoscut de
Consiliul Naional al Cercetrii tiinifice din nvmntul Superior

Lucrare elaborat n cadrul proiectului: "Reea naional de centre pentru


dezvoltarea programelor de studii cu rute flexibile i a unor instrumente
didactice la specializarea de licen i masterat, din domeniul Ingineria
Sistemelor"

Descrierea CIP a Bibliotecii Naionale a Romniei


ALBU, ADRIANA
Computer programming: the C language / Adriana Albu
Bucureti : Conspress, 2013
Bibliogr.
ISBN 978-973-100-270-5
681.3
Colecia Carte universitar

CONSPRESS
B-dul Lacul Tei nr 124, sector 2
cod 020396, Bucureti
Tel: (021) 242 2719 / 300; Fax: (021) 242 0781

To my Grandparents

Contents
Introduction .......................................................................................................... 9
Chapter 1 Programming basics .......................................................................... 11
Chapter 2 Logical diagrams ............................................................................... 15
2.1 The elements of a logical diagram ........................................................... 15
2.2 Solved problems....................................................................................... 20
2.3 Questions and exercises ........................................................................... 24
Chapter 3 Data and data types ........................................................................... 30
3.1 General concepts ...................................................................................... 30
3.1.1 Data types.......................................................................................... 31
3.1.2 Variables ........................................................................................... 34
3.1.3 Constants ........................................................................................... 34
3.1.4 Operators ........................................................................................... 35
3.1.5 Expressions ....................................................................................... 38
3.2 Data types description .............................................................................. 41
3.2.1 The integer type ................................................................................ 41
3.2.2 The real type ..................................................................................... 43
3.2.3 The char type..................................................................................... 43
3.2.4 The logical type................................................................................. 44
3.2.5 The void type .................................................................................... 45
3.2.6 Type casting ...................................................................................... 45
3.3 Questions and exercises ........................................................................... 46
Chapter 4 A first C program .............................................................................. 50
4.1 Stages of a C program implementation .................................................... 50
4.2 The structure of a C program ................................................................... 51
4.3 Possible errors .......................................................................................... 55

Computer Programming The C Language


4.4 Questions and exercises ........................................................................... 56
Chapter 5 Library functions ............................................................................... 59
5.1 Input/output functions .............................................................................. 59
5.2 Mathematical functions ............................................................................ 67
5.3 Conversion functions ............................................................................... 70
5.4 Other functions......................................................................................... 71
5.5 Questions and exercises ........................................................................... 74
Chapter 6 Instructions ........................................................................................ 78
6.1 Simple instructions................................................................................... 79
6.1.1 The assignment instruction ............................................................... 79
6.1.2 The function call ............................................................................... 80
6.2 Alternative instructions ............................................................................ 80
6.2.1 The if instruction ............................................................................ 81
6.2.2 The switch instruction ................................................................... 85
6.3 Repetitive instructions ............................................................................. 90
6.3.1 The for instruction .......................................................................... 90
6.3.2 The while instruction ..................................................................... 95
6.3.3 The do while instruction .............................................................. 99
6.4 Solved problems..................................................................................... 101
6.5 Questions and exercises ......................................................................... 107
Chapter 7 Arrays .............................................................................................. 113
7.1 Single-dimensional arrays ...................................................................... 113
7.1.1 Declaring a single-dimensional array ............................................. 114
7.1.2 Accessing elements ......................................................................... 114
7.1.3 Initialization of elements................................................................. 115
7.1.4 Reading the elements values from the keyboard ........................... 115
7.1.5 Displaying the elements / Traversing an array ............................... 116
6

Contents
7.1.6 A complete example ....................................................................... 116
7.2 Two-dimensional arrays......................................................................... 117
7.2.1 Declaring a two-dimensional array ................................................. 117
7.2.2 Accessing elements ......................................................................... 118
7.2.3 Initialization of elements................................................................. 118
7.2.4 Reading the elements values from the keyboard ........................... 119
7.2.5 Printing a matrix ............................................................................. 119
7.2.6 Traversing a matrix ......................................................................... 120
7.2.7 Particular ways of traversing a square matrix ................................. 121
7.2.8 A complete example ....................................................................... 124
7.3 Solved problems..................................................................................... 125
7.4 Questions and exercises ......................................................................... 131
Chapter 8 Strings.............................................................................................. 135
8.1 Characters .............................................................................................. 135
8.2 Strings .................................................................................................... 137
8.3 Questions and exercises ......................................................................... 145
Chapter 9 Pointers ............................................................................................ 149
9.1 Pointer variables..................................................................................... 149
9.2 Operations with pointers ........................................................................ 151
9.3 Pointers and other elements ................................................................... 153
9.4 Questions and exercises ......................................................................... 156
Chapter 10 User-defined functions .................................................................. 158
10.1 User-defined functions ......................................................................... 159
10.1.1 The prototype of a function........................................................... 159
10.1.2 The description of a function ........................................................ 160
10.1.3 The call of a function .................................................................... 163
10.1.4 The scope of variables .................................................................. 169
7

Computer Programming The C Language


10.1.5 Changing the arguments of a function .......................................... 174
10.1.6 Passing arrays as arguments.......................................................... 176
10.2 Recursion ............................................................................................. 178
10.3 Solved problems................................................................................... 180
10.4 Questions and exercises ....................................................................... 189
Chapter 11 User-defined types......................................................................... 196
11.1 The structure ........................................................................................ 196
11.1.1 Definition and use ......................................................................... 196
11.1.2 Structures and functions ................................................................ 203
11.1.3 Arrays of structures ....................................................................... 206
11.1.4 Pointers to structures ..................................................................... 207
11.2 The enumeration .................................................................................. 209
11.3 Questions and exercises ....................................................................... 211
Chapter 12 Files ............................................................................................... 217
12.1 File handling ........................................................................................ 217
12.1.1 File opening .................................................................................. 218
12.1.2 File closing .................................................................................... 220
12.1.3 File input/output actions ............................................................... 221
12.1.4 Repositioning the file pointer........................................................ 227
12.1.5 File renaming and removing ......................................................... 231
12.2 A complete example ............................................................................ 233
12.3 Questions and exercises ....................................................................... 243
Appendix 1 The set of characters (together with their ASCII codes) .............. 248
Appendix 2 The keywords of the C programming language ........................... 250
Appendix 3 Answers to questions and exercises ............................................. 253
References ........................................................................................................ 263

Introduction
Communication has become a widely used concept over the last decades, playing an important role in all activities. People communicate using words or
signs when they want to do something together, when they need to interact or
to transmit information, feelings and so on. Such a way of communication is
also required between humans and computers. A programming language is used
in order to transmit to a computer how to perform a special task. Similar to the
languages used in human communication, a programming language consists of
words, sentences and well defined syntactical rules. In a programming language, the sentences are combined so that the program is able to provide the
communication between human and computer. Without programs, a computer
is nothing. On the other hand, a person that is able to write such programs has a
lot of advantages over those who know only to use computers and their applications.
This handbook is easy to read, fast and efficient, being useful to the students
who try to become familiar with programming issues. Those who will use this
book in their training process as software developers (including the design, not
only the implementation) will have the opportunity to become competent in the
programming domain, because the offered items lead to acquiring knowledge
and skills appropriate to this area.
Therefore, the book is designed especially for those who made the first steps in
programming and offers characteristics that lead to learning the C programming
language (a strong, portable and popular language, used to develop applications
in various domains). Some of the basic concepts of programming are discussed
before presenting the specific aspects of the C language. Therefore it will be
much easier to learn and to use other programming languages, because the
knowledge base about structured programming already exists.
This book is carefully split into chapters. The programming concepts are gradually presented, in a natural order, so that the connection between a newly introduced notion and the previous notions is very clear and that the learning of a
new notion is made on the basis of the already explained concepts. This way, a
fast understanding and assimilation of the presented elements is guaranteed.
The first two chapters depict general aspects, which apply to all programming
languages. Several basic notions of this domain are presented in the first chapter. The second chapter shows a graphic way of solving problems through

Computer Programming The C Language


logical schemes. Then, specific elements of the C programming language are
described, starting with data and data types (the third chapter) and continuing
with a first C program (the forth chapter). The next two chapters provide the
programmer library functions (the fifth chapter) and instructions (the sixth
chapter) available in C programming language. The seventh chapter presents
the array management, emphasizing the single-dimensional and the twodimensional arrays. In C language, strings (presented in the eighth chapter) are
a particular case of single-dimensional arrays. The C programming language
description continues with pointers characteristics (the ninth chapter). Then
follow two chapters that describe how programmers can split programs into
functions (the tenth chapter) and how they can define their own data types (the
eleventh chapter). In the end, the file handling in C language is presented (the
twelfth chapter).
Throughout all these chapters the theoretical aspects are presented simply and
clearly, allowing the reader to quickly understand the discussed elements. The
chapters also contain a large number of examples accompanied by comments
and explanations, which are intended to support the theoretical part. Examples
are mostly whole programs (not just isolated fragments) and were tested before
being placed in the text.
Those who will use this book will also have the possibility to verify their acquired knowledge, because each chapter (except for the introductory one) is
ending with a set of questions and requirements, generally divided into four
categories. The first category of questions focuses on identifying errors; several
sequences of code with errors that must be found are presented. In the following
category of questions the reader has to specify the result of some expressions,
logical diagrams or sequences of code. Then comes a set of multiple choice
questions about the content of the chapter; these questions cover both theoretical and practical elements (expressions, sequences of code). The last appendix
of the book provides answers and explanations to the questions in these first
three categories. The review ends with some problems that involve writing
entire programs. Answers to these problems are not provided in the book, the
reader having to find himself a solution.
This book can be covered and understood without the help of an expert because
of the clarity of the theoretical aspects and because of the multitude of explained examples, solved problems and answered questions. All those who are
interested into the programming world will find this book a real help.

10

Chapter 1
Programming basics
The computer is able to execute different operations and to offer solutions for a
huge number of problems that have to be solved with its help. It only needs to
be programmed as such. In other words, the computer executes everything it is
asked for, with the imperative condition that it understands what the requirements are. Therefore, a certain means of communication between human
and computer is needed, and this means is the programming languages.
The concepts presented in this book are meant to facilitate the transmission of
basic informatics and structured programming knowledge to those who are at
the beginning of this road. The book can also be useful to those who have some
experience in this domain, helping them to consolidate and to organize the
knowledge they already have.
Information is a widely used concept, lately; its meanings are closely related to:
control, communication, perception, data, knowledge, representation, patterns.
In the computer world data and knowledge are not relate strictly to the word
information; they are connected to this word, heaving also specific significations. Thus, data represents the raw material. After being processed, data becomes information, which is interpreted (given a special meaning) and therefore
becomes knowledge. Figure 1.1.1 is a suggestive graphical representation of the
connection between these three notions that can create a pyramidal shape based
on data (the largest amount), consolidated by information (in the middle of the
pyramid) and crowned by knowledge.

KNOWLEDGE

INFORMATION

DATA
Figure 1.1.1 Pyramidal representation of data, information, and knowledge

Computer Programming The C Language


For instance, symptoms and laboratory tests results of a patient can be considered as data; e.g. the white blood cells level is very high for that patient. The
information can be that a white blood cells level that is higher than a specified
value can lead to leukemia (this requires a processing of initial data by comparing it to a threshold). Finally, knowledge consists in specifying that the patient
is in danger.
At a basic level, the computer processes data. The programmers task is to
design and to develop programs that determine the computer to take the raw
data and to transform it into information with a special meaning for the user.
Closely related to information is another concept: informatics the science that
studies information processing using automatic systems [DEX98]. Other definitions also show that informatics supposes data acquirement, storage, handling,
and classification. It studies the structure, the behavior and the interactions
between systems that store, process and communicate information. This leads to
another concept, frequently dealt with lately, communication. Communication
between people is realized by a language that contains of expressions, signs,
gestures. But it is impossible to communicate anything to a computer without
knowing a language that can be understood by that computer (this means a
programming language).
The Central Processing Unit (CPU) is responsible for solving all problems, but
it doesnt understand any human language. It accepts only so called machine
code instructions, which are written using binary digits only 0 and 1, therefore
transforming programming into a very laborious process. For this reason, some
sort of abbreviations were invented (formed by few letters) for the machine
code instructions. Therefore the assembly language appeared. Even so, the
simplest operations were written with difficulty and involved passing through
several steps.
The repetition of some operations was then noticed. Small separated programs
were written for these operations. After that, a new idea emerged: to create a
programming language formed of these small programs that received suggestive
names. Thus, a problem could have been solved using English words. Obviously, programming became easier and more attractive. This kind of languages
have a high level of abstraction (compared to the assembly language), thus they
are called high level languages. The first high level languages were COBOL
and FORTRAN, followed by Basic, Pascal, Lisp, C, and others.

12

1 Programming basics
The C programming language was invented by Dennis RITCHIE in 1972.
Although many years have passed since then, this language is still widely used
because of its advantages [CH96], [GP00]:
it is a high level language (it can be easily used thanks to its syntax); nevertheless, it provides the power and the flexibility of a machine language because it maintains some features of an assembly language;
it is highly efficient, being created for writing the operating systems (its a
programming language projected by the UNIX operating systems programmers [BK03]);
it is strong; the C programs can produce a large number of computations in
a few steps;
it is succinct due to the use of a large number of operators (some of them
are mathematical operators, others replace particular commands;
it is portable (can be installed on many different computers);
it is popular because of its force and its portability, being used by an impressive number of programmers;
it is in permanent development, being the subject of additions and extensions.
All these characteristics make the C programming language a language that any
programmer must know. Using the tools of the C language, the development of
the programs can be done in an efficient way, resulting high quality final products.
The features of the C programming language allow and encourage structured
programming. This kind of programming is based on a theorem, which states
that any algorithm can be implemented using only three control structures
(figure 1.1.2):
sequence first an entity of a program is executed, and then the next entity;
in other words, parts of a code sequence are executed one after another,
without jumps over certain parts (figure 1.1.2 a);
selection only one of two alternatives is executed, based on the value of a
condition (figure 1.1.2 b);
iteration an entity of a program is repeatedly executed as long as a condition is true (figure 1.1.2 c).
13

Computer Programming The C Language

a) Sequence

b) Selection

c) Iteration

Figure 1.1.2 The three control elements that support the structured programming

Solving a problem actually involves implementing an algorithm; this means


following a number of well-defined steps that must be executed so that the
problem is solved. In order to do this, there are three stages that need to be
accomplished (also represented in figure 1.1.3):
problem analysis, in order to exactly determine the original data and the
requirements;
problem representation, in an appropriate manner so that computer can be
able to solve it;
implementation, meaning the writing of a program (using a programming
language) in order to solve that problem.
Analysis

Representation

Implementation

Figure 1.1.3 Problem solving phases

Even though the implementation, the last phase of the problem solving process,
seems to be the most important, the other two phases are not to be neglected
either. The preliminary analysis of the input data and of the requirements is
essential for finding a correct solution. It is also very important to create a wellstructured program and an explicit flow of executed elements. In order to provide a correct solution for a problem, it is recommended to have a graphical
representation of the algorithm that is being used. This is achieved using some
elements that form a so-called logical diagram. Each step that is executed to
solve a problem is represented by an image with a geometric aspect and a short
text that explains what has to be done in that certain step. Details regarding the
graphical representation of a problem can be found in the chapter that presents
the logical diagrams.
14

Chapter 2
Logical diagrams
2.1 The elements of a logical diagram
First steps in structured programming will be made using logical diagrams, a
very good method to improve the reasoning. The logical diagrams are not connected to a specific programming language. They are graphical representations
of programs, providing an explicit idea about them. A logical diagram is the
simplest way of expressing an algorithm. If a graphical representation of that
algorithm is available, then the program that has to implement it will be easily
written.
The logical diagrams might seem archaic. Nevertheless, they are essential when
a program is developed, being very useful, especially for the beginners in programming. It is said that an image is worth a thousand words; the logical diagrams are exactly the image of a program. Writing the program, after its graphical representation is made, is only routine work [GP00].
A logical diagram is made by several graphical symbols; any algorithm can be
represented using these symbols. The elements that can be used in a logical
diagram are hereby presented.
The START element marks the beginning of the program:

START

The STOP element marks the end of the program:


STOP

These two elements define exactly where the graphical representation of a


program begins and where it ends. This cancels any questions regarding the
delimitation of logical diagrams.
The output element is used to display the results:
For example:

Write a

Computer Programming The C Language


The logical diagram of a first program can be made by using these three elements; it displays the message This is my first program (figure 2.1.1). As can be seen, the diagram contains an output element (which prints
the message) and the two elements that mark the beginning and the end of the
program.
START

Write This is my
first program

STOP
Figure 2.1.1 A logical diagram that uses the output element

The input element is used for data reading.


For example:

Read a

The logical diagram from figure 2.1.2 uses the input element to read the name
of a person; that name is then displayed with an output element.
START

Read name

Write The name is:


name

STOP
Figure 2.1.2 A logical diagram that uses the input and the output elements

16

2 Logical diagrams
The processing element executes operations and it is used when the data is
processed (computations or assignments):

For example:

b=2*a

A lot of problems can be solved by using the processing element. The following
logical diagram calculates the sum and the product of two numbers (figure 2.1.3). An input element is used to read the numbers. Then, in a processing
element, the sum and the product are calculated. These are displayed at the end
of the diagram with an output element.
START

Read a,b

sum=a+b
product=a*b

Write sum, product

STOP
Figure 2.1.3 The logical diagram for calculating the sum and the product of two numbers

Even more complex problems can be solved with the processing element. For
example, the first degree equation: ax+b=0. First, two numbers a and b,
representing the coefficients, are read. Then, the x value is calculated and displayed. The figure 2.1.4 presents a first version of logical diagram that solves
the first degree equation.

17

Computer Programming The C Language

START

Read a,b

x=-b/a

Write x

STOP
Figure 2.1.3 Logical diagram for solving the first degree equation (the first version)

As it can be seen, this logical diagram created to solve the first degree equation
has a drawback: it doesnt cover the case where the a coefficient is zero (in
which case the division cannot be executed). From the mathematical point of
view, the equation ax+b=0 is solved as follows:
The value of the a coefficient is verified:
if a is not zero, then x=b/a;
else, the equation becomes b=0 and the value of the b coefficient must be
verified:
o if b is not zero, then the expression b=0 is false, so no solutions for
the unknown variable x;
o if b is zero, then the expression b=0 is true and any real number is
solution for the equation (this means that the unknown variable x
has an infinite number of solutions).
In order to solve this problem, another element is necessary: the one given
below.
The decisional element evaluates conditions and it is used when a decision
must be made based on two alternatives. The element has to contain a question
with two possible answers: yes or no.
18

2 Logical diagrams

For example
NO

YES

NO

a0

YES

The first degree equation can now be correctly solved using the decisional
element and the algorithm described above. The logical diagram presented in
figure 2.1.5 follows exactly the stages of this algorithm.
START

Read a,b

NO

YES

a0
NO

x=-b/a

YES

b0
Write x
Write No solutions
Write Infinite number
of solutions

STOP

Figure 2.1.5 Logical diagram for solving the first degree equation (the second version)

19

Computer Programming The C Language

2.2 Solved problems


The logical diagrams are a simple, explicit way of representing an algorithm
and of solving a problem, being very useful to those who make their first steps
in the structured programming. These graphical elements are an excellent tool
that can be used to improve the reasoning when the method to solve a problem
is searched. In the following examples, solutions for several other problems are
suggested in order to complete the description of logical diagrams.
2.2.1 First, it is required to calculate the surface of a square with a given side L.
The formula S=L*L will be used to find the surface. A first version of logical
diagram for solving this problem is presented in the figure 2.2.1. The user must
enter (by an input element) the side of the square. Then the surface is calculated
(in a processing element) and it is displayed (using an output element).
START

Read L

S=L*L

Write S

STOP

Figure 2.2.1 The surface of a square (the first version)

But what happens if the user, by mistake or by ignorance, enters a negative side
for the square? The value is unacceptable, because a dimension cannot be negative. Therefore, the logical diagram from the figure 2.2.1 doesnt properly
function for all cases and has to be modified. This problem could be partially
20

2 Logical diagrams
solved if the L value is verified before calculating the surface. If the side is
strictly positive (higher than zero), the surface can be calculated and displayed;
otherwise, an error message will be shown (figure 2.2.2).

START

Read L

NO

YES

L>0

S=L*L
Write
Incorrect value
Write S

STOP
Figure 2.2.2 The surface of a square (the second version)

There are cases when the surface (or something similar) must necessarily be
calculated. In other words, the user must be forced to enter a valid value (in this
case, a positive value). This is realized by a repetitive structure (figure 2.2.3).
The user has to reenter the required value as long as this is not valid. Therefore,
the program will continue, calculating the surface, only after a positive value is
entered.

21

Computer Programming The C Language

START

Write
Incorrect value.
Enter a positive
value.

Read L

NO

L>0

YES

S=L*L

Write S

STOP
Figure 2.2.3 The surface of a square (the complete version)

2.2.2 The following problem is also an example of repetitive structure. The user
enters n numbers (n has to be a natural number). The average of these numbers
will be calculated and displayed (figure 2.2.4). In order to solve this problem, n
must have a positive value. A repetitive structure (similar to that used for the
squares surface) will be used to validate the n value. After a positive number is
read, the average can be calculated. It represents the sum of the entered elements divided by the number of elements. Therefore, a variable called sum,
with the initial value zero, is used (its obvious that the sum is zero before
entering any value). In addition to this, at any time during the programs execution, it is necessary to know how many numbers were already read. In order to
do this, another variable, called counter, is used; it also has the initial value
zero. Then, each number can be read. This is realized in another repetitive
structure. Each time a number is read, it is added to the sum and the counter is increased by one. The loop is repeated as long as the counter is less
22

2 Logical diagrams
than n. When the condition becomes false, the repetitive structure is left and the
execution of the program continues, calculating the average, which is then
displayed.
START

Read n

Write Enter a positive value

NO

n>0
YES

counter=0
sum=0

Read number

sum=sum+number
counter=counter+1

YES

counter<n
NO

average=sum/n

Write average

STOP
Figure 2.2.4 The average of n numbers

23

Computer Programming The C Language

2.3 Questions and exercises


A. Find the error.
1.
START

Read x

x=x+1

Write x

STOP

2.
START

Read x

NO

x>0

YES

Write Positive

Write Negative

STOP

24

2 Logical diagrams
3.
START

Read x

NO

YES

x>0

Write Positive

Write Negative

Write Zero

STOP

B. Considering the following logical diagrams, specify what actions they perform.
4.
START

Read xA,xB,yA,yB

AB

xB

xA

Write AB

STOP

25

yB

yA

Computer Programming The C Language


5.
START

Read a3,a2,a1,a0

Write
a3x3+a2x2+a1x+a0

b2=3a3
b1=2a2
b0=a1

Write b2x2+b1x+a0

STOP

6.
START

Read n

r = n modulo 10

Write r

STOP

26

2 Logical diagrams
7.
START

Read n

Write Enter a positive value

NO

n>0
YES

counter=1
p=1

counter=counter+1
p=p*counter

YES

counter<n
NO

Write p

STOP

C. Choose the correct answer (one only).


8. Which of the following statements, regarding logical diagrams, is true?
a) they are graphical representations of programs; b) they are not
connected to a programming language; c) they are a very good method to improve the reasoning; d) they provide an explicit idea about
the programs they represent; e) all answers are correct.
9. Which of the following elements doesnt exist in a logical diagram?
a) decisional; b) output; c) repetitive; d) processing; e) input.
27

Computer Programming The C Language


10. The decisional element has the shape of a:
a) triangle; b) diamond; c) rectangle; d) trapezoid; e) star.
11. Which of the following shapes cannot be part of a logical diagram?
a) rectangle; b) diamond; c) trapezoid; d) triangle; e) ellipse.
12. The processing element has the shape of a:
a) rectangle; b) circle; c) diamond; d) arc of circle; e) parabola.
13. How many outputs a decisional element has?
a) none; b) one: Yes; c) two: Yes and No; d) three: Yes, No,
Unknown; e) any number, depending on the evaluated expression.
D. Create logical diagrams to solve the following problems:
14. Read a real number x. Calculate and display the value of the expression:
E

x,ifx
|x|,ifx

0;
0.

15. Read three numbers a, b and c, representing the coefficients of the


second degree equation ax2+bx+c=0. Find and display the solutions of
this equation.
Suggestion: From the mathematical point of view, the second degree
equation solving requires several steps. First, the value of the a coefficient is verified:
o if a is not zero, then =b2-4ac can be calculated; the obtained
value is verified:

if <0, then the equation doesnt have real solutions; a


message is displayed for this;

if =0, then the equation has two equals solutions:


x1=x2=b/2a;

if >0, then the equation has two different solutions:


x

and x

28

2 Logical diagrams
o if a is equal to zero, then the equation becomes bx+c=0 and the
value of the b coefficient must be verified:

if b is not zero, then x=c/b;

else, the equation becomes c=0 and the value of the c


coefficient must be verified:

if c is not zero, then the expression c=0 is false,


so no solutions for the unknown variable x;

if c is equal to zero, then the expression c=0 is


true and any real number could be the solution for
the equation (this means that the unknown variable x has an infinite number of solutions).

16. Calculate the surface and the length of a circle with R radius.
Suggestion: The following formulas can be used: surface=R2 and
length=2R. The radius value must be validated (it has to be positive).
17. Display the first n Fibonacci numbers.
Suggestion: Fibonacci numbers list is a repetitive structure example. The
list is represented by a sequence of numbers defined using the following
formula:
F n

0,ifn
1,ifn
F n 1
F n 2 ,ifn

0;
1; ,wheren
1.

0, 1, 2, 3,

Therefore, the first two numbers are known (0 and 1) and each of the
following numbers is calculated as sum of the preceding two numbers.
Thus, the first 10 Fibonacci numbers are:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34.

29

Chapter 3
Data and data types
3.1 General concepts
As seen in the first chapter of this book, the computer stores and processes data;
these have different meanings and are essential for solving all kinds of problems. There are two categories of data:
the ones that can be modified (can change their value) during the execution
of the program, called variables;
the ones that maintain their initial value, without the possibility of changing
it, called constants.
Both variables and constants, before being used in a program, must be declared.
The variables have a name, a type and, optional, an initial value. The constants
have a name, a type and, mandatory, an initial value. Through this declaration,
variables and constants receive memory space.
The name of a variable or of a constant is made of several characters (letters,
digits, special characters), following certain rules. In order to do this, a programmer should know the available set of characters. These can be found in
Appendix 1. When the name of a variable or of a constant is set, several restrictions should be considered [CH96]:
the first character of the name should be a letter or an underscore (e.g.
name or _name);
following the first character, any combination of digits and letters (excepting non alphanumeric characters as #, $ or space) can be used (e.g. names
like variable1, word2new can be used, but var$ is not a valid name);
the C programming language is case sensitive; this means that it makes the
difference between uppercases (capital letters) and lowercases (small letters); this feature of the language should be considered when a variable or a
constant is declared and used (e.g. name1 and Name1 are different variables);
there are several reserved words that cannot be used as names for variables
or constants; a complete list of these words (also known as keywords) can
be found in Appendix 2.

3 Data and data types

3.1.1 Data types


The type of a variable or of a constant depends on what must be represented by
that variable or constant; the consequence is how the information is stored in
the computers memory. Any entity that is to be processed by the computer
must be transposed from its acquired form to a physical form defined by voltage. This leads to the basic unit of information representation in memory,
which is the bit. It can have the logical values of 0 (if the voltage is between 0
and 0.4 volts) or 1 (for a voltage between 2.4 and 5 volts). Therefore, a bit
[NR01] is the elementary and the irreducible information, which captures one
of two potential states that are contradictory and complementary.
Commonly, the bits are grouped together in codes with length that are power
of 2. The usual codes are represented by 8, 16, 32, 64, 128, 256 bits. Eight bits
create a byte. The table 3.1.1 presents the multiples of the bit and of the byte
[NR01].
Table 3.1.1 Multiples of the bit and of the byte
Multiples of the bit

Multiples of the byte

1 Kilobit (Kbit) = 210 bits

1 Kilobyte (KB) = 210 bytes

1 Megabit (Mbit) = 220 bits

1 Megabyte (MB) = 220 bytes

1 Gigabit (Gbit) = 230 bits

1 Gigabyte (GB) = 230 bytes

1 Terabit (Tbit) = 240 bits

1 Terabyte (TB) = 240 bytes

1 Petabit (Pbit) = 250 bits

1 Petabyte (PB) = 250 bytes

1 Exabit (Ebit) = 260 bits

1 Exabyte (EB) = 260 bytes

1 Zettabit (Zbit) = 270 bits

1 Zettabyte (ZB) = 270 bytes

1 Yottabit (Ybit) = 280 bits

1 Yottabyte (YB) = 280 bytes


31

Computer Programming The C Language


A type represents the multitude of values that a variable or a constant can take.
Types have a name and are divided into two main categories:
standard types are already defined in the C programming language and
used as they are (int, float, double, char);
user-defined types according to the context and to the requirements of a
problem, the user can define and then can use its own data types.
The standard data types, which can be used in the C programming language,
(also known as primary types) are presented in table 3.1.2. Together with the
name and the type meaning, there is the number of bits used for the representation and the range of values for the data defined by that certain type.
Table 3.1.2 Data types in C programming language
Types name

Types meaning

Dimension

Range

char

character

8 bits

-128 127

int

integer

16 bits

-32.768 32.767

float

real
point)

(floating

32 bits

3.4 e-38 3.4 e+38

double

real
(floating
point,
double
precision)

64 bits

1.7 e-308 1.7 e+308

Data types are often accompanied by the so-called modifiers, which specify the
length of the memory space allocated to an element. These are:
short short;
long long;
signed with sign;
unsigned without sign.
Table 3.1.3 contains the C data types, together with the potential modifiers (this
is how the derived types resulted) [HS98], [DL06].
32

3 Data and data types


Table 3.1.3 Data types and modifiers of the C programming language
Types name

Types meaning

Dimension

Range

unsigned char

character
sign

8 bits

0 255

char or signed
char

character with sign

8 bits

-128 127

unsigned int

integer without sign

16 bits

0 65.535

int or signed int

integer with sign

16 bits

-32.768 32.767

unsigned short
int

short integer without sign

8 bits

0 255

short int or
signed short int

short integer with


sign

8 bits

-128 127

unsigned
int

long

long integer without


sign

32 bits

0 4.294.967.295

long int or
signed long int

long integer with


sign

32 bits

-2.147.483.648

float

real (floating point)

32 bits

without

2.147.483.647
3,4 e-38
3,4 e+38

double

long double

real (floating point,


double precision)

64 bits

long real (floating


point, double precision)

80 bits

33

1,7 e-308
1,7 e+308
3.4 e-4932
3.4 e+4932

Computer Programming The C Language


The names of the types and of the modifiers are keywords in the C programming language, so they are reserved to this aim. It is not allowed to declare
variables or constants with these names and its also impossible to create new
data types or functions that will have these names. The keywords list of the C
programming language can be found in the Appendix 2.

3.1.2 Variables
When a variable is declared, the type of the information stored by that variable
must be specified. The variable must also have a name. The general form of an
instruction that declares variables is:
type var1,var2, , varn;
where var1, var2, , varn are the variables names and type is the name
of one of the types presented in table 3.1.3 or a user-defined type. Variables are
separated by comma, and the declaration is ended with semicolon.
Examples:
int number1, number2, sum;
double average;
When a variable is declared, it can also receive an initial value, which can be
modified during the execution of the program. For example:
int counter=0;
The previous instruction declares an integer variable, with the name counter
and the initial value zero.

3.1.3 Constants
If a program repetitively uses a value, then that value should be declared as
constant. It receives a name and it can be used throughout the program with that
name. Its similar to Mathematics where the surface of a circle is calculated
using the constant , instead of the value 3.14159265
The use of constants in a program has several advantages [CH96]. The most
important are related to the fact that due to the constants code becomes easy to
understand and easy to modify. If a program uses the constant, then is obvious that it represents the ratio between the circumference of a circle and its
34

3 Data and data types


diameter in the Euclidian geometry. But if the value 3.1415 is used, then things
are not so obvious. Regarding the possibility of changing the values of a constant that is being used in a program, the situation is simple: the constant is
modified when it is declared and this change of value is visible wherever the
constant is being used. But if the program uses only values instead of constants,
then the code is more difficult to be modified because all that values should be
found and replaced.
Before using a constant, it must be declared. This action is performed with the
keyword const. The general form of the instruction that declares a constant is:
const type constant_name = value;
where:
type is the data type of the constant (e.g. int, char, float, etc.);
constant_name is the name of the constant (this will be used in the
program);
value is the value that the constant will have.
The following example declares a floating point constant with the name pi and
the value 3.1415:
const float pi = 3.1415;
Besides the constants that are defined by the user, several predefined symbolic
constants can be used in C programming language. For example, there is a
constant called M_PI with the value 3.14159265.

3.1.4 Operators
Variables and constants can be included in different operations to obtain new
values. In order to do this, operators will be used. Variables, constants and
operators will form expressions. Depending on the type of the operation that
involves operators, these are divided into several categories. Those most frequently used will be discussed below [CH96], [DL06], [GP00].
relational operators when applied, the result is 1 if the comparison is
true and 0 otherwise:
< less than (a<b);
<= less than or equal to (a<=b);
35

Computer Programming The C Language


> greater than (a>b);
>= greater than or equal to (a>=b);
== equal to (a==b);
!= not equal to (a!=b).
additive operators:
+ plus (addition: a=b+c);
minus (subtraction: a=b-c).
multiplicative operators:
* multiplication (a=b*c);
/ division when two integer numbers are divided, the result is the quotient (an integer value); if at least one of the operands is a real number,
then the result is a real value (a=b/c);
% modulo the result is the reminder of the division of two integer values
(a=b%c); it cannot be used with real operands.
compound operators these are used for writing expressions faster:
+= addition assignment the result is stored in the first operand (e.g.:
x+=y is similar with x=x+y);
= subtraction assignment the result is stored in the first operand (e.g.:
x=y is similar with x=xy);
*= multiplication assignment the result is stored in the first operand
(e.g.: x*=y is similar with x=x*y);
/= division assignment the result is stored in the first operand (e.g.:
x/=y is similar with x=x/y);
%= modulo assignment the result is stored in the first operand (e.g.:
x%=y is similar with x=x%y).
logical operators:
! logical negation NOT (p=!q);
&& logical AND, also known as logical conjunction (p=p1&&p2);
|| logical OR, also known as logical disjunction (p=p1||p2).
36

3 Data and data types


other operators:
= assignment copies the right value into the left variable; this way an
expression is created and a new value is obtained (e.g.: x=7; or
i=i+2;);
++ increment is an unary operator (this means that it needs only one
operand); it can be applied only to integer variables and its effect is the
increase in value of that variable by one (x++ or ++x are similar with
x=x+1). The operator can be placed before the variables name (prefix
or pre-increment) or after the variables name (suffix or postincrement); the difference is that the variable will change its value before, respectively after use;
decrement decreases the value of its operand by one (x or x
are similar with x=x1) and has the same features as the increment
operator;
& reference or address operator indicates the memory address of a variable and is placed in front of the variables name (&x);
?: ternary (conditional): a?e1:e2 if a is not zero (or true), then the
expression e1 is executed; if a is zero (or false) the expression e2 is
executed;
() function call is performed through the functions name, sometimes
followed by a list of arguments (e.g.: calculate(a,b));
(type) cast or type conversion the operator is used to change the type
of a variable (e.g. if a floating point variable a is considered and the
instruction (int)a is executed, then an integer value will be obtained).
The order of the operations (also called precedence of the operators) is the
mathematical one. Table 3.1.4 contains the operators presented in this paragraph starting with the strongest and ending with the weakest, according to their
precedence [BK03], [HS98].
In order to avoid the errors that can be made because of the operators precedence, it is better to use parentheses when an extensive expression is made. For
example, if the expression x
must be calculated, it will be written as

37

Computer Programming The C Language


x
7 y / 2 z . This expression is different from x
which in fact calculates x
z.

y /2 z,

Table 3.1.4 The operators precedence


Category

Operators

unary

++, , (type)

multiplicative

*, /, %

additive

+,

relational

<, <=, >, >=

equality

==, !=

logical AND

&&

logical OR

||

conditional

?:

assignment

=, +=, -=, *=, /=, %=

The operators precedence has a very important role when the value of an expression is calculated and knowing the order of applying operators is mandatory. For example, the expression (1||1&&0) has the value 1 because operator
&& is applied before operator || [PT12]. If the order was the other way
around, then the result would change.

3.1.5 Expressions
Similar to Mathematics, in a programming language expressions are operations
made on operands (variables, constants or other expressions) using operators.
38

3 Data and data types


This way a new value is obtained; the type of this new value depends on the
operands type. The general form of an expression is:
E = simple_expression [relational_operator another_simple_expression]
If an entity is placed between square brackets, then that entity is optional.
Therefore, an expression is made by one or more simple expressions connected
with relational operators. A simple expression contains terms connected with
additive operators. A term has several factors connected with multiplicative
operators. Finally, a factor can be: a constant, a variable (represented by its
value), the address of a variable (the address operator followed by the name of
that variable), a negated variable, a function call, a cast or another expression
between parentheses.
The expressions can be divided into three categories, according to the result that
they generate [CH96]:
mathematical expressions
These always have a number as result and are made from values that are connected through symbols representing mathematical operations. Parentheses can
be used to specify the order of the operations.
For example:
the expression 3+4*2 will have the result 24;
while (3+4)*2 will be 14.
text expressions
The result of these expressions is a string; this means a sequence of characters
that can include digits, letters, punctuations and other symbols (e.g. "Dennis
M. RITCHIE"). Unfortunately, the C programming language doesnt have
operators for string processing. Instead of operators, text expressions use particular functions that will be presented in the chapter dedicated to strings.
logical expressions
These can have the result 1 or 0, meaning true, respectively false and are
created using relational operators. A logical expression is similar to a question
with the answer yes or no.
For example:
5>1 is a true expression, so the result is 1;
7==0 is false, so it has the result 0;
39

Computer Programming The C Language


a>=b can be 0 or 1, depending on the values of the considered variables.
The logical expressions results and also elements that can have a logical meaning can be connected with logical operators, obtaining complex conditions. In
order to do this, the logical operators must be well known. In table 3.1.5 two
logical variables a and b are considered and the logical operators AND, OR and
NOT are applied; all possible results are revealed.
Table 3.1.5 How to apply logical operators
a

!a

a&&b

a||b

For example:
the expression (7>=5)&&(0!=10) contains two true expressions connected through the logical AND operator; the final expression is true,
so the result will be 1;
the expression (7==0)&&(3<4) is made of a false expression (the first
one) and a true expression (the second one), connected through a logical AND operator; the result is false, meaning 0;
the expression (7==0)||(3<4) contains the same two parts as the previous expression (a true one and a false one), connected this time
through the logical OR operator; therefore the value 1 will be obtained
(the final expression is true because at least one of the expressions is
true, as can be seen in table 3.1.5 also);
the expression !(7==0) is true because a false expression is negated.

40

3 Data and data types

3.2 Data types description


The following paragraphs present the standard data types that were shortly
described before. There are also discussed the operators that can be applied to
every type. At the end of each paragraph some examples regarding the use of
that data type are presented.

3.2.1 The integer type


In the C programming language there are several types that can be used to
represent integer values, each of these types being a subset of the mathematics
integer numbers set (Z). Summarized in table 3.1.3, integer types are detailed
below.
unsigned int is used for integers without sign. Such a number is
represented using 16 bits and can have values between 0 and 65.535. In the C
programming language a constant that can be used to determine the maximum
limit of this range is defined. The constant is UINT_MAX and has the value
65.535.
int or signed int are the types used to represent integers with sign. 16 bits
are required for this numbers and the range of values is -32.768 32.767. The C
constants that delimit this range are INT_MIN, with the value -32.768, and
INT_MAX, with the value 32.767.
unsigned short int is the type used for short integers without sign.
Numbers are represented on 8 bits, so the range is 0 255. In order to access in
a program the upper limit of this domain, the constant USHRT_MAX can be
used; it has the value 255.
short int or signed short int define short integer numbers with
sign. These types of numbers are represented on 8 bits and have values between
-128 and 127. The limits of this range can be found using the constants
SHRT_MIN, which has the value -128, and SHRT_MAX, with the value 127.
unsigned long int is a data type used for large, positive integers. These
numbers are represented on 32 bits and have values in the range 0
4.294.967.295. The constant ULONG_MAX contains the upper limit of this
range.
long int or signed long int are used for large integers with sign (positive or negative). The representation is made using 32 bits and the numbers are
41

Computer Programming The C Language


between -2.147.483.648 and 2.147.483.647. The limits of this range can be
accessed through the constants LONG_MIN and LONG_MAX.
When programs are written, variables must be properly defined. For example,
the age of a person can be represented by a variable that has the type unsigned short int because the age is always positive and it is also a short
number. But if a force has to be used in a program, then the variables definition
must provide a large enough domain, with positive and negative values (int
for example).
The integer numbers can be involved into different operations: relational (<,
<=, >, >=, ==, !=), arithmetical (+, -, *, /, %) or logical (&&, ||). The integer
variables can also be incremented (++) or decremented (--).
Using the integer type
The following sequence declares, using the integer type, three variables (x, a
and b) and a constant (lambda). The constant has, obviously, an initial value
(3 in this case). The variables do not receive initial values when they are declared; a and b get values later (2, and -7 respectively), and the value of x is
calculated through an expression. The result of this expression is -15.
const unsigned int lambda = 3;
int x, a, b;
a = 2; b = -7;
x = lambda * (a + b);
The integer variables are often used with the increment and decrement operators. These operators can be placed as prefixes or as suffixes of a variable; the
difference is marked by the following two sequences of code. Two integer
variables a and x are declared. The second variable, x, has the value 7. The
difference is visible when the assignment of the x value to the variable a is
made. In the first case, x is incremented after the assignment; in the second
case, before the assignment.
int a, x;
x = 7;
a = x++;

int a, x;
x = 7;
a = ++x;

After these three lines of code are Because x is incremented before the
executed the results are a=7 and x=8 assignment, in this second case the
because x is incremented after the results are a=8 and x=8.
assignment.
42

3 Data and data types

3.2.2 The real type


The real numbers (R set of Mathematics) can be included in a C program
through the types float, double and long double described in table 3.1.3. These data types offer the possibility to use real numbers with different precisions and dimensions, up to the value of 3.4 e+4932.
float is the data type used to represent, on 32 bits, real numbers with 6 decimal places. If a higher accuracy is necessary, then numbers can be declared
double (with representation on 64 bits) and in order to extend the precision,
the long double type can be used (with representation on 80 bits).
The real type variables can be used in expressions with relational operators (<,
<=, >, >=, ==, !=) and with arithmetical operators (+, -, *, /). In relational
expressions, the result is a value that has the meaning of true or false (for example, 7.14 < 17.2 is a true expression, but 3.5 == 7.8 is a false one).
Using the real type
In the following sequence of code two float variables are declared and
receive initial values. The first one is used to store the price and the second to
store the quantity of a product sold in a period of time. A third variable, also of
float type, is declared; its value is calculated multiplying the first two variables (representing the collected amount).
float price = 4.5, quantity = 125.75, amount;
amount = price * quantity;

3.2.3 The char type


This category of data is the set of all possible characters. They can be
represented on 8 bits, with or without sign, through two data types (unsigned
char and char or signed char) described in table 3.1.3.
256 characters can be encoded on the 8 bits available. All characters are converted to integers according to the ASCII code (American Standard Code for
Information Interchange). Appendix 1 contains some of these characters, together with the associated ASCII codes.
Using the char type
Some characters are declared and initialized in order to show how to work
with this kind of data in a C program.
43

Computer Programming The C Language


char c1 = 'A';
char c2 = '7';
These characters may be the subject of few standard operations:
char c3;
c3 = c1 + c2;
After executing the sum, the variable c3 will have the value 'x' because in
fact the ASCII codes of variables c1 and c2 are added.
Relational operators can be applied to characters. Thus, 'D'<'b' is an
expression with a true result, and '8'<'6' has a false result. This is because
the ASCII codes associated to those characters are compared.

3.2.4 The logical type


C programming language doesnt have a standard data type for logical information, as other languages do e.g. Pascal and Java have the boolean type. Numerical values are used in the C programming language in order to represent the
truth value of an expression or any other logical element. Thus, zero means
false and anything else means true.
Relational operators can be applied to logical elements (==, <, >, <=, >=, !=);
the result having a logical character. The logical operators (&&, ||, !) can also
be used with logical data.
Using the logical type
An integer variable x is considered. Somewhere in the execution of a program must be verified if x is an even number. A number is even if it can be
divided by 2 (in other words, if the reminder of the division by 2 is 0). In order
to verify this condition, the % (modulo) operator is used. The expression
x%2==0 will be true if and only if x is even. Therefore, the result of this
expression has a logical value.
It is supposed to have two integer variables x and y. An expression that will
be true if and only if at least one of the variables has a strictly positive value
must be written. That expression will be: (x>0)||(y>0).
A floating point variable called mark stores the mark of a student obtained at
an exam. In order to verify if that mark belongs to the interval (8; 10] the expression (mark>8)&&(mark<=10) must be used.
44

3 Data and data types

3.2.5 The void type


This is not really a data type or it can be considered an empty data type, a data
type that doesnt have values. From a syntactical point of view, it is placed
where a data type is expected. Void is used to specify that a function doesnt
return anything (e.g. void aFunction(int x)). It can also appear as the
unique argument in the prototype of a function, showing that the function
doesnt have any arguments (e.g. float otherFunction(void)).

3.2.6 Type casting


Sometimes the type of an entity must be changed (to benefit from the advantages offered by some properties of another type). This can be achieved through a
type conversion (cast). There are two kinds of type conversions implicit and
explicit [BK03], [HS98].
The implicit type conversion is automatically made by the compiler and it is
necessary when entities with different data types are involved in an expression.
This conversion has two directions.
On the one hand, the conversion modifies a data type into another data type that
includes the initial one, as can be seen in the following example. The integer
variable b is converted to float and the result is x = 9.47.
float a = 2.47, x;
int b = 7;
x = a + b;
In this case, when the expression was evaluated, the most comprehensive type
was searched. All the elements of that expression were converted to that type.
The order of the data type, starting with the most comprehensive is: double,
float, long, int, char [CH96].
On the other hand, if an assignment is made, the source data will be forced to
the destination data type [CH96], even if this implies truncated information and
loss of precision. The previous example was modified considering the result x
an integer variable. The consequence is that all variables from the right side of
the assignment sign are forced to become integers and the result is x = 9.
float a = 2.47;
int b = 7, x;
x = a + b;
45

Computer Programming The C Language


The explicit type conversion is introduced in a program through a type modifier. This is an unary operator that is placed as a prefix to a variable or an
expression and changes that information to the specified type. The general form
of an explicit type conversion is:
(type)expression;
It is very simple to use this kind of conversion in a C program. For example, an
integer variable a is considered. It stores the ASCII code of a character. Another variable, x, of char type will store the character associated to the specified
ASCII code, changing the content of the variable a from int to char.
int a=65;
char x;
x=(char)a;

3.3 Questions and exercises


A. Find the error.
1. const int alpha=2;
int beta=3;
alpha=beta+10;
2. int a=7, double=2, x;
x=double*a;
3. float x=1, y;
y=x++;
4. unsigned int a=22, b=35;
x=a+b;
5. unsigned int x=12, y=-15, q;
q=x-y;
6. float a=2, b=-3;
x=-a/b;
float x, y;
y=2*x+a-b;
7. int x=1, y=2, z=3, e;
e=x+2y-z;
46

3 Data and data types


8. float x=7.5, y;
y=x%2;
9. float 1_mark, 2_mark, final_mark;
final_mark=(2*1_mark+2_mark)/final_mark;
B. Considering the definitions int a=3, b=4;, evaluate the following
expressions and specify the result.
10. E=a/5+1;
11. E=(a++)-(a%2);
12. E=(a++)-(--b);
13. E=(-a)-(--a);
14. E=(a==b);
15. E=(a+b)%4;
16. E=((--b)+a++)%2;
C. Choose the correct answer (one only).
17. Which of the following data types doesnt exist in the C programming
language?
a) int; b) float; c) double; d) char; e) all answers are
wrong.
18. Which of the following variables declarations is wrong?
a) float mark_one; b) float mark one; c) float
markone; d) all declarations are correct; e) all declarations are
wrong.
19. Specify the value of the expression E=((2+4)*3-1)*(3-5)?
a) -34; b) 0; c) -24; d) 24; e) the expression contains an error.
20. Which will be the value of x variable after the following sequence of instructions is executed?
int a=65, x;
x=a/2;
a) 32.5; b) 1; c) 32; d) 65; e) all answers are wrong.
47

Computer Programming The C Language


21. Calculate the value of the expression E = 2*(7-(9+5)+4*(2119).
a) 8; b) -6; c) -12; d) 2; e) the expression contains an error.
22. Which will be the value of m variable after the execution of the following instructions?
double a=7, m;
m=a%2;
a) 3.5; b) 1; c) 14; d) 49; e) the assignment m=a%2 is impossible.
23. Which of the following expressions is true if x=1 and y=3?
a) (x>=0)&&(y<3); b) (x>=0)||(y<3); c) ((x==0)||
(y!=3))&&(x!=y); d) (x==y)||(y<=0); e) all expressions
are false.
24. Which of the following variables declarations is correct?
a) int n1#; b) int #n1; c) int n1_#; d) int
#_n1; e) all declarations are wrong.
25. Which of the following words is not a modifier in the C programming
language?
a) short; b) long; c) signed; d) unsigned; e) all answers are wrong.
26. Which of the following data types doesnt exist in the C programming
language?
a) int; b) float; c) boolean; d) char; e) all answers are
wrong.
27. How many bits a byte has?
a) 1; b) 2; c) 4; d) 8; e) a byte doesnt contain bits.
28. Which will be the value of x variable after the following sequence of instructions is executed?
float a=3.1415;
int x=0;
x=(int)a;
48

3 Data and data types


a) 3; b) 3.14; c) 3.1415; d) 0; e) the assignment x=(int)a is
impossible.
29. Which of the following expressions is false if a=1, b=-3 and c=7?
a) !((a+b+c)<0); b) !((a<b)||(b>c)); c) ((a+b)>c)||
((a!=0)&&(b!=0)); d) !(a>b); e) all expressions are true.
30. Which of the following data types doesnt exist in the C programming
language?
a) int; b) float; c) string; d) double; e) all answers
are wrong.

49

Chapter 4
A first C program
4.1 Stages of a C program implementation
A program is a list of instructions that specify what a computer has to do. In
fact, a program represents the implementation of the algorithm that solves a
certain problem. The instructions that form a program may refer to: reading
information from the keyboard or from a file, writing information on the screen
or in a file, making arithmetic and logical operations, comparing entities.
The first step in making a program is writing it (and obviously saving it) using a
text editor. The result is a source file that will have the extension .c (e.g. program.c). But a source code has no meaning for the computer. It must still
undergo some changes.
Thus, the next step in the development of a program is the source file compilation; this means that the program will be translated from the programming
language used to write it (C, in this case) to the language of the computer machine, language that is called machine-code [NR01]. This process is performed
by a compiler. If the program has errors, these will be displayed and must be
solved. The line that contains each error is emphasized and a short message
explains the possible cause of the error. Once the program is successfully compiled, an object file is created a file with the same name as the source file, but
with the extension .obj (e.g. program.obj)
Next follows the linking phase performed by a linker (or link editor). It connects the object code previously created with object codes of library files, of
input/output drivers and/or of the operating systems programs [NR01]. The
result is a new file, an executable file. This has the same name as the source
file, but the extension is .exe (e.g. program.exe). The executable file can
be run, obtaining the results for which the program was created.
Figure 4.1.1 is a graphical representation of the steps followed in a C program
development, from the code writing, to the results. It can be observed that the
source file represents the input data for the compiler and the object file is the
input for the link editor.

4 A first C program

Editing
Source file
Correcting
errors
Displaying
errors

YES

Compiling

Errors?

NO

Object file
Linking
Executable file
Running
Results

Figure 4.1.1 The development of a C program

If a repeated execution of a program is necessary, then it is sufficient to run the


executable file. But if the source code is modified, then the compiling and the
linking phases must be completed again before the program can be executed
once more.

4.2 The structure of a C program


All programs that are written using the C programming language are made by
one or more functions. First, a program that contains a single function and
displays on the screen the message This is a first C program will
be considered. The source code is presented by the program 4.2.1.
Program 4.2.1
#include <stdio.h>
void main(void)
{
printf("This is a first C program.");
}
51

Computer Programming The C Language


All programs require a starting point. In the C programming language the execution of a program starts with a function called main(). All C programs
must have this function. Otherwise, the starting point of the program will not be
determined and a linking error will be generated.
Both outside and inside the main() function there are a lot of other elements
that are emphasized by numbers in figure 4.2.1, figure that describes the structure of the previous program. All these elements have a well-defined role, some
of them being mandatory in certain contexts.
1

#include <stdio.h>
10
4

void main(void)

printf("This is a first C program.");


}

11
Figure 4.2.1 The structure of a C program

Though the program in figure 4.2.1 has a single objective (to display on the
screen a simple message), it needs several tools in order to accomplish this task.
Their role is hereby presented.
1. #include
it is called preprocessor directive;
it specifies that together with the source code of the current program, another program/file must be considered in order to have a
proper functioning of the application;
usually the files that are included through this directive are library
files and contain a number of functions that are used in the program.
52

4 A first C program
2. <stdio.h>
the name of the file that is intended to be included;
it must be framed by angle brackets (number 10 in figure 4.2.1);
in this case the standard input/output library is included; it contains
functions that are used to read and to write data; the current program
needs to include this library because it has to display a text on the
screen (this is done using a function that is described in the included
library).
3. main
is the name of a function;
in this case it is the name of the most important function of a C program (main()), but it can also be any other function.
4. void or the name of a data type written in front of a functions name
represents the type of a function (in fact, the type of the value returned
by that function);
the main() function from the presented example doesnt return anything; for this reason, in front of its name stands the word void (as
shown in the chapter presenting data types, void can be considered
an empty data type);
caution: if nothing is written in front of a functions name, then that
function must return an integer value.
5. (void) or a list of comma delimited variables, each one preceded by its
type
the arguments of that function;
the list is enclosed by parentheses and is placed after the name of the
function, as shown by number 11 in figure 4.2.1;
if the function doesnt have arguments (as the current case), then the
word void will be used to specify this.
6. { and }
the curly brackets mark the beginning and the end of a function or of a
block of instructions;
53

Computer Programming The C Language


each time a number of instructions must be executed together, curly
brackets will be used to group them.
7. represents the call of a function
this call specifies what the program must execute at that moment;
in this case, the function printf() that is called will display a message on the screen (details about this function are presented in the
chapter about input/output functions of the library functions).
8. the list of the arguments used when a function is called
if a function requires arguments, these must be sent when the function
is called;
the arguments are comma delimited (if there are more than one) and
are enclosed by parentheses;
the parentheses must be present even if the function doesnt require
arguments;
in the presented example the function printf() receives as argument a string delimited by double quotes.
9. the semicolon ;
each C instruction is ending with semicolon;
this is the character used to delimit instructions (thus, the compiler
will understand where an instruction ends and where another one begins);
even if the main() function presented here contains a single instruction (the call of the function printf()), the semicolon delimiter
must be used at the end of this instruction;
in this example the line that contains the beginning of the main()
function doesnt have semicolon; the reason for that is that the instruction doesnt end on this line, but on the last line of the program, where
the closing curly bracket appears;
on the other hand, after the curly bracket it is not required to use semicolon because the curly bracket is only a character that groups elements together and doesnt execute anything by itself [GP00].
As shown in the example in figure 4.2.1, a C program can contain three types of
brackets [GP00]: angle brackets <> (marked by number 10), curly brackets {}
54

4 A first C program
(marked by number 6) and parentheses () (marked by number 11). Square
brackets [] are also used (as shown in some of the following chapters). These
must be well understood and used correctly. In some cases, if they are not correctly used, then some compilation errors will be displayed and the program can
be corrected. In other cases, the compiler doesnt report an error (though these
symbols are not placed according to what the flow of instructions must execute), but the program will not generate correct results.
Comments in the C programming language
Comments can also be included in a C program. These are sequences of text
written in natural language, used by the programmer to mark some sections of
the program or to give some explanations, so that the written source code is as
explicit as possible. Comments are marked accordingly, are ignored by the
compiler and are not executed when the program is run.
The C programming language offers the possibility to use two types of comments:
single line comment is marked by two oblique lines (slashes) // that must
be placed at the beginning of the line;
multi line comment begins with /* and ends with */.
Several comments are inserted in the program that was previously presented, in
order to illustrate how to use them. Thus, the program 4.2.2 resulted.
Program 4.2.2
#include <stdio.h> //standard input/output library
void main(void){
/*The following function is used to display a
message on the screen. It receives the text of
the message as argument.*/
printf("This is a first C program.");
}

4.3 Possible errors


When a program is compiled and linked, errors may emerge if it is not developed according to the rules of the C programming language. The error messages
55

Computer Programming The C Language


that are displayed are usually explicit enough and are very efficient in finding
and removing the errors. Some of the most common errors are hereby presented.
Function 'f_name' should have a prototype. In this case the
compiler doesnt recognize the function f_name(). There are several causes
for this problem. If the function is part of a library, then probably that library
wasnt specified in a preprocessor #include directive. If the function is a
user defined one, then it is possible that the function has not been defined yet (a
function must be defined before it can be used). Finally, if none of these cases
is true (this means that the library is specified or the function is defined), then
the cause could be a misspelling of the functions name.
Statement missing ;. This error message is generated if the semicolon
separator is missing. Usually the message is associated to the line that follows
the line without semicolon because the compiler is not able to separate them.
Compound statement missing }. If this error message is displayed,
then a closing curly bracket (that marks the end of an instructions block) is
missing.
Unexpected }. The error message is because of an extra closing curly
bracket.
Undefined symbol 'x'. In this case, a variable (x), that has not been
declared yet, is being used. As stated in the chapter about data and data types,
any variable must be declared before it can be used. The type of that variable
must be specified at the beginning of the program or at the beginning of the
function.
Undefined symbol _main in module c0.asm. This error is generated in the linking phase, not in the compiling one. The reason is that the program doesnt have a main() function; it was either omitted or misspelled. A C
program must have this function in order to be executed.

4.4 Questions and exercises


A. Find the error.
1. void main(void){
float x,a=2,b=-4;
56

4 A first C program
x=-b/a
}
2. void main(void)
//this function increments the age
int age=18;
age++;
}
3. void main(void){
/*this function gives initial values to the
coefficients of the first degree equation and
calculates the value of the unknown x
float x,a=2,b=-4;
x=-b/a;
}
4. void main(void){
float x=3,y=4,z=5;
surface=(x*y)/2;
}
B. Considering the following programs, specify the value of the expressions
that are calculated.
5. void main(void){
int a, b;
float E1, E2;
a=7; b=2;
E1=a/b;
E2=(float)a/b;
}
6. void main(void){
int a, b, E;
a=7; b=3;
E=a++ + ++b;
}
7. void main(void){
int a, b, E;
a=7; b=3;
E=a>b;
}
57

Computer Programming The C Language


C. Choose the correct answer (one only).
8. In order to translate a C source file into a machine-code file should be
used:
a) a dictionary; b) a compiler; c) a copier; d) a linguist; e) an
engineer.
9. The link editor creates a:
a) source file; b) object file; c) executable file; d) remunerable
file; e) all answers are wrong.
10. Which function must be present in any C program?
a) include; b) void(); c) main(); d) the answers a, b and
c are correct; e) all answers are wrong.
11. If a function does not return anything, what will be written in front of
the name of that function?
a) return; b) void; c) integer; d) main; e) nothing.
12. In the C programming language the instructions can be grouped in a
block using:
a) ( and ); b) [ and ]; c) { and }; d) < and >; e) begin and
end.
13. Which of the following signs can be used to insert a comment in a C
program?
a) //; b) #; c) ||; d) &; e) <!--.
14. In the C programming language the instructions are separated by:
a) ;; b) :; c) .; d) ,; e) it is not necessary to use a separator;
it is enough to write instructions on different lines.
15. A C source file has the extension:
a) .src; b) .obj; c) .exe; d) .c; e) .txt.

58

Chapter 5
Library functions
The C programming language is a very simple language. It only has few instructions that can be used to solve different problems. But these instructions
are not always enough. For instance, the C programming language doesnt
provide any method to read information from the keyboard or from a file, to
display them on the screen or to write them in a file, to process strings, to work
with mathematical functions and so on. For this reason, all C compilers also
include a standard library of functions that implement the most frequently used
tasks. This library contains several header files that gather certain categories of
functions. The programmer can use (or can call) any library function; however,
he is forced to specify, at the beginning of the program, in a #include directive, the name of the header file which contains the function that is used in the
program.
In the following paragraphs some of the most frequently used library functions
are described [BH92], [SL12]. These are gathered in several categories, according to the domain they are applied in.

5.1 Input/output functions


This paragraph presents functions that are used to read information from the
keyboard and to display them on the screen. The values that are read or written
can be characters, strings or numbers of any type. The description begins with
the output functions (used to print something on the screen: putchar, puts,
printf) and continues with the input functions (used to read something from
the keyboard: getchar, gets, scanf).
5.1.1 int putchar(int char);
This function displays on the screen the character received as argument. If the
function is performed successfully, it returns the character that was printed;
otherwise, the constant EOF (end-of-file) is returned. The header file that contains this function is stdio.h.

Computer Programming The C Language


Program 5.1.1 displays on the screen the character A. It can be observed that the
header file required for the function putchar() was specified at the beginning of the program.
Program 5.1.1
#include <stdio.h>
void main(void){
putchar('A');
}
A second example (program 5.1.2) sends a variable of type char as argument
to the function putchar(). This variable is declared, receives an initial value
and then it is printed on the screen.
Program 5.1.2
#include <stdio.h>
void main(void){
char var;
var='A';
putchar(var);
}
In order to display a character on the screen, the function int putch(int
c) from the conio.h header file can also be used. If succeeds, the function
returns the character that was displayed; otherwise it returns EOF. The program
example 5.1.3 uses this function to print the character A.
Program 5.1.3
#include <conio.h>
void main(void){
putch('A');
}

5.1.2 int puts(const char *s);


The call of this function prints on the screen the string s received as argument
and sets the position of the cursor to the next line. If succeeds, a non-negative
value is returned; on error, the function returns the value EOF. This function is
part of the stdio.h header file.
60

5 Library Functions
In program 5.1.4 the function puts()receives as argument directly the string
that must be displayed. It is also possible to send a string variable that was
previously declared, as argument to the function.
Programul 5.1.4
#include <stdio.h>
void main(void){
puts("This is a programming course.");
}

5.1.3 int printf(const char* format [, argument, ...]);


The function is used when formatted data has to be printed on the screen. The
header file that must be included in the program is stdio.h. If succeeds, this
function returns the number of printed characters; on error, it returns a negative
value.
In a very simple way, this function can be used to print text on screen; in this
case, the list of arguments [, argument, ...] is missing and the string
format contains only the text that has to be written. Program 5.1.5 depicts this
way of using function printf().
Program 5.1.5
#include <stdio.h>
void main(void){
printf("The C programming language is useful.");
}
Nevertheless, function printf()proves its qualities when it is used to print
formatted values on the screen. This function accepts a set of arguments (variables or constants); a formatting specified through a string is applied to these
arguments. The formatted arguments are then displayed on the screen.
The string format may contain:
a simple text, printed as it is;
the special character % followed by a format descriptor that, in turn, may
contain:

61

Computer Programming The C Language


o the minus sign (-) which sets that the printed element is to be
aligned to the left (the default alignment is to the right);
o a number that specifies the minimum length of the field where
the element is printed;
o a dot (.) which separates the fields length by the precision used
for the displayed element;
o a number that specifies the precision (the number of decimals
that will be displayed);
o the conversion type character a character that indicates the type
of the printed argument; some of the most frequently used conversion type characters are:

c character;

s string;

d, i signed decimal integer;

u unsigned decimal integer;

f floating point number (float, double).

o for instance: %c prints a character, %d prints an integer number,


%5.2f prints a real number with at least 5 characters, two of
these characters being reserved to the decimal part, %-15s
prints, using at least 15 characters, a left aligned string.
the special sign \ followed by:
o a character that specifies the place of the next printing:

\b moves the cursor (the point where the printing begins) back with one character, deleting that character;

\n the next printing will be done on a new line;

\t moves the cursor with a horizontal tab to the right.

o a character that cannot be printed in any other way:

\\ prints backslash (\);

\ prints apostrophe;

\" prints quotation marks.


62

5 Library Functions
The program from the example 5.1.6 calls function printf() in order to print
the value of the variable weight, which was previously declared and received
an initial value. Once the program is run, the text The suitcase is 17
kg will be displayed on the screen. It can be observed that the value of the
variable weight was inserted in the text where the descriptor %d appears.
Program 5.1.6
#include <stdio.h>
void main(void){
int weight=17;
printf("The suitcase is %d kg.", weight);
}
Function printf()also allows the use of some expressions as arguments.
Example 5.1.7 prints the sum of two numbers, sum that is calculated when
function printf() is called. The result is a real number (float), displayed
with two decimals precision. These features are specified by the format descriptor %.2f. Once the program is executed, the text The sum is: 7.50 is
displayed on the screen.
Program 5.1.7
#include <stdio.h>
void main(void){
float x=3.5, y=4;
printf("The sum is: %.2f.", x+y);
}
When using function printf(), it is possible to print more than one argument, as in example 5.1.8. The text that is displayed after the execution of the
program is The student is 177 cm and 80.7 kg. The value of the
weight is truncated due to the setting from the format descriptor %.1f.
Program 5.1.8
#include <stdio.h>
void main(void){
int h=177;
float w=80.73;
printf("The student is %d cm and %.1f kg.", h,w);
}
63

Computer Programming The C Language


As previously mentioned, function printf() allows to specify the position of
the next printing. Program 5.1.9 shows how a text can be written on a new line.
Program 5.1.9
#include <stdio.h>
void main(void){
int a=7, p=3;
printf("Ann has:\n\t%d apples\n\t%d pears", a, p);
printf("\nThere are %d fruits.", a+p);
}
Characters \n were used to move the cursor down, on the next line; this is the
place where the printing of the text continues. In order to shift the text to the
right (tab), there were used the characters \t. When the program is run, on
the screen will be printed:
Ann has:
7 apples
3 pears
There are 10 fruits.

5.1.4 int getchar(void);


The function reads a character from the keyboard and returns that character
after it converts it to an unsigned integer. On error, the constant EOF is returned. The header file that contains this function is stdio.h.
In example 5.1.10 a character is read from the keyboard using this function. The
character is saved in the variable c and then it is printed on the screen using
function printf(). When the program is run, the text Enter a character is displayed on the screen and the execution of the program waits for the
user to type a character. If, for instance, the user types the character a, then the
program will continue printing the message The read character is:
a.
Program 5.1.10
#include <stdio.h>
void main(void){
int c;
64

5 Library Functions
printf("Enter a character ");
c=getchar();
printf("The read character is: %c.", c);
}
Another function, int getch(void) from the header file conio.h, can be
also used to read a character from the keyboard. It returns the read character.
This function is often used to force the program to wait until a key is pressed (in
fact, the execution of the program is interrupted; the break will be finished
when the user presses a key). The read character is not used by the program, but
this trick is very good when some information is displayed and must be seen
before it is deleted or before the execution of the program is ended.
The program example 5.1.11 prints a simple text on the screen and then calls
the function getch() in order to avoid the ending of the programs execution
immediately after the text is printed; so, the execution is ended only when the
user specifies this by pressing a key. It can be observed that this program needs
two header files: stdio.h for the function printf() and conio.h for the
function getch().
Program 5.1.11
#include <stdio.h>
#include <conio.h>
void main(void){
printf("Press any key to continue.");
getch();
}

5.1.5 char *gets(char *s);


The function reads a string from the keyboard and is part of the stdio.h
header file. The reading includes the whitespace characters (spaces, tabs) and
ends when a new line (ENTER) appears. On error, the function returns EOF.
Example 5.1.12 shows how this function can be used. At the beginning of the
program, a string of 100 characters is defined. More information on strings is
given in the chapter committed to them. The text Enter a string is displayed and then the execution of the program is interrupted, waiting for the user
to type a sequence of characters ended with the ENTER key. If, for instance, the
65

Computer Programming The C Language


introduced string is Once upon a time, then the program will display the
text Your string is: Once upon a time.
Program 5.1.12
#include <stdio.h>
void main(void){
char s[100];
printf("Enter a string ");
gets(s);
printf("Your string is: %s.", s);
}

5.1.6 int scanf(const char* format [, address, ...]);


This function is used to read several fields that are converted according to a
specified format and then are saved at the memory addresses sent as arguments after the formatting string. For each read element there must be a conversion specifier and a storing address. The function is part of the stdio.h header file. If succeeds, it returns the number of the read, converted and stored
fields. If there is nothing to be read or if an error occurs before the reading is
done, then the function returns EOF.
The arguments of this function are, somehow, similar to those of the function
printf(). Therefore:
the string format contains several conversion characters, each one preceded by the special character %; some of the most frequently used conversion characters are:
o c character;
o s string;
o d, i signed decimal integer;
o u unsigned decimal integer;
o f floating point number (float, double).
the address of each read element is in fact the name of the variable that
stores the read value, preceded by the addressing operator & (e.g.: &n); if
the variable is a string, then the addressing operator is missing because the
66

5 Library Functions
address of the first element of the string is given directly by the name of the
string.
In program 5.1.13 a couple of information about a person is read name (defined as string) and age. At the end, this information is displayed on the screen.
Warning: the addressing operator should not be omitted if a variable is not a
string; in the example one can observe that the variable age needs this operator
when it is read and stored.
Program 5.1.13
#include <stdio.h>
#include <conio.h>
void main(void){
char name[100];
int age;
printf("Enter the name ");
scanf("%s", name);
printf("Enter the age ");
scanf("%d",&age);
printf("%s is %d years old.", name,age);
getch();
}
If, for instance, the information entered by the user when the program is run is
Ann for the name and 7 for the age, then the message Ann is 7 years
old will be displayed on the screen. Function getch(), at the end of the
program, is used to determine the program to wait for the pressing of a key
before it ends its execution.

5.2 Mathematical functions


The programs that are written to solve certain problems often involve the use of
some mathematical functions. The standard library of the C programming language contains implementations for the most frequently used mathematical
functions, grouped in the math.h header file. Some of them are hereby presented.
double exp(double x);
o the exponential function;
67

Computer Programming The C Language


o it calculates the value ex, where e 2.71828;
double log(double x);
o the natural logarithm of x;
o the argument must be a strictly positive value, otherwise a domain error is generated;
double log10(double x);
o the base 10 logarithm of x, with x strictly positive;
double pow(double x, double y);
o the power function, x to the y;
double pow10(int x);
o the power function, 10 to the x;
double sqrt(double x);
o square root of x;
o the function is defined for positive numbers; if x is negative, a
domain error is generated;
double fabs(double x);
o calculates the absolute value of a floating point number x;
double sin(double x);
o computes the sine of the input value x, where x is expressed in
radians;
double cos(double x);
o the cosine of x, with x specified in radians;
double tan(double x);
o the tangent of x, with x expressed in radians;
There are implementations with similar prototypes for functions arc sine
(asin()), arc cosine (acos()), arc tangent (atan()), hyperbolic sine
(sinh()), hyperbolic cosine (cosh()), hyperbolic tangent (tanh()). All
these functions receive a double value as argument, representing the angle
specified in radians and also return a double value.
68

5 Library Functions
Two other functions, floor() and ceil(), are also part of this library; they
are used to find the largest integer that is smaller than or equal to the argument
and the smallest integer that is larger than or equal to the argument, respectively. The prototypes of these two functions are hereby presented.
double floor(double x);
double ceil(double x);
In other words, floor() makes a down rounding and ceil() makes an up
rounding of the argument. Both functions return the found integer as a
double. For example:
floor(6.3)=6

ceil(6.3)=7

floor(-1.73)=-2

ceil(-1.73)=-1

floor(0.5)=0

ceil(0.5)=1

floor(-0.5)=-1

ceil(-0.5)=0

floor(7)=7

ceil(7)=7

Example 5.2.1 shows how some of the mathematical functions presented in this
paragraph can be used in a program. During the program, a couple of variables
x and y receive different values and are used as arguments for several function
calls; the values that are returned are printed immediately or are firstly stored in
a variable f.
It can be observed the use of the constant M_PI for the trigonometric functions.
This constant has the value3.1415 and is part of the math.h library.
Program 5.2.1
#include <stdio.h>
#include <conio.h>
#include <math.h>
void main(void){
double x, y, f;
x=3; f=exp(x);
printf("\nexp(%.2f) = %.2f",x,f);
x=2; y=3;
printf("\n%.0f to the %.0f=%.0f",x,y,pow(x,y));
x=49;
printf("\nsquare root of %.1f is %.2f",x,sqrt(x));
69

Computer Programming The C Language


x=1.7; f=log(x);
printf("\nln(%.2f) = %.3f",x,f);
x=-7;
printf("\n|%.2f| = %.2f",x,fabs(x));
f=sin(M_PI/6);
printf("\nsine of 30 degrees is %.2f", f);
getch();
}
Once the program is run, the following results will be printed on the screen:
exp(3.00) = 20.09
2 to the 3 = 8
square root of 49.0 is 7.00
ln(1.70) = 0.531
|-7.00| = 7.00
sine of 30 degrees is 0.50

5.3 Conversion functions


In some situations, for different reasons, a number is represented as a string. In
order to use it in arithmetical, logical or relational operations, this number must
be converted. The following two functions can be used to convert a string into
an integer and into a real number, respectively. These are declared in the
stdlib.h header file.
int atoi(const char *str);
o converts the string received as argument to an integer value;
o the name of the function stands for ASCII to integer;
o the function returns 0 if the argument contains non-numerical
sequences and cannot be converted.
double atof(const char *str);
o converts the string str, received as argument, in a floating point
number;
o the name of the function stands for ASCII to float;
o the function returns 0 if str is a string that doesnt have a numerical meaning.
70

5 Library Functions
Program 5.3.1 illustrates how these two functions can be used. A string is read
from the keyboard and then the integer and the real number represented by this
string are printed.
Program 5.3.1
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void main(void){
char str[20];
printf("Enter the string: ");
scanf("%s", str);
printf("Converted to integer: %d", atoi(str));
printf("\nConverted to real: %f", atof(str));
getch();
}
When the program is run, the user is asked to enter a string. If, for instance, the
string is 14.7, then the program will print:
Converted to integer: 14
Converted to real: 14.700000
If the user enters a non-numerical value (for instance abc2,7), then the printed
result will be:
Converted to integer: 0
Converted to real: 0.000000

5.4 Other functions


This paragraph presents several functions that are frequently used. They are part
of different categories; for this reason, they were grouped under the name other functions.
5.4.1 void clrscr(void);
The function clears the screen in text mode (its name stands for clear screen)
and places the cursor in the upper left corner of the window. It doesnt have
71

Computer Programming The C Language


arguments and doesnt return anything. The header file that contains this function is conio.h. Example 5.4.1 uses this function.
Program 5.4.1
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void main(void){
clrscr();
printf("This is an example.\n");
printf("Press any key to clear the screen.");
getch();
clrscr();
printf("The screen was cleaned.");
getch();
}
At the beginning of the program, function clrscr() clears the screen; this
way, the results displayed by previous running sessions of other programs or of
the current program are not visible anymore. Then, on several lines, the sentences This is an example. and Press any key to clear the
screen. are printed. After that follows another call of the function
clrscr() and the screen is cleared again. Next, the message The screen
was cleaned. is displayed and the program ends after a key is pressed.
5.4.2 int random(int num);
Using this function a random integer number between 0 and num-1 is generated. For example, the call random(100) (program 5.4.2) will generate an
integer between 0 and 99.
Program 5.4.2
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void main(void){
clrscr();
printf("%d",random(100));
getch();}
72

5 Library Functions
If the program is repetitively run, it can be observed that the generated number
is the same. If this case is not accepted in a program, then the function void
randomize(void); must be called before; this will initialize the generator
of random numbers making the connection to the system clock, which, obviously, is modifying continuously. This way, function random() that is called
will not start from the same number. Program 5.4.3 is a complete example of
random number generator.
Program 5.4.3
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void main(void){
clrscr();
randomize();
printf("%d",random(100));
getch();
}
Both functions, random() and randomize(), are part of the stdlib.h
header file.
5.4.3 void exit(int status);
The call of this function causes the ending of the program. If there are other
instructions after exit(), these will not be executed. The function doesnt
return anything and receives as argument the exit status of the program, status
that is sent to the calling process (usually the operating system). Typically, the
value zero of the argument status indicates a normal exit and a non-zero
value is connected to a certain error. In order to use this function, the
stdlib.h header file must be included in the program.
Example 5.4.4 calls function exit() to quit the program after the first message (The program is ending here.) is displayed. The instruction
that prints the second message (This message wont be displayed.) is not executed.
Program 5.4.4
#include <stdio.h>
73

Computer Programming The C Language


#include <conio.h>
#include <stdlib.h>
void main(void){
clrscr();
printf("The program is ending here.");
getch();
exit(0);
printf("This message wont be displayed.");
}

5.5 Questions and exercises


A. Find the error.
1. #include <stdio.h>
#include <math.h>
void main(void){
float a=49,x;
x=sqrt(a);
printf("The result is: ",x);
}
2. void main(void){
int a;
float b,x;
a=7; b=3.54;
x=a+b;
printf("The result is: %5.2f",x);
}
3. #include <stdio.h>
#include <math.h>
void main(void){
int a,x;
scanf("%d",a);
x=fabs(a);
printf("The absolute value is: %d",x);
}
4. #include <stdio.h>
void main(void){
74

5 Library Functions
int a,b,x;
scanf("%d",&a); scanf("%d",&b);
x=a+b;
printf("The result is: " %5d,x);
}
5. #include <stdio.h>
void main(void){
int a;
float b,x;
a=7; b=3.54;
x=a+b;
printf("The result is: %5.2d",x);
}
6. #include <stdio.h>
void main(void){
int a,b,x;
a=7; b=3;
x=a+b;
printf("The result is: x=%4.1f",x);
}
7. #include <stdio.h>
#include <math.h>
void main(void){
float a=-49.7,x;
x=sqrt(a);
printf("The result is: %.2f",x);
}
B. Considering the following programs, specify what will be printed on the
screen after these programs are executed.
8. #include <stdio.h>
void main(void){
float x=39;
printf("%.1f",x/4);
}
9. #include <stdio.h>
#include <conio.h>
void main(void){
75

Computer Programming The C Language


int x=7;
clrscr();
printf("Sunday \\%d PM\\\t\"Tosca\" Giacomo
PUCCINI",x);
}
10. #include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void main(void){
float x=20, y=5.5;
clrscr();
exit(0);
printf("%.1f/%.1f=%.3f",x,y,x/y);
getch();
}
C. Choose the correct answer (one only).
11. Which of the following functions is an output one?
a) gets(); b) getch(); c) printf(); d) scanf();
e) getchar().
12. Which of the following functions is an input one?
a) getch(); b) printf(); c) clrscr(); d) #include;
e) all answers are wrong.
13. Which letter can be used to specify the type of the displayed argument
in printf() function?
a) d; b) c; c) f; d) s; e) all of them.
14. Which of the following functions is an output one?
a) printf(); b) puts(); c) putch(); d) putchar();
e) all of them.
15. What happens when function scanf("%f",x) is executed?
a) a float variable is read; b) a float variable is printed; c) an
image is scanned; d) the program ends because an error occurs during
the execution of the function; e) all answers are wrong.

76

5 Library Functions
16. The default alignment when function printf() is used to display
something is:
a) to the left; b) centered; c) to the right; d) justified; e) all answers are wrong.
17. Which of the following format descriptors (used in the printf()
function) are wrong?
a) %-7s; b) %7.3f; c) %d; d) %c; e) all answers are wrong.
18. What type of variables are read by the call of the function
scanf("%d%c", &x,a);?
a) a real number and a char; b) an integer and a char; c) an integer and a string; d) a real number and a string; e) the instruction contains an error.
D. Write programs to solve the following problems.
19. Calculate and display the sum of two real numbers whose values are
read from the keyboard.
20. Transform the dimension of an angle from degrees into radians (180=
radians). Suppose that the number entered by the user is valid.
21. Use the mathematical functions sqrt, log, exp, pow, fabs. Check
what happens during the execution of the program if the arguments sent
to these functions are wrong (for instance, square root of a negative
number).
22. Find and display the last digit of an integer.
23. Print on the screen (using a single instruction) the following text lines:
"C language" \ Dennis RITCHIE
#1972

77

Chapter 6
Instructions
According to the previous chapters, C programs contain several entities: preprocessor directives, declarations of variables and different mechanisms used to
execute the actions for which the program was created. The latter are called
instructions [HS98], [BH92] and may be subject to the following classification:
simple instructions: assignments and function calls;
compound instructions:
o associative: blocks of instructions; they group two or more instructions that have some connection in the logic of the programs execution; these blocks of instructions are delimited using open curly bracket { at the beginning of the block and close
curly bracket } at the end of the block;
o alternative: if, switch; these instructions are used when, according to a condition, only certain branches of the program can
be executed;
o repetitive: for, while, do while; these are used when one
or more instructions have to be repeated.
Compound instructions are used to control how the program behaves when it is
run. Two jump instructions are presented within: break and continue.
The names of the instructions are keywords in the C programming language;
this means that these words can only be used for the purpose for which they
were created. It is not possible to define variables, constants, data types or
functions with the names of these instructions. The list of keywords of the C
programming language is available in Appendix 2.
The instructions are components of the C programming language. They are not
part of any library, therefore is not necessary to include any header file when
they are used.

6 Instructions

6.1 Simple instructions


This category contains assignments and function calls. These were already used
in examples from the previous chapters, but without emphasizing that they are
in fact instructions.

6.1.1 The assignment instruction


This is used to give a value to a variable and is a simple way of executing a
certain task in a program. The general form of the assignment instruction is:
variable_name assignment_operator expression;
The expression can be a simple constant or a complex entity that contains
arithmetical, logical or relational operations. The result of the expression is
converted to the data type of the variable from the left side of the assignment.
The destination of the assignment (the place where the result of the assignment
is stored) must be a variable; it cannot be a constant or a name of a function. In
turn, the assignment operator can be simple or compound.
The simple assignment operator = gives the variable on its left side the value
of the expression on its right side. Here are several examples of using this operator:
x=7;
y=3+4;
delta=b*b-4*a*c;
z=sqrt(x);
The compound assignment operators have the form op=, where op can be,
among others, +, -, *, /, %. Regarding the effect of these operators, the instruction
var op= expression;
is equivalent to
var = var op expression;
These compound assignment operators were widely described in the chapter
about data and data types. Examples of using this sort of operators can be considered the following:
79

Computer Programming The C Language


sum+=x; //equivalent to sum=sum+x;
a*=(3*m+n); //equivalent to a=a*(3*m+n);
The multiple assignments can be used in the C programming language to give
the same value to more than one variable in the same instruction. In the following example the value zero is assigned to the variables a, b and c:
a=b=c=0;

6.1.2 The function call


The call of a function, either library function or user-defined function, is also
considered a simple instruction. When the function is called, the name of the
function and the list of its arguments must be specified; then the value returned
by the function (if there is such a value) can be used. The following instructions
are examples of function calls.
puts("This is a function call");
printf("The result is: %.2f", sqrt(x));
y=log(fabs(x));
getch();

6.2 Alternative instructions


When using the alternative instructions, the program is organized in two or
more branches and the sequences of code that form those branches are executed
after a condition is evaluated. Therefore, according to the value of truth of an
expression, the block of instructions from a certain branch is executed or not.
The test that is performed has a logical value and the result can be true or false.
In the C programming language, true is equivalent to any nonzero value (even
negative numbers mean true from logical point of view) and false is represented
by zero.
The instructions if and switch are part of this category. These are also called
selection instructions and are described in the following paragraphs.

80

6 Instructions

6.2.1 The if instruction


This is the simplest alternative instruction. It has two branches and, according
to a condition, executes one of them. Figure 6.2.1 is a graphical representation
of its functionality. A certain expression is evaluated; if the result is true, then a
branch is executed, otherwise, the other branch is executed. Then the program
continues with the instructions that follow.

false

EXPRESSION

Instructions
block 2

true

Instructions
block 1

Figure 6.2.1 The if instruction

The general form of the if instruction is:


if(expression)
//instructions block 1
else
//instructions block 2
The instructions blocks can contain one or more instructions. If there is more
than one instruction, it is mandatory to group those using curly brackets. Otherwise, compilation errors will occur or the program will not function according
to the requirements.
81

Computer Programming The C Language


When, during the execution of a program, an if instruction is encountered, the
expression (which must be enclosed by parentheses) is evaluated first. If it is
true (this means that the result is not zero), then instructions block 1
is executed (the one that follows the if). Otherwise (if the expression is false,
meaning zero), instructions block 2 is executed (the one that follows
the else).
The expression evaluated by the if instruction can be relational, logical or
arithmetical. The operators used by these expressions were already presented in
the chapter about data and data types. Several examples of expressions evaluated by the if instruction are hereby presented.
a>b is true if a is greater than b;
x==0 is true if x is zero;
m!=n is true if m is not equal to n;
(x<y)&&(z!=0) is true if x is less than y and if z is not equal to zero;
a||b is true if a is not equal to zero or if b is not equal to zero (in other
words, if at least one of the variables a and b is not equal to zero);
a+b is true if the sum of the numbers a and b not equal to zero;
1 is always true;
7 is always true;
0 is always false.
Program 6.2.1 reads from the keyboard the mark of a student. If this is greater
than or equal to 5, then the message Passed is displayed, otherwise, the message Failed is displayed.
Program 6.2.1
#include <stdio.h>
#include <conio.h>
void main(void){
int mark;
clrscr();
printf("Mark="); scanf("%d", &mark);
if (mark>=5)
printf("Passed");
82

6 Instructions
else
printf("Failed");
getch();
}
If the branches of if or else need more than one instruction, then these must
be grouped in a block using curly brackets. In example 6.2.2 the exam and
laboratory marks are read. If both of them are greater than or equal to 5, then
the final mark is calculated and displayed. Otherwise, only a message is printed.
Program 6.2.2
#include <stdio.h>
#include <conio.h>
void main(void){
float em, lm, fm;
clrscr();
printf("Mark for the exam: "); scanf("%f", &em);
printf("Mark for the lab: "); scanf("%f", &lm);
if ((em>=5)&&(lm>=5)){
printf("The student passed");
fm=(2*em+lm)/3;
printf("\nThe final mark is: %.2f", fm);
}
else
printf("The student failed");
getch();
}
The else part of the if instruction is optional; this means that it is possible to
write instructions that dont execute anything if the evaluated expression is
false. Program 6.2.3 is an example in this way. A temperature sensor whose
value is read from the keyboard is considered, as well as a variable that causes
the air conditioning (that is initially stopped) to be turned on. If the read temperature is greater than 25 degrees, then the message The air conditioning was turned on is displayed and the variable sw is set. The
else branch is missing, so the program doesnt execute any action if the temperature is less than or equal to 25 degrees.
Program 6.2.3
#include <stdio.h>
83

Computer Programming The C Language


#include <conio.h>
void main(void){
int temperature, sw=0;
clrscr();
printf("Temperature=");
scanf("%d", &temperature);
if (temperature>25){
printf("The air conditioning was turned on ");
sw=1;
}
getch();
}
Other if instructions can be included inside an if instruction. This is called
nested if instruction. In program 6.2.4 the age of a person who wants to vote is
read from the keyboard. First, the value that is read is verified in order to be
validated (if it is a negative value, it cannot represent the age and the message
Incorrect value is displayed). If the number is valid, then it is verified if
that person has the permission to vote (if he or she is at least 18 years old).
Program 6.2.4
#include <stdio.h>
#include <conio.h>
void main(void){
int age;
clrscr();
printf("Age=");
scanf("%d", &age);
if (age>0)
if (age>18)
printf("You can vote.");
else{
printf("You
dont
have
the
permission
vote.\n");
printf("Come back in %d years.",18-age);
}
else
printf("Incorrect value.");
getch();
}
84

to

6 Instructions
When cascading checks are required, then the if-else-if structure can be
used. This is in fact an if instruction on the else branch of another if instruction. Program 6.2.5 is an example of this kind of use. According to the
average mark of a student, which is read from the keyboard (the variable av), a
scholarship is granted (the variable sch). The value of the scholarship is set
after some cascading tests.
Program 6.2.5
#include <stdio.h>
#include <conio.h>
void main(void){
float av, sch;
clrscr();
printf("The average mark=");
scanf("%f", &av);
if (av>=9.5)
sch=1000;
else if (av>=8.5)
sch=800;
else if (av>=8)
sch=500;
else
sch=0;
printf("The scholarship is: %f", sch);
getch();
}

6.2.2 The switch instruction


This is an alternative instruction with several branches where the value of an
expression (or simply of a variable) is successively compared to the elements of
a list of integer or char constants. When the value of the expression is identical
to an element of the list, then the instructions of that branch are executed. If
none of the elements of the list matches the value of the expression, then a final
sequence of instructions, dedicated to these cases, is executed. Figure 6.2.2 is a
graphical representation of how the switch instruction works.

85

Computer Programming The C Language

var = val1

true

Sequence of
instructions 1

false
var = val2

true

Sequence of
instructions 2

false

var = valN

true

Sequence of
instructions N

false
Sequence of
instructions

Figure 6.2.2 The switch instruction

The general form of switch instruction is:


switch (variable){
case constant1: sequence_of_instructions_1; break;
case constant2: sequence_of_instructions_2; break;
...
case constantN: sequence_of_instructions_N; break;
default: sequence_of_instructions;
}
86

6 Instructions
The variable is successively compared to each constant marked by a case
instruction. When a constant matches the value of the variable, then the sequence of instructions of that case branch is executed until a break instruction is encountered or until the switch instruction is ended. The default
branch is dedicated to the case when the value of the variable doesnt match any
of the considered constants. This is an optional branch; if it is not present and
the variable is not equal to any constant of the list, than the entire switch
ensemble will not generate any action.
Regarding the comparison made between the variable and the constants of the
list, this cannot be any relational expression, but only an equality check. In
other words, the switch instruction cannot verify if a variable is less or greater than a certain value, but only if the variable has exactly that value.
The constants of the list must be unique. It is not possible to have more than one
case branch with the same constant. These constants must also be integers or
chars (which are automatically converted to integers).
Break is a jump instruction. When it is encountered inside a switch instruction, a jump to the first instruction that follows the switch is executed. If
there are several nested instructions, then break will only affect the switch
instruction it belongs to, not a possible other instruction containing this
switch. Therefore, break acts only at the level on which it stands.
Usually, the switch instruction is used to process the users options when
he/she selects something from a menu. Program 6.2.6 is an example in this way.
The user has a menu with several mathematical operations (1 for addition, 2 for
subtraction, 3 for multiplication and 4 for division). He enters the values for the
variables x and y and then presses the key associated to his option. Inside a
switch instruction this option (which is an integer number) is compared to the
four possible values. If it is one of these, then the related operation is executed
and the result is displayed; after this, because of the presence of break instruction, a jump to the instruction that follows the switch (getch(), in this
case) is made. If the user enters a number that is not 1, 2, 3, or 4, then the
instruction of the default branch is executed, displaying an error message,
which informs the user that the option he entered doesnt exist.
Program 6.2.6
#include <stdio.h>
#include <conio.h>
87

Computer Programming The C Language


void main(void){
int option;
float x, y, res;
clrscr();
printf("x="); scanf("%f",&x);
printf("y="); scanf("%f",&y);
printf("\n1 - Add");
printf("\n2 - Sub");
printf("\n3 - Mul");
printf("\n4 - Div");
printf("\nEnter your option ");
scanf("%d", &option);
switch(option){
case 1: res=x+y; printf("\nx+y=%.2f",res);
case 2: res=x-y; printf("\nx-y=%.2f",res);
case 3: res=x*y; printf("\nx*y=%.2f",res);
case 4: res=x/y; printf("\nx/y=%.2f",res);
default: printf("\nWrong option");
}
getch();
}

break;
break;
break;
break;

The break instruction, which is placed at the end of the case branches, is not
mandatory. It closes the sequence of instructions that belongs to a constant. If it
is omitted, then the instructions belonging to the next branches are executed,
until a break instruction is encountered or the switch instruction is ended.
Example 6.2.7 emphasizes this aspect. The user enters the value of an integer
variable x and has the possibility to increment it once (the option 1), to increment it twice (the option 2), to decrement it once (the option 3) or to decrement
it twice (the option 4).
Inside the switch instruction, the case branch that firstly appears is that for
the option 2 (double increment). On this branch there is a single instruction for
increment. However, the result that is displayed is correct. This is because the
break instruction of this branch is missing; therefore the instructions of the
next branch (those belonging to the option 1) are executed. There is also an
instruction that increments the variable, followed by a break; this makes the
switch instruction end and the result to be displayed. If the user chooses
option 1, the variable is normally incremented because that case branch
doesnt have anything special.
88

6 Instructions
Options 3 and 4 are not implemented yet and it is required that when the user
chooses one of these options, the message Unimplemented option is
displayed. The case branch that belongs to option 3 doesnt have any instruction (not even break); this emphasizes another important aspect: a case
branch can be empty. In this case, the instructions from the following branches
will be executed: the message regarding the option that is not implemented is
displayed (this message is also displayed if the user chooses option 4).
Program 6.2.7
#include <stdio.h>
#include <conio.h>
void main(void){
int option, x;
clrscr();
printf("x="); scanf("%d",&x);
printf("\n1 - Single increment");
printf("\n2 - Double increment");
printf("\n3 - Single decrement");
printf("\n4 - Double decrement");
printf("\nEnter your option ");
scanf("%d", &option);
switch(option){
case 2: x++;
case 1: x++; break;
case 3:
case 4: printf("Unimplemented option"); break;
default: printf("\nWrong option");
}
printf("\nx=%d", x);
getch();
}
If break instructions are not used on some case branches, then the instructions belonging to different branches are executed together. This increases the
efficiency of a program because redundancy is avoided (it is not necessary to
write twice some code lines). But the programmer must be very careful with
these aspects. They are very useful, but they can also produce improper functionalities of the programs if they are not correctly used.

89

Computer Programming The C Language

6.3 Repetitive instructions


If during the execution of a program it is necessary to repeat a sequence of
code, then one of the repetitive instructions that C programming language provides must be used. These are also called iterative instructions and the block of
instructions that they repeat is called loop. The sequence of code is repeated
according to a condition. In C programming language there are three repetitive
instructions, for, while and do while, which are hereby presented.

6.3.1 The for instruction


This repetitive instruction is used to execute a sequence of code for a preknown number of times. The first step of the instruction is an initialization.
Then, an expression is evaluated. If it is false, then the block of instructions
belonging to for is not executed and the program continues with the instructions that follow the for. If the expression is true, then the instructions from
the loop are executed. At the end of the loop an action is performed and then the
expression is evaluated again. Figure 6.3.1 is a graphical presentation of these
steps.

Initialization

EXPRESSION

false

true
Block of
instructions

Action

Figure 6.3.1 The for instruction

90

6 Instructions
The general form of the for instruction is:
for(initialization;expression;action)
//block of instructions
The for instruction usually has a variable of control; through this variable, it
establishes how many times the loop is repeated. The initial value of this variable is set in an assignment made in the first step executed by the for instruction: initialization.
The expression that is then evaluated determines when to stop the repeating
of the loop. The block of instructions is executed as long as the expression is
true (the result of its evaluation is not zero).
The action that is performed at the end of each iteration specifies how the
control variable is changed as the loop repeats. Usually this action increments
the value of the control variable, but other kind of operations are also possible.
All these three entities of the for instruction are optional. If the expression is
missing, it is considered that it is true.
The entities are separated by semicolon. This is required even if the entities are
not present.
The program from example 6.3.1 calculates the sum of the first 100 natural
numbers. The control variable i receives the initial value 1, and the loop is
repeated until i becomes greater than 100. At the end of each iteration the
value of i is incremented. Because the loop contains a single instruction (addition of i to the partial sum), the curly brackets are not mandatory. The sum is
displayed after the for instruction is ended. The sum must receive an initial
value before its first use and this value is 0 (the identity element for addition).
If a product is calculated, then the initial value would be 1 (the identity element
for multiplication).
Program 6.3.1
#include <stdio.h>
#include <conio.h>
void main(void){
int i,s=0;
clrscr();
for(i=1;i<=100;i++)
s=s+i;
91

Computer Programming The C Language


printf("The sum is: %d", s);
getch();
}
In example 6.3.2 the loop contains several instructions; therefore the curly
brackets must be used to delimit them. The control variable i was changed too.
The squares of the even numbers less than or equal to 20 and greater than 0
must be calculated and displayed, in a descending order. Because a descending
order is needed, the control variable will receive as initial value a maximum
value (this means 20) and it will decrease each step until it becomes zero. Only
even numbers must be considered, so the control variable wont be decreased
with 1, but with 2 (i-=2 is similar to i=i-2).
Program 6.3.2
#include <stdio.h>
#include <conio.h>
void main(void){
int i,p;
clrscr();
for(i=20;i>0;i-=2){
p=i*i;
printf("%d ", p);
}
getch();}
In the for instruction the expression is evaluated right after the control variable
receives its initial value and before anything else is executed. For this reason, if
the expression is false from the beginning, then the block of instructions inside
for will never be executed. Program 6.3.3 is an example for this situation. The
natural numbers less than a given number n must be displayed. The counter i
starts from the value 0, it is incremented each step and the condition that is
evaluated before each execution of the loop is that i is less than n. Because n
has also the value 0, the condition is false and the loop is not executed even
once. Therefore, only the instruction outside the for, which displays the final
value of the control variable i, is executed. The value of i in that point of the
program is 0 because the for instruction didnt make any changes on it.
Program 6.3.3
#include <stdio.h>
92

6 Instructions
#include <conio.h>
void main(void){
int i,n;
clrscr();
n=0;
for(i=0;i<n;i++)
printf("%d ",i);
printf("The final value of i is: %d",i);
getch();
}
The for instruction can use two or more control variables. Their initializations
and changes must be separated by comma. The expression that is evaluated
must not necessarily refer to the control variables. Program 6.3.4 emphasizes
these aspects. It uses two variables i and j and displays their values during 10
iterations. The expression is a test performed only on variable i.
Program 6.3.4
#include <stdio.h>
#include <conio.h>
void main(void){
int i,j;
clrscr();
for(i=0,j=0;i<10;i++,j=j-i)
printf("%d %d\n",i,j);
getch();
}
As stated earlier in this chapter, the three elements that form the definition of
the for instruction are not mandatory. Some of them (even all of them) can
miss. The following examples emphasize this aspect.
It is possible to have a for instruction, which doesnt contain the action that
modifies the control variable. In program 6.3.5 the value of this variable is read
from the keyboard inside the loop. The value 1/i is calculated and displayed as
long as the user enters numbers that are not equal to zero.
Program 6.3.5
#include <stdio.h>
#include <conio.h>
93

Computer Programming The C Language


void main(void){
int i;
clrscr();
for(i=1;i!=0;){
printf("1/%d=%f ",i,1/(float)i);
printf("\nEnter another number ");
scanf("%d", &i);
}
getch();
}
Sometimes the control variable receives its initial value before the for instruction; in this case in obvious that this part will not be present anymore in the
definition of the for instruction. In example 6.3.6 a number n is read from the
keyboard. If it is odd (the reminder of the division by two is not zero), then the
initial value of the control variable will be 1, otherwise it will be 2. Inside the
for instruction the odd or the even numbers will be printed, according to the
users option (in fact according to the type odd or even of the number entered by the user). The printing is ended when the value 10 is exceeded.
Program 6.3.6
#include <stdio.h>
#include <conio.h>
void main(void){
int i,n;
clrscr();
printf("Enter a number "); scanf("%d", &n);
if(n%2!=0) i=1;
else i=2;
for(;i<=10;i=i+2)
printf("%d ",i);
getch();
}
The for instruction can be used to create loops that are executed an infinite
number of times. This is made with an empty expression; if the expression of
the for instruction is missing, then it is considered true. Of course this kind of
instruction would block the program because it infinitely repeats the loop.
Inside the for must be placed a break instruction, which is able to stop, in
certain conditions, the execution of the for instruction. Example 6.3.7 repeti94

6 Instructions
tively reads a character from the keyboard and stops only when the user enters
the letter 'z'.
Program 6.3.7
#include <stdio.h>
#include <conio.h>
void main(void){
char c;
clrscr();
for(;;){
c=getchar();
if(c=='z') break;
}
}
If some delays must be inserted in a program, then a for instruction with empty body can be used. Program 6.3.8 creates a delay; after the definition of the
instruction for follows a semicolon, meaning that it doesnt contain anything,
so it doesnt do anything, excepting it increments the control variable until this
reaches the threshold. In order to have a noticeable delay, the control variable
must have large values; for this reason it was declared as long int.
Program 6.3.8
#include <stdio.h>
#include <conio.h>
void main(void){
long int i;
clrscr();
printf("Wait!");
for(i=0;i<500000000;i++);
printf("\nThis was a delay.");
getch();
}

6.3.2 The while instruction


This instruction is another way of repeating a sequence of code. While is
especially used when the number of repeats is unknown. The loop is repeated as
95

Computer Programming The C Language


long as a condition is true (not equal to zero). As in for instruction case, the
condition is evaluated at the beginning; therefore, if the expression is false, the
block of instructions wont be executed even ones. Figure 6.3.2 is a graphical
representation of the while instruction and of its functionality.

true

EXPRESSION

Block of
instructions

false

Figure 6.3.2 The while instruction

The general form of this instruction is:


while (expression)
//block of instructions
The first step is to evaluate the expression. If this is true, the block of instructions is executed. Then the expression is evaluated again. These steps are
repeated until the expression becomes false; in this case the program continues
with the instruction that comes right after the while cycle.
Example 6.3.9 uses the while instruction to display, in a repetitive way, the
square root of a number x entered by the user. The loop is repeated until the
user gives a negative number. It can be observed that the variable x receives an
initial value; this in made in order to assure that the while loop is executed at
least once.
Program 6.3.9
#include <stdio.h>
#include <conio.h>
96

6 Instructions
#include <math.h>
void main(void){
float x=0;
clrscr();
printf("The square root is calculated\n.");
printf("Negative number -> end of the program.\n");
while (x>=0){
printf("Square root of %f is %f", x, sqrt(x));
printf("\nEnter a number ");
scanf("%f",&x);
}
}
Together with repetitive instructions a jump instruction is frequently used:
continue. This forces the program to execute the next iteration, ignoring the
lines of code that come after it until the end of the loop. It influences only the
iterative cycle that contains it and doesnt affect other outside instructions.
Program 6.3.10 reads numbers from the keyboard until the user enters the value
zero. If the read number is negative, it is transformed into a positive one and a
message informs the user about this. If the number is already positive, then a
jump to the next iteration is made using the continue instruction. This is also
an example where the variable x receives an initial value, which provides that
the loop is executed at least ones (this value will be overwritten anyway with
the first number entered by the user).
Program 6.3.10
#include <stdio.h>
#include <conio.h>
#include <math.h>
void main(void){
int x=1;
clrscr();
while (x!=0){
printf("Enter a number ");
scanf("%d",&x);
if (x>0) continue;
x=-x;
printf("The number was transformed.\n");
}}
97

Computer Programming The C Language


while instruction can be used to repeat an infinite number of times a sequence
of code. Program 6.3.11 creates a menu that is repetitively displayed on the
screen until the user enters the value zero. The expression that is evaluated by
while instruction is in fact a number (1 in this case), which has always a true
value. It ensures that while wont be interrupted because of this expression.
The program will be stopped by the call of function exit(), when the user
expresses this option.
Program 6.3.11
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <stdlib.h>
void main(void){
int option, x;
while(1){
clrscr();
printf("\n1 Absolute value");
printf("\n2 - Exponential");
printf("\n0 - Exit");
printf("\nEnter your option ");
scanf("%d", &optiune);
switch(option){
case 1:
printf("x="); scanf("%d",&x);
printf("%.2f",fabs(x)); break;
case 2:
printf("x="); scanf("%d",&x);
printf("%.2f",exp(x)); break;
case 0: exit(0);
default: printf("\nWrong option");
}
getch();
}
}

98

6 Instructions

6.3.3 The do while instruction


The third way of repeating a sequence of code is provided by the do while
instruction. It features a major difference from the other two repetitive instructions (for and while): the expression is evaluated at the end of each iteration;
this ensures that the block of instructions inside the do while cycle will be
executed at least once. The graphical representation of the do while instruction is provided in figure 6.3.3.

Block of
instructions

EXPRESSION

true

false

Figure 6.3.3 The do while instruction

The general form of this instruction is:


do{
//block of instructions
}while(expression);
The block of instructions is repeated until the expression becomes false.
do while instruction is frequently used to validate the users values. Program 6.3.12 calculates the surface of a square whose side L is read from the
keyboard. Since L represents a size, it cannot be negative or zero, therefore the
user is forced to enter a positive value. The reading is repeated as long as the
number that is entered is less than or equal to zero (see the third version of
solving this problem in chapter about logical diagrams).
99

Computer Programming The C Language


Program 6.3.12
#include <stdio.h>
#include <conio.h>
void main(void){
float L;
clrscr();
do{
printf("Enter the side: "); scanf("%f", &L);
}while(L<=0);
printf("The surface is: %.2f",L*L);
getch();
}
Repetitive menus can also be created using do while instruction. Program 6.3.13 is the example presented in the while instruction, but slightly
modified; therefore, the program isnt stopped by the call of the exit() function, but through the expression of do while cycle, expression that evaluates
the users option. The program will repeat the loop as long as the user enters 1
or 2. For any other option, the do while cycle stops.
Program 6.3.13
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <stdlib.h>
void main(void){
int option, x;
do{
clrscr();
printf("\n1 Absolute value");
printf("\n2 - Exponential");
printf("\nAny other number - Exit");
printf("\nEnter your option ");
scanf("%d", &option);
switch(option){
case 1:
printf("x="); scanf("%d",&x);
printf("%.2f",fabs(x)); break;
case 2:
100

6 Instructions
printf("x="); scanf("%d",&x);
printf("%.2f",exp(x)); break;
}
getch();
}while(option==1||option==2);
}

6.4 Solved problems


6.4.1 The program calculates and displays the absolute value of an integer
number x whose value is read from the keyboard (it doesnt use fabs() function).
Program 6.4.1
#include <stdio.h>
#include <conio.h>
void main(void){
int x;
clrscr();
printf("x=");scanf("%d", &x);
if(x>=0)
printf("|%d|=%d",x,x);
else
printf("|%d|=%d",x,-x);
getch();
}
6.4.2 Two real numbers, x and y, whose values are read from the keyboard, are
considered. The program calculates the value of the expression
E

e
x y,x
ln |x y|
2 y,x

Program 6.4.2
#include <stdio.h>
#include <conio.h>
#include <math.h>
101

Computer Programming The C Language


void main(void){
float x,y,e;
clrscr();
printf("x="); scanf("%f", &x);
printf("y="); scanf("%f", &y);
if (x>=y)
e=exp(x)+sqrt(x-y);
else
e=log(fabs(x-y))+2*y;
printf("E=%.2f",e);
getch();
}
6.4.3 An integer number, read from the keyboard, is checked whether it is even
or odd. A number is even if the reminder of the division by two is zero. It is
obvious that the number must be integer and not real as the modulo operator
(%) cannot be applied to real numbers and a real number cannot be considered
odd or even.
Program 6.4.3
#include <stdio.h>
#include <conio.h>
void main(void){
int n;
clrscr();
printf("n="); scanf("%d", &n);
if(n%2==0) printf("The number is even");
else printf("The number is odd");
getch();
}
6.4.4 The program calculates the maximum of three real numbers entered from
the keyboard. At the beginning, the algorithm considers that the first number is
the maximum. Then it compares this maximum value with the other two numbers. When it finds a number that is greater than the maximum, it modifies the
value of the maximum.

102

6 Instructions
Program 6.4.4
#include <stdio.h>
#include <conio.h>
void main(void){
float a,b,c,max;
clrscr();
printf("a="); scanf("%f", &a);
printf("b="); scanf("%f", &b);
printf("c="); scanf("%f", &c);
max=a;
if(b>max) max=b;
if(c>max) max=c;
printf("MAX:%.2f",max);
getch();
}
6.4.5 The coefficients of a first degree equation, two numbers a i b, are read
from the keyboard. Then the equation is solved and the result is displayed (see
also the logical diagram used to solve this problem in chapter 2).
Program 6.4.5
#include <stdio.h>
#include <conio.h>
void main(void){
float a,b,x;
clrscr();
printf("a=");scanf("%f", &a);
printf("b=");scanf("%f", &b);
if(a==0)
if(b==0)
printf("An infinite number of solutions");
else
printf("The equation doesnt have solutions");
else{
x=-b/a;
printf("The result is: %5.2f", x);
}
getch();}
103

Computer Programming The C Language

6.4.6 This program displays all natural numbers i[a,b] that can be divided
by n. The values for a, b and n are read from the keyboard. If a and b are not
in an ascending order, they are reversed using an auxiliary variable.
Program 6.4.6
#include <stdio.h>
#include <conio.h>
void main(void){
int i, n, a, b, aux;
clrscr();
printf("a="); scanf("%d", &a);
printf("b="); scanf("%d", &b);
printf("n="); scanf("%d", &n);
if(b<a){ //if it is not the correct order
aux=a; a=b; b=aux; //they are reversed
}
for(i=a;i<=b;i++) //the [a,b] range is scanned
if(i%n==0) //if the number is divisible by n
printf("%d ",i); //it is printed
getch();
}
6.4.7 The program reads n integer numbers and calculates the average of the
positive ones. Since the numbers are integers, a type conversion is required
when the average is calculated.
Program 6.4.7
#include <stdio.h>
#include <conio.h>
void main(void){
int i, n, sum=0, count=0, x;
float average;
clrscr();
printf("n="); scanf("%d", &n);
for(i=1;i<=n;i++){
printf("\nx="); scanf("%d",&x);
if(x>0){
104

6 Instructions
/*if the number is positive, it is added to the
sum and the variable that counts the number of
positive elements is incremented*/
sum=sum+x;
count++;
}
}
if(count==0)
printf("There are no positive numbers!");
else{
average=(float)sum/count;
printf("The average is: %.2f",average);
}
getch();
}

6.4.8 This problem is an example of repeating a set of instructions as long as the


user confirms that. Inside a do while cycle a real number is read and its
square is displayed. At the end of each iteration the user is asked if he/she wants
to continue or not.
Program 6.4.8
#include <stdio.h>
#include <conio.h>
void main(void){
float n;
int answer;
clrscr();
do{
printf("\nEnter a number: ");
scanf("%f", &n);
printf("The square of %.2f is: %.2f", n, n*n);
printf("\n\nContinue (1=Yes/0=No)? ");
scanf("%d", &answer);
}while(answer==1);
}

105

Computer Programming The C Language


6.4.9 The program verifies if a natural number n is a prime number or not. First,
in a do while cycle, the user is forced to enter a natural number. The algorithm stars from the premise that the number is prime (this information is stored
in a variable called flag, with the value 1). Then the range [2, n/2] is
scanned and if n can be divided by at least one of these numbers, it is not
prime; the flag variable receives the value 0 and the for cycle is left using a
break instruction. At the end of the program the flag is verified; if it is
still 1, then the number is prime.
Program 6.4.9
#include <stdio.h>
#include <conio.h>
#include <math.h>
void main(void){
int i, n, flag=1;
clrscr();
do{
/*the user is forced to enter a positive number*/
printf("n="); scanf("%d", &n);
}while(n<=0);
for(i=2;i<=n/2;i++)
if(n%i==0){
/*if n is divisible by i, then it is not prime;
the for can be leaved because the next checks
dont have sense anymore*/
flag=0;
break;
}
if(flag==0)
printf("%d is not prime", n);
else
printf("%d is prime", n);
getch();
}
6.4.10 The greatest common divisor of two natural numbers is determined using
the Euclids algorithm. First, the user must be forced to enter two natural numbers. The reading of each number is made in a do while instruction that can
106

6 Instructions
be left only if the number is valid. Second, the numbers must be in descending
order; if not so, they must be reversed. After these two conditions are accomplished, the greatest common divisor can be determined.
Program 6.4.10
#include <stdio.h>
#include <conio.h>
void main(void){
int m, n, r, aux;
clrscr();
do{
printf("M="); scanf("%d", &m);
}while(m<=0);
do{
printf("N="); scanf("%d", &n);
}while(n<=0);
if (m<n){
aux=m;
m=n;
n=aux;
}
/*Here starts the Euclids algorithm*/
r=m%n;
while (r!=0){
m=n;
n=r;
r=m%n;
}
printf("\nThe greatest common divisor: %d", n);
getch();
}

6.5 Questions and exercises


A. Find the error (considering that all variables are correctly defined and all
header files are included).
1. if(a>b)
printf("a greater than b");
107

Computer Programming The C Language


E=(a+2*b)/3;
else
printf("a less than or equal to b");
E=(2*a+b)/3;
printf("E=%.2f", E);
2. for(i=0, i<n, i++){
//set of instructions
}
3. if a<0
a=fabs(a);
4. for(i=0; i<n; i++);{
//set of instructions
}
5. if((a<0)&(b<0)){
//set of instructions
}
6. do while(n<=100){
//set of instructions
}
7. for(i==0;i<n;i++){
//set of instructions
}
8. for(i=100;i>0;i++)
printf("%d ", i);
9. n=10;
do{
n--;
}while(n<10)
B. Considering the following programs, specify what will be printed on the
screen after these programs are executed.
10. #include <stdio.h>
void main(void){
int a=5, b=7, x=0, y=0;
if((a<b)&&(a!=0))
x=a+b;
108

6 Instructions
else if((a>0)&&(b>0))
y=a*b;
printf("x=%d, y=%d", x, y);
}
11. #include <stdio.h>
#include <conio.h>
void main(void){
int i;
clrscr();
for(i=1;i<0;i++)
printf("%d ",i);
getch();
}
12. #include <stdio.h>
#include <conio.h>
#include <math.h>
void main(void){
float r;
clrscr();
do{
printf("r="); scanf("%f",&r);
}while(r<=0);
printf("%.2f", 2*M_PI*r);
getch();
}
C. Choose the correct answer (one only).
13. Which of the following operators cannot be used in a comparison?
a) >=; b) <=; c) +=; d) ==; e) all answers are wrong.
14. Which of the following instructions is an alternative one?
a) while; b) if; c) break; d) for; e) all answers are correct.
15. After the instruction for(i=0; i<5; i++) is executed, the variable
i will have the value:
a) 0; b) 1; c) 4; d) 5; e) 6.
16. Which of the following instructions is a repetitive one?
109

Computer Programming The C Language


a) while; b) if; c) switch; d) break; e) all answers are
wrong.
17. Which of the following operators is an assignment operator?
a) =; b) +=; c) -=; d) %=; e) all answers are correct.
18. Which of the following numbers has a true logical value?
a) 1; b) -1; c) 7.5; d) -7; e) all of them.
19. The keyword else is connected to the instruction:
a) switch; b) if; c) while; d) do while; e) for.
20. Which will be the value of the variable x after the following sequence of
instructions is executed: x=0; a=2; b=3; if(a>0) if(a>b)
x++; else x--; else if(a>b) x+=2; else x-=2;
a) -2; b) -1; c) 0; d) 1; e) 2.
21. Which of the following instructions can be used to execute a jump?
a) break; b) for; c) while; d) do while; e) none of
them.
22. The keyword default is connected to the instruction:
a) for; b) if; c) while; d) switch; e) there is not such a
keyword.
23. Which iterative instruction ensures that the sequence of code it repeats
will be executed at least once?
a) for; b) while; c) do while; d) all; e) none.
24. Which of the following keywords is the name of a jump instruction?
a) if; b) switch; c) case; d) continue; e) default.
25. Which is the repetitive instruction with initial test and unknown number
of iterations?
a) while; b) do while; c) for; d) continue; e) repeat.
D. Write programs to solve the following problems.
26. The value of a real number x is read from the keyboard. Calculate and
display the value of the function
110

6 Instructions
f(x)=max{7x2-3,|25-x|}.
27. Calculate and display the roots of the second degree equation (the coefficients a, b and c are real numbers and they are read from the keyboard).
28. The values of the three real numbers a, b and c are read from the keyboard; they represent the sides of a triangle. Calculate and display the
surface of the triangle. Herons formula will be used:
A

s s

a s

b s

where s is the semi-perimeter (a+b+c)/2. In order to calculate the


surface, the numbers must be positive and must form a triangle; this
means that the sum of any two sides must be greater than the third side
(for instance, the values 2, 4 and 100 cannot be the sides of a triangle).
29. Read three real numbers a, b and c and verify if they can be the sides of
a right-angled triangle. Besides the fact the numbers must be positive,
they should verify Pythagoras theorem: the sum of the squares of the
legs (the two sides that meet at the right angle) is equal to the square of
the hypotenuse (the side opposite the right angle).
30. Simulate the behavior of an electronic calculator for real numbers; the
program must allow the user to enter two numbers and a char that
represents the operation (+, , *, /).
31. The value of a real number x is read from the keyboard. Write a program that calls several mathematical functions through the following repetitive menu:
1 - e
2 ln x
3 - x
4 - |x|
5 - e
0 - Exit
32. Display the squares of the first n natural numbers.
33. A natural number n is read. Calculate n! (the factorial of n).
111

Computer Programming The C Language


34. The value of a natural number n is read. Calculate the sum of the digits
that form the number n. The last digit of a number is the reminder of its
division by 10. The other part of the number is the quotient of its division by 10.
35. A natural number n is read from the keyboard. Find and display all its
divisors. Any natural number n has the values 1 and n as divisors. Excepting these, the smallest divisor of a number can be 2 and the greatest
n/2. Therefore, in order to find the divisors of a natural number n, the
range [2, n/2] must be scanned.
36. Read from the keyboard n integer numbers. Determine which is the
smallest and which is the greatest.
37. Several marks are read from the keyboard (until the value 0 is entered).
Display how many students passed the exam (each student has a single
mark).
38. Read n real numbers. Calculate and display the product of non-zero values.
39. Display the first 20 Fibonacci numbers:
f1=0, f2=1, f3=1, f4=2, , fi=fi-2+fi-1.

112

Chapter 7
Arrays
An array is a homogeneous collection of variables; therefore the elements that
form an array must have the same type. Each element of an array has allocated
its own memory space. In C programming language arrays are made of adjacent
memory locations; the first element of an array has the smallest memory address and the last one has the greatest memory address [HS98].
Within an array, each element is identified and accessed through one or more
indexes. These indexes can only have integer values [DL06]. In C programming
language the numbering of indexes starts at 0 and each index is written inside
square brackets.
When an array is declared, it receives a name and it is associated to a data type.
The array can have one or more dimensions. Therefore they can be classified in:
single-dimensional arrays are the programming version of mathematical
vectors and are also used to represent strings (sequences of characters);
two-dimensional arrays represent the mathematical matrices and are organized on rows and columns;
multi-dimensional arrays are rarely used because they need a huge adjacent memory space and a lot of time is consumed to access their elements;
the dynamic memory allocation is usually used for this kind of variables
[HS98].
The following paragraphs describe the arrays with one and two dimensions
because they are most commonly used. Strings are closely related to this subject; they are in fact single-dimensional arrays of elements that have the type
char. Their description is made separately, in one of the next chapters.

7.1 Single-dimensional arrays


They are also called vectors because they take the features of these mathematical entities. A single-dimensional array has a name, a data type and a number of
elements. The indexes of these elements start with the value 0. Figure 7.1.1 is
the graphical representation of a vector with the name v, which has n integer
elements.

Computer Programming The C Language

-3

12

-9

n-2

n-1

Figure 7.1.1 Graphical representation of a single-dimensional array

7.1.1 Declaring a single-dimensional array


As any other variable, a single-dimensional array must be declared before it can
be used. The general form of its declaration is:
type name[dimension];
The type of the table is in fact the type of each of its elements. The name is
subject to the same restrictions applied to any other name of variable (see the
indications regarding the name of a variable from the chapter about data and
data types). The dimension indicates the number of elements that form the
array.
The following examples declare two single-dimensional arrays. The fist one is a
vector of maximum 10 integer numbers, called v. The second one is called
marks and can contain 50 elements of float type.
int v[10];
float marks[50];

7.1.2 Accessing elements


The indexes of the elements are consecutive integer numbers that start from
zero. If, for instance, an array has the dimension 10, the indexes will be: 0, 1,
2, , 9. Each index identifies an element of the array, specifying its position in
the array. Through its index, the element can be accessed.
Considering the vector in figure 7.1.1, element v[2] is the third element of this
array and it has the value 7. Its value can be modified through an instruction as:
v[2]=14;.

114

7 Arrays

7.1.3 Initialization of elements


The elements of a single-dimensional array can be initialized when the array is
declared. The following example declares an array of five real numbers. The
first three elements of the array receive their initial values at declaration; the
last two elements will have the value zero.
float values[5]={2.4, 7.1, -3};
If the dimension of an array is not explicitly specified, but its elements receive
initial values, then it is considered that the array has as many elements as there
were initialized. In the following example an array of integer numbers is declared and seven elements receive initial values; the dimension of the array will
be considered 7.
int numbers[]={1, 7, -9, 17, 20, -70, 4};
If the elements of an array have not been initialized, then they probably contain
values that have no meaning for the program (values that are stored in their
memory locations). These elements should not be used before they receive
values (read from the keyboard or from a file or obtained through computation).

7.1.4 Reading the elements values from the keyboard


One of the methods used to get values to the elements of an array is reading
them from the keyboard. In order to do this, a repetitive instruction, usually
for, is used (because the number of the arrays elements is usually known).
In the following sequence of code the elements of an array v that contains n
integer numbers are read from the keyboard. When the program is run, the text
v[0]= is displayed and the execution waits for a number (the user must enter
a number); then the text v[1]= is printed and so on, until all the elements
receive values.
printf("Number of elements: ");
scanf("%d", &n);
for(i=0;i<n;i++){
printf("v[%d]=", i);
scanf("%d", &v[i]);
}
115

Computer Programming The C Language

7.1.5 Displaying the elements / Traversing an array


There is a standard sequence of code used to display the content of a singledimensional array; it traverses the array, accessing each of its elements. A for
repetitive instruction is also used here, as shown in the following example that
prints the elements of the same vector v of n integer numbers. These will be
displayed one after another, with a space between them.
for(i=0;i<n;i++)
printf("%d ", v[i]);
Once the elements of a single-dimensional array are read and, eventually, displayed, the array must be processed in some way or must be involved in some
operations. The following sequence of code traverses the array in order to calculate the sum of its elements. The sum is initialized by zero before the repetitive instruction and is displayed once the traversing of the array is finished.
sum=0;
for(i=0;i<n;i++)
sum=sum+v[i];
printf("\nThe sum is: %d", sum);

7.1.6 A complete example


Program 7.1.1 is a complete example of working with a single-dimensional
array. It contains the reading of the arrays elements, the printing of these elements and the traversing of the array in order to calculate the sum of its elements.
Program 7.1.1
#include <stdio.h>
#include <conio.h>
void main(void){
int v[20], n, i, sum=0;
clrscr();
printf("Number of elements: ");
scanf("%d", &n);
116

7 Arrays
for(i=0;i<n;i++){//reading the elements
printf("v[%d]=", i);
scanf("%d", &v[i]);
}
for(i=0;i<n;i++)//displaying the array
printf("%d ", v[i]);
for(i=0;i<n;i++)//calculating the sum
sum=sum+v[i];
printf("\nThe sum is: %d", sum);
getch();
}

7.2 Two-dimensional arrays


They are the representation of mathematical matrices. Two-dimensional arrays
have a number of rows and a number of columns whose numbering starts
from 0. From the graphical point of view, they look like in figure 7.2.1.
0

m-1

-3

11

-7

-1

17

.
.
.
.
.
n-1

Figure 7.2.1 Graphical representaion of a two-dimensional array

7.2.1 Declaring a two-dimensional array


The two-dimensional arrays are declared and accessed in C programming language using two sets of square brackets, one for each dimension. The general
form for the declaration of a matrix is:
117

Computer Programming The C Language


type name[rows][columns];
As any other variable, a matrix has a name and a type. The first dimension
specified is the number of rows and the second is the number of columns.
The matrix will have rows*columns elements.
The following example declares a matrix of integer numbers organized on 3
rows and 4 columns. Therefore, the matrix has 12 elements.
int matr[3][4];

7.2.2 Accessing elements


Each dimension of a matrix has its own set of indexes. If a matrix has n rows
and m columns, the indexes will be from 0 to n-1 for rows and from 0 to m-1
for columns, as shown in figure 7.2.1.
In order to access an element of a matrix, the index of the row and the index of
the column that contain that element must be specified. For instance, in figure
7.2.1 the element placed at the intersection of the row with the index 1 with the
column with the index 2 is matr[1][2] and it has the value 11. It can be
changed through an assignment instruction like: matr[1][2]=13;.

7.2.3 Initialization of elements


The elements of a matrix can receive initial values when the matrix is declared,
if this is necessary. The following example initializes a two-dimensional array
of 2 rows and 3 columns, containing integer numbers.
int matr[2][3]={
{7,-10,1},
{4,0,-32}
};
Not all the elements of a matrix must receive initial values. Those that are not
explicitly initialized will automatically receive the value 0. In the following
example a matrix of 3 lines and 4 columns is declared, but only the elements of
the first three columns receive values. The elements of the last column will
have the value 0.
118

7 Arrays
int matr[3][4]={
{1, 9, 12},
{-7, 40, 3},
{3, -2, 8}
};
This kind of initialization of the elements of a matrix is a very simple procedure, but it could be improper for two-dimensional arrays with large dimensions
or when the values must be read or calculated. For these reasons, mostly, the
elements of a matrix receive their values through some instructions during the
execution of the program.

7.2.4 Reading the elements values from the keyboard


An iterative structure is used to read the elements of a matrix. This structure
contains two nested for instructions. The first for is used to traverse the rows
and inside each row a second for is used to traverse the elements of that row.
The following sequence of code reads from the keyboard the elements of a
matrix with n rows and m columns. Messages like matr[0][0]=,
matr[0][1]= and so on will be displayed on the screen, waiting each time
for the users value.
printf("Number of rows: "); scanf("%d", &n);
printf("Number of columns: "); scanf("%d", &m);
for(i=0;i<n;i++)
for(j=0;j<m;j++){
printf("matr[%d][%d]=", i, j);
scanf("%d", &matr[i][j]);
}

7.2.5 Printing a matrix


The same two nested for cycles must be used to display a matrix, as can be
seen in the following sequence of code. Once the elements of a line are printed,
119

Computer Programming The C Language


the cursor must be moved on the next line; this is made through a
printf("\n"); instruction placed inside the first for, once the second
for is finished. For a better alignment, each element has 5 characters allocated.
for(i=0;i<n;i++){
for(j=0;j<m;j++)
printf("%5d ", a[i][j]);
printf("\n");
}

7.2.6 Traversing a matrix


A two-dimensional matrix can be traversed in several ways; the horizontal and
the vertical traversing, which are graphically represented in figure 7.2.2, are the
most frequently used. These are made through the same two for instructions
and have some particular features of each other.

a) horizontal

b) vertical
Figure 7.2.2 Traversing a matrix

In order to have a horizontal traversing of a matrix, the outside for refers to


the rows and the inside one refers to the columns (similar to the sequence that is
used to print the matrix). The following example executes a horizontal traversing of a matrix and calculates the sum of all the elements.
sum=0;
for(i=0;i<n;i++)
for(j=0;j<m;j++)
sum=sum+matr[i][j];
printf("The sum: %d", sum);
120

7 Arrays
In a vertical traversing, the outside for refers to the columns and the inside one
refers to the rows. Therefore, the index of the row is the one that changes more
often (unlike the horizontal traversing, where the index of the columns was the
one that was changed more often). The following example performs a vertical
traversing of a matrix and displays the elements in the accessing order.
for(j=0;j<m;j++)
for(i=0;i<n;i++)
printf("%3d ", a[i][j]);
It can be observed that the two fors used for the traversing were inverted,
compared to the horizontal traversing. This is because the traversing is made on
column, not on row.
If the matrix is
1 2 3 4
5 6 7 8
then
1 5 2 6 3 7 4 8
will be displayed on the screen (because of the vertical traversing).

7.2.7 Particular ways of traversing a square matrix


A square matrix is a particular matrix, which has the same number of rows and
columns. This type of matrix has several specific elements, revealed in figure 7.2.3: the main and the secondary diagonals and their upper and lower
triangles.

a) the main diagonal

b) the upper triangle of the


main diagonal

121

c) the lower triangle of the


main diagonal

Computer Programming The C Language

d) the secondary diagonal


(anti-diagonal)

e) the upper triangle of the


secondary diagonal

f) the lower triangle of the


secondary diagonal

Figure 7.2.3 Specific features of a square matrix

There are cases when only these parts of a matrix must be traversed, not the
entire two-dimensional array. The following sequences of code show how to
execute these types of specific traversing of a square matrix a that contains
integer numbers. The index of the row is represented by the variable i and that
of the column is represented by the variable j. The accessed elements are displayed in order to be identified.
traversing the main diagonal the elements belonging to the main diagonal
have the index of the row equal to the one of the column; therefore a single
for instruction is enough to access them; an element of the main diagonal
has the coordinates i and j;
for(i=0;i<n;i++)
printf("%3d ", a[i][i]);
traversing the upper triangle of the main diagonal for the elements placed
above the main diagonal the index of the row, i, belongs to the range
[0,n) and the index of the column, j, starts from i+1 and goes to n-1;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
printf("%3d ", a[i][j]);
traversing the lower triangle of the main diagonal at the elements placed
below the main diagonal, the index i also goes from 0 to n-1 and the index
j starts from 0 and stops before the element placed on the main diagonal
(the one on the column i);
122

7 Arrays
for(i=0;i<n;i++)
for(j=0;j<i;j++)
printf("%3d ", a[i][j]);
traversing the secondary diagonal the rows must be traversed downside up
(in the range [n,0)); between the index of the row and the one of the column there is a well-defined connection; therefore, in this case a single for
cycle is enough for the traversing; the elements of the secondary diagonal
have the coordinates i-1 and n-1;
for(i=n;i>0;i--)
printf("%3d ", a[i-1][n-i]);
traversing the upper triangle of the secondary diagonal for the elements
placed above the secondary diagonal both indexes start from 0; the i stops
before n and the j before n-i-1;
for(i=0;i<n;i++)
for(j=0;j<n-i-1;j++)
printf("%3d ", a[i][j]);
traversing the lower triangle of the secondary diagonal at the elements
placed below the secondary diagonal the index of row, i, also traverses the
range [0,n); the index of column, j, starts from n-i and stops at n-1.
for(i=0;i<n;i++)
for(j=n-i;j<n;j++)
printf("%3d ", a[i][j]);
There is considered a square matrix of 4 rows and 4 columns with the initial
values:
1

9 10 11 12
13 14 15 16
When the sequences of code previously presented are run, these will print:
for the main diagonal: 1 6 11 16;
123

Computer Programming The C Language


for the upper triangle of the main diagonal: 2 3 4 7 8 12;
for the lower triangle of the main diagonal: 5 9 10 13 14 15;
for the secondary diagonal: 13 10 7 4;
for the upper triangle of the secondary diagonal: 1 2 3 5 6 9;
for the lower triangle of the secondary diagonal: 8 11 12 14 15 16.

7.2.8 A complete example


Program 7.2.1 is a complete example of working with two-dimensional arrays.
It reads the values for the elements of a matrix, prints the matrix and calculates
the sum of all the elements.
Program 7.2.1
#include <stdio.h>
#include <conio.h>
void main(void){
int a[50][50], n, m, i, j, sum=0;
clrscr();
printf("Number of rows: ");
scanf("%d", &n);
printf("Number of columns: ");
scanf("%d", &m);
for(i=0;i<n;i++)//reading the elements
for(j=0;j<m;j++){
printf("a[%d][%d]=", i, j);
scanf("%d", &a[i][j]);
}
for(i=0;i<n;i++){//printing the matrix
for(j=0;j<m;j++)
printf("%3d ", a[i][j]);
printf("\n");
}
for(i=0;i<n;i++)//calculating the sum
for(j=0;j<m;j++)
sum=sum+a[i][j];
printf("The sum is: %d\n", sum);
getch();}
124

7 Arrays

7.3 Solved problems


7.3.1 Finding the minimum value in a single-dimensional array. In order to
solve this problem the program starts from the premise that the first element of
the vector is the minimum. Then the vector is traversed starting from its second
element; each element of the vector is compared with the minimum value at that
moment. If a value less than the minimum is found, then the minimum is modified and it will store the new minimum value.
Program 7.3.1
#include <stdio.h>
#include <conio.h>
void main(void){
int v[20], n, i, min;
clrscr();
printf("Number of elements: ");
scanf("%d", &n);
for(i=0;i<n;i++){//reading the elements
printf("v[%d]=", i); scanf("%d", &v[i]);
}
for(i=0;i<n;i++)//printing the array
printf("%d ", v[i]);
//finding the minimum value
min=v[0];//the first element is considered the min
for(i=1;i<n;i++)
/*the minimum is compared to each element*/
if (v[i]<min)
/*if an element less than the minimum is found,
then the minimum is changed*/
min=v[i];
printf("\nThe minimum is: %d", min);
getch();
}
7.3.2 Calculating the average age of the employees of a company. The ages of
the employees are read from the keyboard and stored in a single-dimensional
array. Each time an age is read, it is added to a variable that calculates the total
125

Computer Programming The C Language


age (therefore, the information is processed directly when it is read, not in an
additional repetitive structure). At the end, once the for is left, the total age is
divided to the number of employees to obtain the average age. Because both
total age and number of employees are integer variables, a type conversion is
required in order to have a correct result.
Program 7.3.2
#include <stdio.h>
#include <conio.h>
void main(void){
int age[100];
int n, i, total_age=0;
clrscr();
printf("Number of employees: ");
scanf("%d", &n);
printf("Enter the age of each employee.\n");
for(i=0;i<n;i++){
/*reads the age of each employee and adds it to
the total age*/
scanf("%d", &age[i]);
total_age=total_age+age[i];
}
/*the total age is converted to float in order to
obtain a correct result*/
printf("The average: %.2f", (float)total_age/n);
getch();
}
7.3.3 Finding and displaying the first 20 Fibonacci elements using a singledimensional array. A vector of 20 elements is declared and the first two locations receive the values 0 and 1 respectively. The array is traversed starting
from its third element (the one with the index 2) and the value of each element
is calculated as the sum of the elements with the indexes i-1 and i-2.
Program 7.3.3
#include <stdio.h>
#include <conio.h>
void main(void){
126

7 Arrays
int fibo[20];
int i;
clrscr();
/*the first two elements of the vector receive initial values (these values are known)*/
fibo[0]=0; fibo[1]=1;
/*the values of the next elements are calculated*/
for(i=2;i<20;i++)
fibo[i]=fibo[i-1]+fibo[i-2];
/*all the elements are displayed*/
for(i=0;i<20;i++)
printf("%d ", fibo[i]);
getch();
}
7.3.4 The minimum value in a two-dimensional array. At the beginning, the
value of the first element is considered the minimum. Then the entire matrix is
traversed, comparing the minimum with each element of the matrix; if a value
less than the minimum is found, then the minimum is changed.
Program 7.3.4
#include <stdio.h>
#include <conio.h>
void main(void){
int a[50][50], n, m, i, j, min;
clrscr();
printf("Number of rows: ");
scanf("%d", &n);
printf("Number of columns: ");
scanf("%d", &m);
for(i=0;i<n;i++)//reading the elements
for(j=0;j<m;j++){
printf("a[%d][%d]=", i, j);
scanf("%d", &a[i][j]);
}
for(i=0;i<n;i++){//printing the matrix
for(j=0;j<m;j++)
printf("%3d ", a[i][j]);
printf("\n");
127

Computer Programming The C Language


}
min=a[0][0];//initializing the minimum
for(i=0;i<n;i++)
for(j=0;j<m;j++)
/*each element is compared to the minimum*/
if (a[i][j]<min)
/*if a value less than the minimum is found,
then the minimum is changed*/
min=a[i][j];
printf("\nThe minimum value is: %d", min);
getch();
}
7.3.5 The sum of the elements on the main diagonal. The main diagonal is
traversed. A single for instruction is enough; because the elements of the main
diagonal have the index of row equal to the index of column, they will be accessed through the coordinates [i][i].
Program 7.3.5
#include <stdio.h>
#include <conio.h>
void main(void){
int a[50][50], n, i, j, sum=0;
clrscr();
printf("Number of rows: ");
scanf("%d", &n);
for(i=0;i<n;i++)//reading
for(j=0;j<n;j++){
printf("a[%d][%d]=", i, j);
scanf("%d", &a[i][j]);
}
for(i=0;i<n;i++){//printing
for(j=0;j<n;j++)
printf("%3d ", a[i][j]);
printf("\n");
}
for(i=0;i<n;i++)//traversing the main diagonal
sum=sum+a[i][i];
printf("The sum is: %d", sum);
128

7 Arrays
getch();
}
7.3.6 The number of odd elements placed below the main diagonal of a twodimensional array is found and these elements are displayed. Only that triangle
is analyzed (not the entire matrix), using a specific sequence of code: the index
of rows traverses the range [0,n), and the index of columns has values in the
range [0,i).
Program 7.3.6
#include <stdio.h>
#include <conio.h>
void main(void){
int a[50][50], n, i, j, count=0;
clrscr();
printf("Number of rows: ");
scanf("%d", &n);
for(i=0;i<n;i++)
for(j=0;j<n;j++){
printf("a[%d][%d]=", i, j);
scanf("%d", &a[i][j]);
}
for(i=0;i<n;i++){
for(j=0;j<n;j++)
printf("%3d ", a[i][j]);
printf("\n");
}
printf("The odd elements are: ");
for(i=0;i<n;i++)
for(j=0;j<i;j++)
if(a[i][j]%2!=0){
count++;
printf("%d ", a[i][j]);
}
printf("\nThere are %d odd elements", count);
getch();
}

129

Computer Programming The C Language


7.3.7 The product of two matrices. In order to calculate this product, the first
matrix must have a number of columns equal to the number of rows of the
second matrix. Therefore, the first matrix has n rows and p columns and the
second one has p rows and m columns. The elements of the product matrix have
the initial value 0 and are calculated according to the expression
c[i][j]=c[i][j]+a[i][k]*b[k][j], where i and k traverse the rows
and the columns of the first matrix and k and j traverse the rows and the columns of the second matrix.
Program 7.3.7
#include <stdio.h>
#include <conio.h>
void main(void){
int a[20][20], b[20][20], c[20][20];
int i, j, k, n, m, p;
clrscr();
printf("Matrix 1 number of rows ");
scanf("%d", &n);
printf("Matrix 1 number of columns ");
scanf("%d", &p);
/*the number of rows of the second matrix is equal
to the number of columns of the first matrix*/
printf("Matrix 2 number of columns ");
scanf("%d", &m);
for(i=0;i<n;i++)//reading the first matrix
for(k=0;k<p;k++){
printf("a[%d][%d]=",i,k);
scanf("%d", &a[i][k]);
}
for(k=0;k<p;k++)//reading the second matrix
for(j=0;j<m;j++){
printf("b[%d][%d]=",k,j);
scanf("%d", &b[k][j]);
}
printf("The first matrix is:\n");
for(i=0;i<n;i++){
for(k=0;k<p;k++)
printf("%3d",a[i][k]);
printf("\n");
130

7 Arrays
}
printf("The second matrix is:\n");
for(k=0;k<p;k++){
for(j=0;j<m;j++)
printf("%3d",b[k][j]);
printf("\n");
}
for(i=0;i<n;i++)//the product matrix is initialized
for(j=0;j<m;j++)
c[i][j]=0;
for(i=0;i<n;i++)//calculating the product matrix
for(j=0;j<m;j++)
for(k=0;k<p;k++)
c[i][j]=c[i][j]+a[i][k]*b[k][j];
printf("The product matrix is:\n");
for(i=0;i<n;i++){
for(j=0;j<m;j++)
printf("%3d",c[i][j]);
printf("\n");
}
getch();
}

7.4 Questions and exercises


A. Find the error (considering that all variables are correctly defined and all
header files are included).
1. The elements of a vector of 10 integer numbers must be read.
for(i=0;i<10;i++)
printf("a[%d]=",i);
scanf("%d",&a[i]);
2. A matrix of real numbers with 3 rows and 4 columns must be displayed.
for(i=0;i<3;i++)
for(j=0;j<4;j++){
printf("%7.2f",a[i][j]);
printf("\n");
}
131

Computer Programming The C Language


3. A vector of 10 integer numbers whose elements are correctly read must
be printed.
for(i=1;i<=10;i++)
printf("%d ",v[i]);
B. Considering the following sequences of code, specify what will be printed
on the screen after they are executed.
4. counter=0;
for(i=0;i<n;i++)
for(j=0;j<m;j++)
if(a[i][j]==0)
counter++;
printf("%d",counter);
5. counter=0;
for(i=0;i<n;i++)
if(a[i][i]==0)
counter++;
printf("%d",counter);
6. for(i=n-1;i>=0;i--)
printf("%d ",v[i]);
7. for(j=0;j<3;j++)
for(i=0;i<2;i++)
printf("%3d ", a[i][j]);
C. Choose the correct answer (one only).
8. An array is a collection of variables that have:
a) the same color; b) the same height; c) the same type; d) the
same index; e) all answers are wrong.
9. Which of the following types of arrays can be used in C programming
language?
a) single-dimensional array; b) two-dimensional array; c) multidimensional array; d) the answers a, b and c are correct; e) all answers are wrong.
10. Which of the following statements regarding the indexes of the elements
in a single-dimensional array is true?

132

7 Arrays
a) are integer numbers; b) are consecutive numbers; c) start from
the value zero; d) identify an element of the array; e) all of them.
11. When a single-dimensional array is declared, one must be specify:
a) the name; b) the type; c) the number of the elements; d) the
answers a, b and c are correct; e) all answers are wrong.
12. What is the action performed by the instruction a[7]=7;?
a) verifies if a variable a is equal to 7; b) assigns the value 7 to the
element with the index 7 of the single-dimensional array a; c) verifies
if the element a[7] is equal to 7; d) declares a vector of 7 elements
and gives initial value to its first element; e) all answers are wrong.
13. What is the effect of the line of code float average[20][10];?
a) declares a two-dimensional array of maximum 20 rows and 10
columns, containing real numbers; b) declares a single-dimensional
array with maximum 200 real numbers; c) declares a singledimensional array and initialize two of its elements with the values 20
and 10; d) performs a type conversion of the values 20 and 10 from
int to float; e) calculates the average between 20 and 10.
14. Which of the following statements regarding element a[2][3] of a
matrix is true?
a) it is placed on the second row and on the third column; b) it is
placed on the second column and on the third row; c) it is placed on
the third row and on the fourth column; d) it is placed on the third column and on the fourth row; e) all answers are wrong.
D. Write programs to solve the following problems.
15. Calculate and display the sum of odd elements in a single-dimensional
array.
16. Display in reverse order (from right to left) the elements of a vector.
17. Calculate and display the average grade of a student whose marks are
stored in a single-dimensional array. The average will be calculated only
if all the marks are greater than or equal to 5.
18. Determine the index of the first occurrence of a given value in a singledimensional array of n integer elements.
133

Computer Programming The C Language


19. The elements of a single-dimensional array of real numbers are read.
Display those elements whose values are greater than a threshold value
that is also read from the keyboard.
20. The coefficients of a polynomial function are stored in a singledimensional array. Display its derivative.
If the polynomial function is
p(x) = anxn + an-1xn-1 ++ a3x3 + a2x2 + a1x + a0
its derivative is
p(x)= nanxn-1 + (n-1)an-1xn-2 ++ 3a3x2 + 2a2x + a1
21. Perform the sum of two matrices.
22. A number is read. Verify if that number occurs in a matrix of n rows
and m columns whose values are also read from the keyboard.
23. The elements of a matrix are read. Count how many of these elements
are greater than their average.
24. Verify if a square matrix is the identity (or the unit) matrix (if it contains
1s on the main diagonal and 0s elsewhere). The matrix is initially considered the identity matrix and if an element that doesnt satisfy the criteria is found, than the check ends because the matrix is not the identity
matrix.
25. Verify if a square matrix is symmetric with respect to the main diagonal.
The upper or the lower triangle of the main diagonal must be traversed
and the statement a[i][j]==a[j][i] must be verified.

134

Chapter 8
Strings
A string variable stores a sequence of characters. C programming language
doesnt have a data type dedicated to strings (as Java and Pascal have the
string type). In C the strings are represented using single-dimensional arrays
that contain in each location a character and that have in their last location the
character '\0', which marks the end of the string. Because the basic element
of a string is the character, this chapter starts by presenting several aspects
connected to characters; then the features of the strings are described in detail.

8.1 Characters
The data type char is used in order to declare a character. This type has 8 bits;
therefore 28, meaning 256 characters can be represented. Each character is
stored as an integer number in the range [0, 255], number that is the ASCII code
related to that character [CH96]. Appendix 1 contains the most used characters
together with their ASCII codes.
When a character variable must be declared, the keyword char is used, followed by the name of that new variable. If the variable requires an initial value,
then that value must be enclosed by apostrophes (not quotation marks). The
following instruction declares a variable with the name ch and gives it the
ASCII value of the letter A.
char ch='A';
For input/output actions made on character variables the functions getchar() and putchar() can be used. If a formatted manner is required for
these variables, it can be performed through the functions printf() and
scanf(), using the format descriptor %c. The following instruction displays
on the screen the variable ch, previously declared; therefore the letter A will be
printed.
printf("%c",ch);
The characters can be analyzed and processed through several functions that are
part of the header file <ctype.h>. Some of these functions are hereby presented (each function receives a character as argument).

Computer Programming The C Language


isalfa(c) returns a non-zero value if the argument is a letter (A to Z or a
to z);
isdigit(c) returns a non-zero value if the argument is a digit (0 to 9);
isalnum(c) returns a non-zero value if the argument is a letter or a digit;
isupper(c) returns a non-zero value if the argument is an uppercase letter
(A to Z);
islower(c) returns a non-zero value if the argument is a lowercase letter
(a to z);
isspace(c) returns a non-zero value if the argument is space, tab, new
line;
toupper(c) returns the argument converted to its uppercase value;
tolower(c) returns the argument converted to its lowercase value.
Program 8.1.1 is an example of using a character variable. It depicts the option
of the user who decides whether he/she wants to increment and to display the
value of a counter whose initial value is zero. The counter is displayed, then it is
incremented and the user is asked whether he/she wants to continue these actions. His/her option is read through the getch() function and stored in a
char variable. This sequence of code is repeated within a do while instruction until the user enters the letter 'N' or 'n'. In order to avoid the requirement to enter only 'N' (uppercase) or only 'n' (lowercase) and also to avoid a
compound condition (the comparison of the users option to both 'N' and
'n'), the letter that is read from the keyboard is transformed to lowercase,
using the function tolower() and it is only compared to 'n' letter.
Program 8.1.1
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
void main(void){
int counter=0;
char option;
do{
clrscr();
printf("Counter: %d", counter++);
printf("\nDo you want to continue? (Y/N)");
136

8 Strings
option=getch();
}while(tolower(option)!='n');
}

8.2 Strings
A string is a sequence of characters that ends with '\0' (character that has the
ASCII code 0) and enclosed in double quotes ("This is a string"). The
double quotes specify that it is a string and the compiler adds the terminator for
strings [CH96]. The null character from the end of a string exists only in the
computers memory; the programmer is not required to worry about it too
much. The string from above can have the following memory representation:
T

t r

n g

\0

In order to create a string element, a single-dimensional array of character


variables will be used. The declaration is made as in the case of other variables,
specifying the type (char) and the number of elements and giving a valid
name for the new variable:
char str_name[str_length];
The number of elements specified when the variable is declared must take into
account that the string is ended with the null character ('\0'), therefore the
declaration must allocate memory space for this character too. For instance, if
the string "Programming", which has 11 characters, must be stored, then the
variable must be declared with at least 12 characters length.
A string can also be declared as a pointer (more about pointers in Chapter 9).
The variable stores the address of the first character of the string:
char *name;
A string can be initialized somewhere during the program or even when it is
declared. In this case, it is not mandatory to specify the length of the string (it
will have one character more than the number of characters used as initial value). If the string receives value character by character, then the programmer
must manually add the string terminator '\0'. The following instructions
emphasize these three types of initialization:
char my_name[8]="Adriana";
137

Computer Programming The C Language


char my_name[]="Adriana";
char my_name[8]={'A','d','r','i','a','n','a','\0'};
Though a string is an array, it is not necessary to access it character by character. It can be handled as a whole, as can be observed in the first two previous
initializations. The functions that process a string start from its first character
(whose address is specified by the name of the string) and traverse it until the
null character (which specifies the end of the string) is encountered. It is therefore very important not to omit this final character when the string is made of
individual characters, as the case of the third initialization from above.
The input/output actions performed on strings can be made through the functions gets() and scanf() for reading and puts() and printf() for
writing. The format descriptor for scanf() and printf() functions is
"%s". Because the name of an array contains the memory address of its first
element, the string variables do not need the addressing operator (&) when they
are read using the scanf() function.
In program 8.2.1 a string is declared, its value is read from the keyboard and
then it is displayed on the screen. Pay attention, the scanf() function reads
until a space is encountered and gets() until a new line (Enter) is found.
Program 8.2.1
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
void main(void){
char name[30];
clrscr();
printf("Enter the name ");
scanf("%s", name);
//or:
//gets(name);
//if the name contains spaces
printf("The name is: %s", name);
getch();
}
Because C programming language doesnt have a special type dedicated to
strings, it doesnt have operators for strings either. Therefore, instructions as
if(str1==str2) or str="Abc"+"def"; are impossible in C language.
138

8 Strings
The string processing (copying, concatenating, comparing) is made through
several functions that are part of the header file <string.h>. Some of these
functions are hereby presented.
int strlen(const char *s);
It returns the length of the string s (the number of characters), not counting the
terminating null character. Program 8.2.2 shows how this function can be used.
Once the program is run, values 14 and 17 (the lengths of the two strings) will
be displayed on the screen.
Program 8.2.2
#include <stdio.h>
#include <conio.h>
#include <string.h>
void main(void){
char name[]="Dennis Ritchie";
int l;
clrscr();
l=strlen("Bell Laboratories");
printf("%d, %d", strlen(name), l);
getch();
}
char *strcpy(char *dest, const char *src);
The function is used to make assignments between two strings, copying the
source string src into the destination string dest. It returns the destination
string and assumes that it is long enough to store the source string (if not, the
program can have an improper behavior, even if it doesnt have compilation
errors). This function is necessary because in C programming language the
assignments of strings cannot be made by simple instructions as str1=str2.
Program 8.2.3 is a short example that uses this function. The text abcdefg
will be displayed on the screen. It can be noted that strcpy() function modifies the content of the destination string (the initial content of this string is
lost), but keeps the source string unchanged (actually, the source string is declared as a constant in the functions prototype).
Program 8.2.3
#include <stdio.h>
#include <conio.h>
139

Computer Programming The C Language


#include <string.h>
void main(void){
char dest[20];
char src[] = "abcdefg";
clrscr();
strcpy(dest, src);
printf("%s", dest);
getch();
}
char *strcat(char *dest, const char *src);
Through this function two strings dest and src are concatenated. The address
of the destination string is returned; it contains the result of this action and must
be long enough to store the new string. Program 8.2.4 concatenates a space at
the end of the variable str1. Then the variable str2 is concatenated to the
result, obtaining the text C Programming.
Program 8.2.4
#include <stdio.h>
#include <conio.h>
#include <string.h>
void main(void){
char str1[20]="C";
char str2[]="Programming";
clrscr();
strcat(str1, " ");
strcat(str1, str2);
printf("%s", str1);
getch();
}
int strcmp(const char *s1, const char *s2);
This function is used to compare two strings (the lexicographical order is considered). The function is case sensitive, therefore it will distinguish between
uppercases and lowercases (lowercases have the ASCII codes greater than
uppercases and the function will act accordingly). The returned value is an
integer with the following meanings:
o a negative value if string s1 is less than string s2 (e.g. calculator is less than key);
140

8 Strings
o 0 if strings s1 and s2 are identically;
o a positive value if string s1 is greater than string s2.
Program 8.2.5 compares the password entered by the user to the password that
was set through the program; a message is displayed accordingly. The passwords are stored into strings.
Program 8.2.5
#include <stdio.h>
#include <conio.h>
#include <string.h>
void main(void){
char pass[20]="Secret!";
char user_pass[20];
clrscr();
gets(user_pass);
if(strcmp(pass, user_pass)==0)
printf("Welcome!");
else
printf("Incorrect password");
getch();
}
char *strchr(const char *s, int c);
This function searches the char c into the string s. If it finds the character, it
returns a pointer to the characters first occurrence into the string; else, it returns the null value.
char *strrchr(const char *s, int c);
The character c is also searched into the string s, but the traversing is made
from right to left; therefore the function returns the address of the characters
last occurrence (or the null value if string s doesnt contain the character c).
char *strstr(const char *s1, const char *s2);
The function looks for string s2 into string s1. It returns a pointer to the address of s2 into s1 or null if s2 in not part of s1.
Program 8.2.6 is an example of using the previously described three functions.
"C Programming" string is considered and three substrings are extracted
from it; the first one begins where the char 'r' occurs for the first time, the
141

Computer Programming The C Language


second one begins where the char 'r' occurs for the last time and the third
substring begins where the string "gram" occurs. Therefore, on the screen will
be displayed:
Substring 1: "rogramming"
Substring 2: "ramming"
Substring 3: "gramming"
Program 8.2.6
#include <stdio.h>
#include <conio.h>
#include <string.h>
void main(void){
char str1[] = "C Programming", str2[] = "gram";
char substr1[20], substr2[20], substr3[20];
char ch='r';
clrscr();
strcpy(substr1,strchr(str1,ch));
strcpy(substr2,strrchr(str1,ch));
strcpy(substr3,strstr(str1,str2));
printf("\nSubstring 1: \"%s\"", substr1);
printf("\nSubstring 2: \"%s\"", substr2);
printf("\nSubstring 3: \"%s\"", substr3);
getch();
}
char *strncpy(char *dest, const char *src, int n);
It is similar to the function strcpy(), but it copies only maximum n characters from the source string to the destination string.
char *strncat(char *dest,const char *sursa, int n);
It is similar to the function strcat(), but it concatenates only maximum n
characters from the source string to the destination string.
int strncmp(const char *s1, const char *s2, int n);
It is similar to the function strcmp(), but it compares only the first maximum
n characters of the two strings. The function is case sensitive.
int stricmp(const char *s1, const char *s2);
142

8 Strings
It is similar to the function strcmp(), but it doesnt distinguish between
lowercases and uppercases; therefore it is not case sensitive (the strings "ABC"
and "abc" will be considered identical by this function).
int strnicmp(const char *s1,const char *s2, int n);
It is similar to the function strncmp(), but it doesnt distinguish between
lowercases and uppercases; therefore it is not case sensitive.
Conversion functions these are used to transform a string into another data
type (usually a number) and vice versa. These functions are part of the
header file <stdlib.h>.
o int atoi(const char * str );
This function transforms the string received as argument into an integer number. First, the function ignores the spaces from the beginning of the string (if
there are such spaces); then it interprets a possible plus or minus sign; finally
the function transforms the next characters into an integer number (if these
characters have such a meaning). When a character that cannot be interpreted as
a number is encountered, the function stops, returning the already created number and ignoring the rest of the string. If the string doesnt begin with a sequence of characters that can be transformed into an integer, then the function
returns zero.
o long int atol(const char * str );
It is similar to the function atoi(), but it returns a value of type long int.
o double atof(const char * str );
It is similar to the function atoi(), but transforms the string (or a part of it)
into a real number (of type double).
o char *itoa(int val, char * str, int base);
This is not a standard function, but it is accepted by some compilers. Using this
function, an integer number is transformed into a string. The number is the first
argument of the function. The string obtained through the conversion is returned by the function and it is also stored into the second argument of the
function. The third argument specifies the base to be used in conversion (for
instance, 10).
Program 8.2.7 uses the functions atoi() and itoa() to convert a string into
an integer and two integers into strings (the third string is the base 2 representa143

Computer Programming The C Language


tion of the third number). Once the program is run, on the screen will be displayed:
number1=-987, str1=-987
number2=12345, str2=12345
number3=7, str3=111
Program 8.2.7
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
void main(void){
int number1, number2=12345, number3=7;
char str1[25]="-987", str2[25], str3[25];
clrscr();
number1=atoi(str1);
itoa(number2, str2, 10);
itoa(number3, str3, 2);
printf("number1=%d, str1=%s\n",number1,str1);
printf("number2=%d, str2=%s\n",number2,str2);
printf("number3=%d, str3=%s",number3,str3);
getch();
}
Though a string is usually dealt with as a whole, it can also be analyzed or
processed character by character because it is in fact an array. Program 8.2.8
verifies if a string read from the keyboard is a palindrome (a word or a phrase
that may be read the same way in either direction: "eye", "madam",
"level", "1234321", "A car, a man, a maraca"). In order to
do this, the symmetry of characters with respect to the middle of the string must
be verified. An integer variable, called flag is declared; it receives the initial
value 1, considering that the string is a palindrome. When it is found that the
string is not palindrome, the variable is changed to 0. At the beginning, the
algorithm determines the length of the string (using the function strlen()).
Then the first half of the string is traversed character by character and the characters symmetrical with respect to the middle of the string are compared (the
first with the last, the second with the last but one and so on). When a pair of
characters that are not identical is found, the variable flag changes its value to
0 and the checking ends; the for is left through the instruction break. If after
144

8 Strings
the for the variable flag is unchanged (its value is still 1), then all the characters of the string are symmetrical with respect to the middle of the string,
therefore the string is a palindrome; otherwise, not.
Program 8.2.8
#include <stdio.h>
#include <conio.h>
#include <string.h>
void main(void){
char str[25];
int flag=1;
int i, n;
clrscr();
printf("Enter the string: ");
gets(str);
n=strlen(str);
for(i=0;i<n/2;i++)
if(str[i]!=str[n-i-1]){
flag=0;
break;
}
if(flag)
printf("The string is palindrome.");
else
printf("The string is not palindrome.");
getch();
}

8.3 Questions and exercises


A. Find the error.
1. A character must be declared and initialized.
char ch="A";
2. The value 'a' is assigned to a char variable and then that variable is
displayed.
char ch='a';
printf("%d",ch);
145

Computer Programming The C Language


3. A string variable must be declared and initialized.
char str[5]="C Programming";
4. Two strings s1 and s2 must be compared.
if(s1==s2)
//something
else
//something else
B. There are considered the following sequences of code. Specify what happens during their execution.
5. char key;
do{
key=getch();
}while(toupper(key)!='X');
6. char s1[10], s2[10];
int flag;
strcpy(s1,"abc"); strcpy(s2,"abc");
if(strcmp(s1,s2))
flag=1;
else
flag=2;
printf("%d",flag);
7. char str[25]={'a','b','c','\0','1','2','3'};
printf("%s, %d",str,strlen(str));
8. char s1[10], s2[10];
strcpy(s1,"abc"); strcpy(s2,"123");
if(strcmp(s1,s2)==0)
strcpy(s1,s2);
else
strcat(s1,s2);
printf("%s, %s",s1,s2);
C. Choose the correct answer (one only).
9. Which of the following functions can be applied to a char variable?
a) isalnum(); b) isspace(); c) toupper(); d) tolower(); e) all answers are correct.
146

8 Strings
10. There are considered two strings a="abra" and b="cadabra". After the execution of the instruction strcat(a,b);, the variables a
and b will have the following values:
a) a="abra", b="cadabra"; b) a="abra si cadabra",
b="cadabra"; c) a="abracadabra", b="cadabra"; d)
a="abra
cadabra", b="cadabra"; e) a="abra",
b="abracadabra".
11. There are considered two strings s1="abc" and s2="abc" and two
integer variables a=0 and b=0. The following sequence of code is executed: if(strcmp(s1,s2)==0) a++; else b+=1;. What
will be the values of the variables a and b after this execution?
a) a=0, b=0; b) a=1, b=0; c) a=1, b=1; d) a=0, b=1; e)
all answers are wrong.
12. Which of the following functions should be used to determine the length
of a string?
a) strlength(); b) length(); c) String.Len(); d)
strlen(); e) len().
13. Which of the following actions is possible with two strings s1 and s2?
a) s=s1+s2; b) s=s1-s2; c) s=s1*s2; d) s=s1/s2; e)
all answers are wrong.
14. A string is:
a) a data type; b) an array of characters; c) an operator; d) a
function; e) a program.
15. The function that concatenates two strings is:
a) strcat(); b) strconcatenate(); c) concatenate(); d) strconc(); e) conc().
16. Which of the following functions is case sensitive?
a) strcpy(); b) strcat(); c) strlen(); d) strcmp();
e) stricmp().
17. Which of the following instructions copies a string s1 to a string s2?

147

Computer Programming The C Language


a) strcpy(s1,s2); b) strcpy(s2,s1); c) s2=s1; d)
s2==s1; e) none of them.
D. Write programs to solve the following problems.
18. Read in a string the first name and the last name of a person (both entered on the same line).
19. Read, in two different variables, the first name and the last name of a
person. Concatenate these values without losing any of them and display
the complete name.
20. A string is read from the keyboard. Find out how many digits, how
many uppercases and how many lowercases that string contains.
21. A string is read from the keyboard. Display the string from right to left.
22. Determine how many times a character is present in a text. Both the character and the text are read from the keyboard.
23. Ten words are read from the keyboard. Display a warning for those
words that are greater (from lexicographical point of view) than the first
word.
24. The first name and the last name of a person are stored in two strings.
Modify these strings so that the first name has the first letter uppercase
and the rest of them lowercases and the last name has all letters uppercases.

148

Chapter 9
Pointers
Pointers are essentials in C programming; they are connected to arrays and
strings (described in two previous chapters) and also to functions, user-defined
types and files, which will be explained in the following chapters. The dynamic
memory allocation is also closely related to pointers. A good programmer must
be able to manage this kind of variables.
Pointers are considered as some of the strongest features of C programming
language. On the other hand, they are also a very dangerous tool available to
anyone. The pointers that are uninitialized or that have incorrect values could
lead to errors that are very difficult to be located in a program or could even
cause dysfunctions of the operating system [HS98], [CH96].

9.1 Pointer variables


A pointer is a variable that contains the memory address of another variable. It
is said that a pointer indicates or points to a variable. Because pointes are more
special than other variables, they need a special syntax, too; this syntax should
allow manipulating the memory locations stored by pointers and also the values
from those addresses [PT12]. The compiler must also be informed that a certain
variable is a pointer. The declaration of a pointer is made using a data type (any
data type of C) and giving it a name that is preceded by the unary operator
asterisk (*). The general form for declaring a pointer is:
type *ptr_name;
The type of the pointer defines the type of the variables that can be indicated
by that pointer [HS98]. It is very important to have correctly declared pointers
because the operations that involve pointers are closely related to their types (as
shown later in this chapter)
Two special operators are used together with pointers [HS98]:
& The addressing operator (ampersand) is an unary operator and returns
the memory address of its operand. The instruction p=&mark1; assigns to
the pointer p the address of the variable mark1. This address is the memory
location where the variable is stored.

Computer Programming The C Language


* The dereference operator (asterisk) is also an unary operator, being
complementary to the addressing operator. It returns the value stored at the
address pointed by its operand. The instruction mark2=*p; will assign to
the variable mark2 the value from the address indicated by the pointer p.
Therefore, the initialization of a pointer is made through an instruction with the
following general form:
ptr_name=&var_name;
Before it receives an initial value, a pointer has the value NULL. It doesnt point
to any memory address, to any element.
The general form for an instruction that accesses the value stored at the address
indicated by a pointer is:
var_name=*ptr_name;
An example of how these things happen in memory is shown in figure 9.1.1,
which reflects the following lines of code:
float mark, *p; //a regular variable and a pointer are declared
p=&mark; //the pointer will store the address of the variable mark
mark=9.5; //mark and also *p will have the value 9.5
Memory addresses

Values of the variables

.
..
65528

9.5

.
..
65520

mark

*p

65528

..
.

Figure 9.1.1 Pointers representation

150

9 Pointers
In order to access the value of the mark one can either use the mark variable
directly or the dereferenced pointer *p. Therefore, the following two instructions have the same result: they display the mark on the screen.
printf("%.2f", mark);
printf("%.2f", *p);
Program 9.1.1 provides the entire example. It can be noted that both the variable mark and the pointer p have the same type, in order to make possible the
assignment p=&mark. Pointers must have a type related to the variables they
indicate. This means that it is unnatural to have an int pointer that stores the
address of a float variable (though any address can be assigned to a pointer).
Program 9.1.1
#include <stdio.h>
#include <conio.h>
void main(void){
float mark, *p;
clrscr();
p=&mark;
mark=9.5;
printf("%.2f",mark);
printf("\n%.2f",*p);
getch();
}

9.2 Operations with pointers


A pointer can be used as a right side member in an assignment operation,
giving its value to another pointer. This is emphasized by program 9.2.1. Pointer p2 will contain the address of the variable mark because p2 receives the
address stored by p1, which is in fact the address of this variable. Therefore,
the value of the mark can also be obtained through pointer p2.
Program 9.2.1
#include <stdio.h>
#include <conio.h>
void main(void){
151

Computer Programming The C Language


float mark=9.5,*p1,*p2;
clrscr();
p1=&mark;
p2=p1;
printf("%.2f",*p2); //the mark is displayed
getch();
}
The pointers can be the subject of the addition and of the subtraction arithmetical operations (these two only). These operations are closely related to the type
of the pointer because the addition and the subtraction will be made with an
integer number of bytes that is proportional to the number of bytes used by the
data type to represent the variables.
As an example, an integer pointer p is considered; the integer type is
represented on two bytes. If the pointer p has the value 65522, then its increment (meaning the operation p++) transforms it to the value 65524, making it
to point to the next memory location that contains an integer. The decrement
(p--) will modify the value of the pointer from 65522 to 65520, indicating
to the previous memory location. Therefore, a pointer will be incremented or
decremented with a number of bytes equal to the length of the data type whose
address it contains: 1 byte for char, 2 bytes for int, 4 bytes for long int, 4
bytes for float, 8 bytes for double and so on.
It is also possible to add/subtract integer numbers to/from pointers. For instance, if p is a type float pointer and it is involved in the operation p=p+8,
the pointer will move forward with 8x4=32 memory locations, pointing to the
float element that is stored there. It is obvious that pointers cannot bear
additions or subtractions with float or double values (operations like
p=p+4.5 are impossible with pointers).
Two pointers can be compared through a relational operation. An instruction as
if(p1==p2) will verify if the pointers are identical regarding the memory
address that they contain (in other words, it will verify if the pointers indicate to
the same memory address).

152

9 Pointers

9.3 Pointers and other elements


Pointers are closely related to arrays because the elements of an array are
placed in consecutive memory locations. If, for example, there is considered the
array
int v[15]={10, 12, -7, 17, 29};
its elements can be accessed through certain indexes: v[0] is the first element,
v[1] is the next element, v[4] is the last element.
In order to access the elements of an array, pointers can also be used. First, a
pointer of the same data type as the array is declared:
int *p;
Then the pointer must indicate to the first element of the array:
p=&v[0];
The address of the first element of an array is contained by the name of the
array itself. Therefore, the following instruction has the same effect as the
previous one:
p=v;
The elements of the array are accessed through the pointer as follows: *p is the
content of its first element, *(p+1) is the content of the second element,
*(p+4) is the content of its last element.
Program 9.3.1 displays the elements of an array through both its indexes and a
pointer. In the first part, using a for instruction, the vector is traversed in the
classical way and its elements (v[i]) are displayed. In the second part a pointer p starts from the first element of the array; after an element is displayed, the
pointer is incremented, indicating to the next location of the vector. These
actions are repeated as long as the pointer contains a value that is not null.
Because only the first 5 locations of the vector are initialized, the rest of them
receive the value 0, therefore the instruction while ends after 5 iterations.
Another way of constructing this repetitive part is to stay within the loop of the
while instruction as long as the pointer indicates an address that is less than
the address of the beginning of the vector plus the number of the useful elements (p<v+5). When pointers are used to handle arrays, this must be made
carefully because the compiler doesnt verify the bounds of the array and there
is the risk to get out of boundary and to overwrite (or, generally, to access) the
adjacent memory areas.
153

Computer Programming The C Language


Program 9.3.1
#include <stdio.h>
#include <conio.h>
void main(void){
int v[15] = {10, 12, -7, 17, 29};
int *p;
int i;
clrscr();
for (i = 0; i < 5; i++)
printf("%d ",v[i]);
printf("\n");
p = v;
while(*p) // or while(p<v+5)
printf("%d ",*(p++));
getch();
}
Pointers can also be used when strings are handled. Most of the functions that
process strings receive their arguments as pointers; this way the address of the
first character of the string is transmitted. An important role is played here by
the terminator '\0' without which it would be impossible to establish where
the end of the string is.
Program 9.3.2 initializes a string. The address of its first element is assigned to
a pointer. Then, the string is displayed by both the variable str and the pointer p.
Program 9.3.2
#include <stdio.h>
#include <conio.h>
void main(void){
char str[15]="C Programming";
char *p;
clrscr();
p = str;
printf("%s\n",str);
printf("%s",p);
getch();
}
154

9 Pointers
Because pointers are frequently used together with strings, another example
from this area is hereby presented (program 9.3.3). The program searches for
the first occurrence of a character in a string and displays the index of this
occurrence. In order to do this, a string str is declared using the classical way
(array of characters); it stores the text "C Programming". Another string,
ptr, is declared as pointer. It receives the address of the first occurrence of the
character 'r' that is stored in the variable c. If the address of the beginning of
the string (meaning str) is subtracted from the address of the first occurrence
of the character in the string (meaning ptr) then the result is the number of
locations between these two addresses, which is in fact exactly the index of the
first occurrence of the character c in the string str. If the character stored in
the variable c doesnt belong to the string str, then the pointer ptr will have
the value NULL and a message will be displayed accordingly.
Program 9.3.3
#include <stdio.h>
#include <conio.h>
#include <string.h>
void main(void){
char str[20];
char *ptr, c = 'r';
clrscr();
strcpy(str, "C Programming");
ptr = strchr(str, c);
if (ptr)
printf("\'%c\' has the index: %d", c, ptr-str);
else
printf("The character was not found");
getch();
}
The use of pointers doesnt end here. The following chapters describe the connections between pointers and functions (pointers are especially used to send
parameters by address), user-defined types (for instance, structures can be
accessed through pointers) or files (the connection to a file is made through a
pointer).

155

Computer Programming The C Language

9.4 Questions and exercises


A. Find the error.
1. A pointer of integer type should be declared.
int &m;
2. int *m, x=3;
m=*x;
3. int *m, x;
m=&x;
*m=3;
x=&m;
4. float average=8.75;
int *m;
m=&average;
5. float *p, x=9.5;
p=&x;
if(p+0.5!=NULL) printf("Valid number");
B. There are considered the following sequences of code. Specify what happens after their execution.
6. int *p, a=17;
p=&a;
printf("%d",*p);
7. int *p, v[3]={21, -12, 103};
p=v;
printf("%d",*(p+1));
8. char *s1="Abra", *s2="cadabra";
printf("%s",strcat(s1,s2));
C. Choose the correct answer (one only).
9. Which of the following instructions should be used in order to store the
value 7 in the memory location indicated by the pointer p?
a) *p=7; b) p=7; c) &p=7; d) p=&7; e) p=*7.
10. Which of the following operators cannot be applied to pointers?
a) *; b) &; c) ++; d) --; e) /.
156

9 Pointers
11. Which of the following statements is false?
a) & is the addressing operator; b) * is the dereference operator;
c) * can be used to multiply two pointers; d) & cannot be used to multiply two pointers; e) all answers are wrong.
12. Which of the following sequences is the address of a variable indicated
by the pointer p?
a) p; b) &p; c) *p; d) &&p; e) none of them.
13. Which of the following sequences is the value of a variable indicated by
the pointer p?
a) p; b) &p; c) *p; d) &&p; e) none of them.
14. There is considered the sequence of code float *p1, *p2, x=3,
y=4; p1=&x; p2=&y;. Which of the following instructions cannot
be executed?
a) p1=p1+7.25; b) p1=p1+7; c) p1=p1-7; d)
if(p1==p2); e) all these instructions are correct.
D. Write programs to solve the following problems.
15. Two marks are read from the keyboard (the mark for the exam and the
mark for the lab); they are stored in pointer variables. Display the final
mark (the mark for the exam is 2/3 of the final mark and the mark for
the lab is 1/3 of the final mark).
16. The elements of a vector with integer numbers are read from the keyboard. Traverse this vector using a pointer and display the value of its
first negative element.
17. The first name and the last name of a student are read in two variables
char *. Create a third string (also a pointer of type char) that contains the first name followed by the second name (separated through a
space).
18. A text t and two words w1 and w2 are read from the keyboard. Display
the string that is obtained by replacing in text t all the occurrences of
w1 with w2.

157

Chapter 10
User-defined functions
A complex problem is not usually solved by a single group of instructions
placed in the main() function. This would imply the writing of a very long
and intricate program and, on the other hand, an unnecessary duplication of
some sections of code that perform the same task (eventually using different
input data). In order to avoid these disadvantages, the problem that must be
solved is split into several sub-problems; separated sections of code are written
for each sub-problem that has distinct features. These sections of code are in
fact the functions.
A C program can contain two types of functions:
predefined functions (or library functions)
o this are already implemented to solve simple and well-defined
problems;
o they are part of the standard library of the C programming language; therefore, a preprocessor directive #include followed
by the name of the header file that contains a certain function is
necessary when that function is used in a program;
o examples: mathematical functions (math.h): sqrt(), exp();
functions that perform input/output actions (stdio.h, conio.h): printf(), scanf(); functions used to process
strings (string.h): strlen(), strcpy();
user-defined functions
o these are written by the developer of a program;
o their use makes the program clearer, easier to correct, maintain
and modify and allows code reusability.
Therefore, functions are an important feature of the C programming language,
representing the location where the entire activity of a program takes place
[HS98]. Splitting programs into small units (functions) is the best solution in
structuring these programs. Functions are easier to handle and can be used in
various configurations [CH96].

10 User-defined functions
A function is a sequence of code that has a name and that performs a certain
task. A C program must have at least one function (the main() function,
without which a program cannot be executed), but it can contain many other
functions.

10.1 User-defined functions


The following steps must be covered in order to work with user-defined functions:
first, the compiler must be notified that a function will be defined in the
program; this is done through the prototype of the function several features of that function, which must be specified before the beginning of the
main() function;
the description of the function contains the definition and the body of that
function and is the location where the code that solves the task for which the
function was created appears; this implementation of the function can be
placed once the main() function ends or before it begins (in the latter case
the definition overlaps the prototype);
the call of the function is in fact the use of that function in the program.

10.1.1 The prototype of a function


The prototype of a function is the first thing that must be specified when a
function is created and used. Through the prototype, the name of the function
and several information about the data received by the function from outside
and about the result generated by the function are mentioned. The compiler will
use the prototype in order to verify if the instructions that are related to a certain
function use it correctly (otherwise, an error message will be generated).
When the prototype of a function is specified, a line of code with the following
general form is used:
type_returned_val function_name(type_arg1 name_arg1,
type_arg2 name_arg2, , type_argn name_argn);
where:
o type_returned_val is the type of the value returned by the
function (sent back where the function was called);
159

Computer Programming The C Language


o function_name is a valid name, which will be used to call
the function (it is the subject of the same rules as a variables
name: it must begin with a letter or an underscore, it cannot contain the characters #, $ or space, the keywords of the language
must be avoided, etc.);
o type_argi name_argi specify the type and the name of
each argument received by the function from outside;
o the prototype is followed by the separator ; (semicolon).
The following line of code specifies the prototype of a function called average that will calculate and will return the average of the first n natural numbers
(n is a parameter of type int received by the function when it is called):
float average(int n);
If the function doesnt send any result outside, then the type of the returned
value is void (this kind of functions are called void functions). The following
prototype defines a function that receives an argument of type char, but
doesnt return anything:
void a_function(char a);
It is possible to have nothing in front of the name of a function (the type of the
returned value is not specified). Attention! In this case it is considered that the
function will return an integer value (do not confuse with a function that doesnt
return anything and that has the type void specified). The following function
will receive two arguments (one of type float and the other one of type int)
and will return an integer value:
another_function(float x, int y);

10.1.2 The description of a function


This contains the definition and the body of a function. The definition must be
identical to the prototype (same number of arguments, same type of both arguments and returned value), but it is not followed by the semicolon separator.
The body of the function is the sequence of code that solves the task for which
the function was created. The instructions that form the functions body follows
right after the functions definition and are enclosed by curly brackets. The
definition and the body of the function average (previously specified by its
prototype) could be:
160

10 User-defined functions
float average(int n){
int i;
float sum=0;
for(i=1;i<=n;i++)
sum=sum+i;
return sum/n;
}
About return
If a function has to return a value, then its body must contain at least one return instruction followed by the value that is returned (as in case of the function average previously presented). The general form for this instruction is:
return [expression];
When the instruction return is executed, the function that contains it is immediately left and the execution of the program goes back to the instruction that
caused the call of the function. If the function returns a value, then the expression that follows after return is executed and the result is sent outside. If return is not followed by an expression, a variable or a value or even
is missing, then the function is left without returning a value (of course, this is
the case of a void function). The following function receives as argument a
string and displays it in reverse order, without returning anything:
void reverse(char *s){
int i;
for(i=strlen(s)-1;i>=0;i--)
printf("%c",s[i]);
}
A function may contain several return instructions; the first one that is encountered will be executed. These multiple return instructions emerge on
different branches of conditional instructions (for instance if else) and
using them distinct values are returned, accordingly to the path followed by the
execution of the program. The following function receives as argument a real
number (a float one) and returns its sign (-1 if the number is negative, 0 if it
is zero or 1 if it is positive):
161

Computer Programming The C Language


int signum(float x){
if(x<0) return -1;
else
if(x==0) return 0;
else return 1;
}

About arguments
The arguments (or the parameters of a function) are enclosed by parentheses
and are placed right after the name of a function in its prototype and in its definition. Data is transmitted from outside to function through these arguments.
They can be used in the function as any other variable that was declared inside
that function. Each argument has a name and a type. The type that is specified
in the prototype must be identical to the one used when the function is called;
the name can be different. The following function returns the product of two
integer numbers received as argument:
int product(int x, int y){
return x*y;
}
If a function doesnt accept arguments, then its prototype and its definition will
have the type void instead of the list of arguments. The following function
doesnt receive arguments (it returns the sum of the first 5 natural numbers):
int sum(void){
int i, s=0;
for(i=1;i<=5;i++)
s=s+i;
return s;
}

162

10 User-defined functions

10.1.3 The call of a function


The call of a function is required when the function must be used. This is a
simple action that is made through the name of the function followed by its
parameters (enclosed by parentheses). The programs that were written in the
previous chapters have already called library functions, though the functions
were not explicitly discussed. The following instructions call few of these functions:
printf("This is a library function");
getch();
sqrt(49);
strlen("text");
The call of a user-defined function is made in the same manner. The following
instruction calls the function reverse() that was previously defined and that
displays a string from right to left:
reverse("C Programming");
The parentheses that follow the name of a function when it is called are mandatory, though the function doesnt require arguments. For instance, the function
that calculates the sum of the first 5 natural numbers (previously defined) is
correctly called in this way:
sum();
If a function returns a value (as the function sum() does), this value can be
used in several ways:
it is assigned to a variable (it is the right side operand of an assignment):
x=sum();
it is part of an expression (the call of the function is also in the right side of
an assignment):
average=sum()/5;
it is a parameter of another function:
printf("The sum is: %d", sum());
it is part of a condition:
if(sum()>0) printf("The sum is positive");
163

Computer Programming The C Language


it is lost, because it is neither assigned nor used in an expression (it is obvious that the use of the function in this case has no sense):
sum();
If a function requires parameters, these can be (function average(), previously described, is considered as example):
values:
a=average(3);
variables:
n=7;
a=average(n);
expressions:
n=1;
m=2;
a=average(n+m);
The call of a function cannot be the left side operand in an assignment. The
following instruction is wrong and will generate a compilation error:
sum()=100; //incorrect call
It is not mandatory that the name of the parameters used in the functions call is
identical to the name of the arguments from the prototype of the function (only
their number and their type must be the same). Therefore, a function with the
prototype
void calculate(float x, int y);
can be called:
calculate(a,b);
Program 10.1.1 is a complete example of declaring and calling a function. This
function calculates and returns the average of the first n natural numbers (it is
obvious that the average can be calculated only if n is not zero).
Program 10.1.1
#include <stdio.h>
#include <conio.h>
164

10 User-defined functions

float average(int nr);


void main(void){
int n=2;
clrscr();
if(n!=0)
printf("The average is: %.2f",average(n));
else
printf("Error: division by zero!");
getch();
}
float average(int nr){
int i;
float sum=0;
for(i=1;i<=nr;i++)
sum=sum+i;
return sum/nr;
}
It is possible to have the definition and the body of a function before the
main() function; in this case, the definition and the prototype are overlapping.
The semicolon separator from the end of the prototype must be removed because the body of the function follows (enclosed by curly brackets). Program 10.1.2 presents the same example with the average, but places the description of the function average() at the beginning of the program. Attention! If
this kind of implementation is chosen, then the main() function must be the
last function in the program.
Program 10.1.2
#include <stdio.h>
#include <conio.h>
float average(int nr){
int i;
float sum=0;
for(i=1;i<=nr;i++)
sum=sum+i;
return sum/nr;
165

Computer Programming The C Language


}
void main(void){
int n=2;
clrscr();
if(n!=0)
printf("The average is: %.2f",average(n));
else
printf("Error: division by zero!");
getch();
}
The call of a function can be performed within any function, not only in the
main() function. Example 10.1.3 also calculates the average of the first n
natural numbers, but inside the average() function, a function sum()is
called, that returns the sum of the first n natural numbers; then the average is
calculated and returned.
Program 10.1.3
#include <stdio.h>
#include <conio.h>
float sum(int nr){
int i;
float s=0;
for(i=1;i<=nr;i++)
s=s+i;
return s;
}
float average(int nr){
return sum(nr)/nr;
}
void main(void){
int n=2;
clrscr();
if(n!=0)
printf("The average is: %.2f",average(n));
else
166

10 User-defined functions
printf("Error: division by zero!");
getch();
}
One of the major advantages of functions is that these are written once and
could be used (called) many times, generating different results if different parameters are sent to them. In program 10.1.4, function signum() is called
three times.
Program 10.1.4
#include <stdio.h>
#include <conio.h>
int signum(float x){
if(x<0) return -1;
else
if(x==0) return 0;
else return 1;
}
void main(void){
clrscr();
printf("\n%d", signum(-7.17));
printf("\n%d", signum(0));
printf("\n%d", signum(70));
getch();
}

Return from a function


Once the execution of a function ends, the program continues from the point
where the function was called. There are two ways a function ends its execution
[HS98]:
the instructions from a function are executed one by one, until the end of the
function (the closing curly bracket). The function from program 10.1.5 displays a string from left to right, traversing it character by character. Once
the string was entirely displayed, the function has nothing else to do, therefore it ends and the execution of the program comes back in the main(), at
the instruction that follows after the call of the reverse() function.
167

Computer Programming The C Language


Program 10.1.5
#include <stdio.h>
#include <conio.h>
#include <string.h>
void reverse(char *s){
int i;
for(i=strlen(s)-1;i>=0;i--)
printf("%c",s[i]);
}
void main(void){
clrscr();
reverse("C Programming");
getch();
}
the execution of a function is interrupted by a return instruction. This is
used both to return a value (in this case it is followed by that value or by an
expression) or to increase the efficiency of the function (for instance, a
function that searches a character in a string could finish its execution when
the first occurrence of that character is found, without losing time to search
to the end of the string). This kind of function can contain several return
instructions. The function from program 10.1.6 returns 1 if the searched
character is found and 0 otherwise.
Program 10.1.6
#include <stdio.h>
#include <conio.h>
#include <string.h>
int search(char *s, char c){
int i;
for(i=0;i<strlen(s);i++)
if(s[i]==c) return 1;
return 0;
}
void main(void){
168

10 User-defined functions
char str[20], ch;
int found;
clrscr();
printf("Enter the string: ");
gets(str);
printf("Enter the character: ");
scanf("%c", &ch);
found=search(str,ch);
if(found)
printf("The character was found");
else
printf("The character doesnt exist");
getch();
}

10.1.4 The scope of variables


A variable has a certain scope (a context where it is valid and can be used)
according to the location where that variable is declared [CH96]. The variable
scope refers to its visibility, to who can see it (meaning who can use it), to
when it is created and when it is destroyed. Two main categories of variables
can be distinguished from this point of view:
local variables:
o are declared within a function;
o are created each time the function is called;
o are destroyed when the function ends and it is left;
o are available only inside the function, any attempt to access them
outside the function being an error;
o are required in order to isolate the functions (generally, a function should not affect other functions or their variables); a function receives data from outside through its arguments and sends
values outside through return instructions; everything else
happening within the functions body is private.
global variables:

169

Computer Programming The C Language


o are declared outside any function, at the beginning of the program, after the preprocessor directives (#include, #define);
o are available during the entire execution of the program;
o can be accessed and modified by any function of the program;
o are used when more functions of the program must access the
same data;
o should be avoided if they are not necessary, because they hold
useless the memory during the entire execution of the program
and reduce the generality of the functions that use them (those
functions cannot be used in other programs because they refer to
something that must be defined outside their code) [HS98].
A function is connected to its external environment through its arguments and
through the global variables. The arguments received by the function can be
handled as local variables.
The values that are used in a functions call are called actual parameters. When
these values arrive inside the function they are called formal parameters.
Program 10.1.7 calculates the average of two numbers and it is an example for
all types of variables previously presented. Variable n is a global variable; it is
declared at the beginning of the program, it is initialized within the function
main() and it is used by the function calculate(). Variables n1, n2 and
result are local variables of the function main() and can only be used
within this function. n1 and n2 are also actual parameters passed to the function calculate() when it is called. Inside the function they became formal
parameters a and b. The function calculate() also has a local variable, m,
created at the beginning of the function and destroyed when the function ends.
Program 10.1.7
#include <stdio.h>
#include <conio.h>
int n; //n global variable
float calculate(float a, float b){
//a, b formal parameters
float m; //m local variable
170

10 User-defined functions
m=(a+b)/n;
return m;
}
void main(void){
float n1=5, n2=10, result;
//n1, n2, result local variables
clrscr();
n=2;
result=calculate(n1,n2);
//n1, n2 actual parameters
printf("The average is: %.2f", result);
getch();
}
It is advisable to use local variables and parameters rather than global variables
whenever is possible. For instance, a function that calculates the sum of two
numbers can be developed in several ways:
version 1 the function can only be used to calculate the sum of the global
variables x and y:
int x, y;
int sum(void){
return x+y;
}
version 2 the function receives two numbers as arguments; it is more
general and because it is parameterized, it can be used to calculate the sum
of any two numbers:
int sum(int x, int y){
return x+y;
}
If a local variable has the same name as a global variable, all the instructions
that access the variable within the function where the local variable is declared
refer only to the local variable and do not affect the global variable [HS98].
Program 10.1.8 emphasizes this aspect. Once it is run, on the screen is displayed:
x in main: 10
171

Computer Programming The C Language


x in function_1: 100
x in function_2: 10
A global variable x is declared; it receives the initial value 10 within the
main() function and then it is displayed. In turn, function_1() declares a
local variable with the same name, gives it the value 100 and then prints it; the
x variable within this function refers to the local variable and not to the global
one. The call of function_2() proves this, the global variable x having the
same value 10, which was initially established within the main() function.
Program 10.1.8
#include <stdio.h>
#include <conio.h>
int x;
void function_1(void){
int x=100;
printf("\nx in function_1: %d", x);
}
void function_2(void){
printf("\nx in function_2: %d", x);
}
void main(void){
clrscr();
x=10;
printf("\nx in main: %d",x);
function_1();
function_2();
getch();
}
Local variables, in turn, can be of two types:
automatic;
static.

172

10 User-defined functions
If nothing else is specified, then the local variables are destroyed when the
function ends its execution. This is because they are considered by default
automatic.
There is the possibility to keep the content of a variable between two executions
of the function that created it. The variable can be accessed only by that function and its content is maintained until the execution of the entire program ends.
In other words, a static local variable gives the possibility to store information
in a private way (because this information is available only to the function
where the variable is defined) and also in a permanent way (the information is
available during the entire execution of the program) [BK03]. This is performed
using the keyword static in front of the variables declaration:
static int counter=0;
Program 10.1.9 emphasizes the difference between static and automatic variables. The functions increment1() and increment2() increment and
display the value of a counter that receives the initial value 0 at the beginning
of these functions. They are repetitively called 10 times in the main() function. The difference between these two functions is the manner of declaring the
local variable counter. Within function increment1() it remains automatic, but within function increment2() it is declared static; this will maintain the value of the variable counter, belonging to the function increment2(), from an execution to the next one.
Once the program is executed, on the screen will be displayed:
Automatic variable:
1 1 1 1 1 1 1 1 1 1
Static variable:
1 2 3 4 5 6 7 8 9 10
The counter variable receives the initial value 0 at the beginning of each
function. It must be specified that if a variable is declared static, this line is
executed only when the function is called for the first time (this is the reason
why the value of the variable is not altered when the function is recalled).
Program 10.1.9
#include <stdio.h>
#include <conio.h>
173

Computer Programming The C Language


void increment1(void){
int counter=0;
counter++;
printf("%d ",counter);
}
void increment2(void){
static int counter=0;
counter++;
printf("%d ",counter);
}
void main(void){
int i;
clrscr();
printf("Automatic variable:\n");
for(i=1;i<=10;i++){
increment1();
}
printf("\nStatic variable:\n");
for(i=1;i<=10;i++){
increment2();
}
getch();
}

10.1.5 Changing the arguments of a function


There are two ways of passing arguments to functions:
by value;
by address.
By default, the arguments are passed by value (with one exception: the arrays;
their passing to functions will be separately discussed); therefore, the arguments
used in a functions call cannot be altered by the code that is executed within
the function. This is because the value of the actual parameter (the one used
when the function is called) is copied into the formal parameter of the function
(parameter that has a temporary aspect). This value can be changed within the
174

10 User-defined functions
function, but because it is only a copy of the value used in the functions call,
these changes have no effect on the actual parameter.
Program 10.1.10 creates and initializes a variable x within the main() function and then sends this value to the function pass_val() that increments the
received argument. Variable x is displayed at return from the function in order
to see that its value is not changed.
Program 10.1.10
#include <stdio.h>
#include <conio.h>
void pass_val(int x){
x++;
}
void main(void){
int x=10;
clrscr();
pass_val(x);
printf("x=%d", x); //it is displayed x=10
getch();
}
Programs that pass the parameters by value are more compact and have fewer
global variables (within functions the formal parameters are similar to local
variables) [BK03]. Using this way of passing the arguments, the functions dont
have access to the original variable, but only to their copies.
Nevertheless, sometimes the changing of actual parameters is required; in this
case they must be passed by address. The address of a variable is sent in the
functions call. The parameter is declared as pointer in the functions prototype
and the variable is indirectly accessed through this pointer [BK03]. This way
the changes are made right on the original variable.
Program 10.1.11 emphasizes the passing of arguments by address. The code is
very similar to the one used for the passing by value. The first difference that
should be noticed emerges at the call of the function pass_adr() that receives as argument the address of the variable x (&x). The second aspect is connected to the prototype of the function, where x is declared as pointer (*x).
Finally, the third thing regards the way of handling the variable x within the
175

Computer Programming The C Language


function (the operations with pointers must be used here): through the instruction (*x)++; the value stored at the address indicated by the pointer is accessed and incremented. Therefore, the changing is made right on the original
variable, which is then displayed in the function main() in order to see that
the changes have even been made.
Program 10.1.11
#include <stdio.h>
#include <conio.h>
void pass_adr(int *x){
(*x)++;
}
void main(void){
int x=10;
clrscr();
pass_adr(&x);
printf("x=%d", x); //it is displayed x=11
getch();
}

10.1.6 Passing arrays as arguments


Passing arrays as arguments is different from passing other variables, being an
exception from the usual rule of passing arguments by value [HS98]. The arrays
are always passed by address without explicitly specifying this through the
addressing operator &, because the name of an array is in fact the address of its
first element. Therefore, a function can access and alter any element of an array
received as argument.
Within program 10.1.12 a single-dimensional array is passed as argument. It
can be noticed that the function doubles() doesnt receive information about
the maximum dimension of the array (100), but only about the real number of
elements that are processed (n, which is 10). The array is declared within
main() and its elements receive initial values from 0 to 9. Within the function
doubles() each element of the array doubles its value. The array is displayed
on return from the function in order to see that the values of its elements are
changed.
176

10 User-defined functions
Program 10.1.12
#include <stdio.h>
#include <conio.h>
void doubles(int n, int v[]){
int i;
for(i=0;i<n;i++)
v[i]=v[i]*2;
}
void main(void){
int v[100], i;
clrscr();
for (i=0;i<10;i++) v[i]=i; //0 1 2 3 4 5 6 7 8 9
doubles(10,v);
for(i=0;i<10;i++)
printf("%d ", v[i]); //0 2 4 6 8 10 12 14 16 18
getch();
}
A two-dimensional array (a matrix) is passed as argument in a similar way.
Program 10.1.13 is an example of this matter. There is a difference: the function
that receives the matrix as argument (modifies()) requires information
regarding the maximum number of columns of the matrix (100), besides the
real number of rows (n, which is 2 in this case) and of columns (m, which is 3
in this case) used by the matrix.
Program 10.1.13
#include <stdio.h>
#include <conio.h>
void modifies(int n, int m, int a[][100]){
int i, j;
for(i=0;i<n;i++)
for(j=0;j<m;j++)
a[i][j]++;
}
void main(void){
177

Computer Programming The C Language


int a[100][100]={
{1, 2, 3},
{4, 5, 6}
};
int i, j;
clrscr();
modifies(2, 3, a);
for(i=0;i<2;i++){
for(j=0;j<3;j++)
printf("%d ", a[i][j]);
printf("\n");
}
getch();
}

10.2 Recursion
The recursion is the process of defining an entity using the same entity [HS98].
A function is recursive if it is called directly or indirectly by itself [BK03].
One of the simplest examples of recursion is the factorial of an integer number
n. It is the product of all integer numbers between 1 and n (including n) and
from the mathematical point of view is written n!. For instance, 4 factorial is
4!=1x2x3x4=24.
The implementations of both recursive and iterative (non-recursive) versions
are hereby presented (program 10.2.1). The function iterative_factorial() is very simple; it traverses the numbers between 1 and
n and multiply each number i with the already calculated product of its previous numbers.
For the recursive version of the factorial, the function recursive_factorial() is called by itself. For instance, if factorial of 3 must be
calculated:
n has the initial value 3, therefore the instruction on the else branch is
executed; the result will be 3 multiplied with the value returned by a new
call of the function, this time with the parameter n-1, which is 2;
n is 2, therefore the result is 2*recursive_factorial(1);
178

10 User-defined functions
n is 1, therefore result=1 (the true branch of the if instruction is
executed) and this third call of the function ends, returning the value 1 to
the second call;
the second call of the function calculates result=2*1=2 and returns this
value to the first call of the function;
the first call calculates result=3*2=6 and returns it where the function
was initially called (in main()).
Program 10.2.1
#include <stdio.h>
#include <conio.h>
int iterative_factorial(int n){
int i, result=1;
for(i=1;i<=n;i++)
result=result*i;
return result;
}
int recursive_factorial(int n){
int result;
if(n==1)
result=1;
else
result=n*factorial_recursiv(n-1);
return result;
}
void main(void){
int n;
clrscr();
printf("n="); scanf("%d", &n);
printf("Iterative: %d", iterative_factorial(n));
printf("\nRecursive: %d", recursive_factorial(n));
getch();
}
Generally, a recursive function has an if instruction that determines whether
the last call of the function was encountered or it must be called again. Without
179

Computer Programming The C Language


such an instruction the functions calls will never end and the program will have
a wrong functionality, usually within an infinite loop. In order to clarify these
things, printf() instructions could be placed inside recursive functions and
certain messages could be displayed this way at each call of the function.
When a function is called by itself, memory space is allocated for a new set of
automatic local variables and parameters and the function is executed from the
beginning with the new set of variables. Ones a recursive call is finished and the
execution of the program returns from that call of the function (with or without
returned value), the local variables and the old parameters are lost and the execution of the program continues from the point where the call that just ended
was made [HS98].
The recursive versions of certain programs do not necessary cause improvements regarding the speed of execution, the dimension of a program or the
memory use. Nevertheless, the recursion has several notable advantages
[HS98], [BK03]:
the code is more compact and easily written and understood than its iterative equivalent;
many algorithms become clearer and simpler in their recursive implementation; there are algorithms that have very difficult iterative versions;
some problems, especially those connected to the artificial intelligence
domain, have only recursive solutions;
there are software developers who work better with the recursive version.

10.3 Solved problems


10.3.1 A real number is read and passed to a function that transforms it from
Celsius to Fahrenheit and to another function that considers that it is a Fahrenheit value and transforms it to Celsius.
Program 10.3.1
#include <stdio.h>
#include <conio.h>
float C_F(float celsius){
return ((celsius*9)/5)+32;
}
180

10 User-defined functions

float F_C(float fahrenheit){


return ((fahrenheit-32)*5)/9;
}
void main(void){
float n;
clrscr();
printf("The number that must be transformed: ");
scanf("%f", &n);
printf("%.2f Celsius=%.2f Fahrenheit",n,C_F(n));
printf("\n%.2f Fahrenheit=%.2f Celsius",n,F_C(n));
getch();
}
10.3.2 The sum of two matrices (with user-defined functions). Three matrices
(a, b and s) are declared within main() function. Then a function used to
read the elements of a matrix is called, first for the matrix a and then for the
matrix b. Those two matrices are displayed through another user-defined function that is called for a and then for b. The sum of two matrices can be performed only if they have the same number of rows and the same number of
columns respectively. If this condition is not accomplished, then an error message is displayed and the program ends. Otherwise, the function that calculates
the sum is called and then the result matrix is printed.
The functions that are created have the following features:
Function read() is created to read a matrix; because it is a general function it can be used to read any matrix. Its parameters are:
o n, m the number of rows and of columns; these variables are
passed by address, therefore their values are available within
main() function;
o mat the matrix that is read; it is by default passed by address;
o name the name of the matrix that is read a string passed as
pointer.
Function write() is created to display a matrix (any matrix). It has the
following parameters:
181

Computer Programming The C Language


o n, m the number of rows and of columns; these variables are
passed by value;
o mat the matrix that is displayed;
o name the name of the matrix that is printed a string passed
as pointer.
Function sum(), which calculates the sum of two matrices has the following parameters:
o n, m the number of rows and of columns of the three matrices
(this function is called only if the matrices can be added);
o m1, m2 the matrices that are added;
o m3 the result matrix.
The functions are very simple and familiar regarding the code. It can be noticed
that the reading and the writing functions are called several times, with different
parameters; this way the program benefits from the advantages of repeated use
of a sequence of code described by a user-defined function. The main() function also becomes very simple and clear.
Program 10.3.2
#include <stdio.h>
#include <conio.h>
void read(int *n, int *m, int mat[][50], char *name){
int i, j;
printf("Reading - matrix %s\n", name);
printf("Number of rows: ");
scanf("%d", &(*n));
printf("Number of columns: ");
scanf("%d", &(*m));
for(i=0;i<(*n);i++)
for(j=0;j<(*m);j++){
printf("%s[%d][%d]=", name, i, j);
scanf("%d", &mat[i][j]);
}
}
void write(int n, int m, int mat[][50], char *name){
182

10 User-defined functions
int i, j;
printf("Writing - matrix %s\n", name);
for(i=0;i<n;i++){
for(j=0;j<m;j++)
printf("%3d ", mat[i][j]);
printf("\n");
}
}
void sum
(int n,int m,int m1[][50],int m2[][50],int m3[][50]){
int i, j;
for(i=0;i<n;i++)
for(j=0;j<m;j++)
m3[i][j]=m1[i][j]+m2[i][j];
}
void main(void){
int a[50][50], b[50][50], s[50][50];
int n_a, m_a, n_b, m_b;
clrscr();
read(&n_a, &m_a, a, "a");
read(&n_b, &m_b, b, "b");
clrscr();
write(n_a, m_a, a, "a");
write(n_b, m_b, b, "b");
if((n_a!=n_b)||(m_a!=m_b))
printf("Incorrect number of rows or columns!");
else{
sum(n_a, m_a, a, b, s);
write(n_a, m_a, s, "sum");
}
getch();
}
10.3.3 The implementation of some mathematical expressions. The user can
choose, through a repetitive menu, which expression to evaluate. Each expression is implemented within a separated function. Functions receive parameters
183

Computer Programming The C Language


passed by value or by address (according to the context) and return a value if
necessary. The program has the following menu:
1 The surface of a square;
2 The surface of a circle;
3 The surface and the height of an equilateral triangle;
0 Exit.
A while structure with an always true condition is used in order to have a
repetitive menu; the while cycle is left through the function exit() that is
called if the user chooses the option 0. Within the instruction while the menu
is displayed and the user is asked to enter his option; these actions are performed by the function menu() that returns the users option. Then, this option
is evaluated by a switch instruction and the program executes the branch that
corresponds to the option.
If the user chooses option 1, then he is asked to enter the side of the square.
This value is passed as argument to the function square(), which returns the
surface or 0 if the side is not a positive value (from a geometrical point of view
a square cannot have its side of a negative or zero value).
For option 2 the actions are performed in a similar manner; the surface of a
circle is calculated (if possible). It can be noticed the use of the constant M_PI
from the math.h library within the function circle().
The function triangle(), which implements option 3, is slightly more
complicated because it must calculate and send back two values. The instruction return cannot be used to return two separated variables. A solution is to
store these values in parameters that are passed by address. Therefore, the function triangle() has three parameters: the side of the triangle (passed by
value) and on the other hand the surface and the height (passed by address: &s,
&h). The values that are assigned to these last two parameters within the triangle() function are available to main() after this function is executed.
Program 10.3.3
#include
#include
#include
#include

<stdio.h>
<conio.h>
<stdlib.h>
<math.h>
184

10 User-defined functions
float square(float sd){
if(sd>0)
return sd*sd;
else
return 0;
}
float circle(float r){
if(r>0)
return M_PI*r*r;
else
return 0;
}
int triangle(float sd, float *s, float *h){
if(sd>0) {
*s=sd*sd*sqrt(3)/4;
*h=sd*sqrt(3)/2;
return 1;
}
else
return 0;
}
int menu(void){
int o;
printf("1-Square-surface\n");
printf("2-Circle-surface\n");
printf("3-Equilateral triangle-surface, height\n");
printf("0-Exit\n");
printf("Your option: ");
scanf("%d", &o);
return o;
}
void main(void){
int option;
float side, radius;
float s, h;
while(1){
185

Computer Programming The C Language


clrscr();
option=menu();
switch(option){
case 1: printf("The side: ");
scanf("%f", &side);
s=square(side);
if(s==0)
printf("Error!");
else
printf("Surface=%.2f",s);
break;
case 2: printf("The radius: ");
scanf("%f", &radius);
s=circle(radius);
if(s==0)
printf("Error!");
else
printf("Surface=%.2f",s);
break;
case 3: printf("The side: ");
scanf("%f", &side);
if(triangle(side,&s,&h)==0)
printf("Error!");
else{
printf("Surface=%.2f\n",s);
printf("Height=%.2f",h);
}
break;
case 0: exit(0);
default: printf("Wrong option!");
}
getch();
}
}
10.3.4 The first n Fibonacci numbers (0, 1, 1, 2, 3, 5, 8, ) are displayed in
three versions of code. Each version is written within a separated function, and
the user decides, through a menu, which version to use.
186

10 User-defined functions
The first version uses three variables: f1 with the initial value 0, f2 with the
initial value 1 and f3 that is calculated as f1+f2. At the end of each iteration
f1 takes the value of f2 and f2 the value of f3. The function fibo_var(),
which implements this version, receives as argument the variable n and doesnt
return anything.
The second version is probably the simple one; it stores the numbers within a
single-dimensional array. The first two elements of this vector receive the initial
values 0 and 1 respectively and the following elements are calculated as the
sum of the previous two elements. The function fibo_arr() receives as
argument the variable n and doesnt return anything.
The third version calculates each element in a recursive way. Thus, the function
fibo_rec() is called for each number that must be displayed. If n is greater
than 2, then the function calls itself again.
Program 10.3.4
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void fibo_var(int n){
int i, f1=0, f2=1, f3;
if(n==1)
printf("%d ", f1);
else if(n==2)
printf("%d %d ", f1, f2);
else{
printf("%d %d ", f1, f2);
for(i=3;i<=n;i++){
f3=f1+f2;
printf("%d ", f3);
f1=f2;
f2=f3;
}
}
}
void fibo_arr(int n){
int i, v[100];
187

Computer Programming The C Language


v[0]=0; v[1]=1;
for(i=2;i<n;i++)
v[i]=v[i-2]+v[i-1];
for(i=0;i<n;i++)
printf("%d ",v[i]);
}
int fibo_rec(int n){
if(n==1) return 0;
else if(n==2) return 1;
else
return fibo_rec(n-1)+fibo_rec(n-2);
}
int menu(void){
int o;
printf("1-Variables\n");
printf("2-Array\n");
printf("3-Recursion \n");
printf("0-Exit\n");
printf("Your option: ");
scanf("%d", &o);
return o;
}
void main(void){
int option, n, i;
while(1){
clrscr();
do{
printf("Enter a positive number.\n");
printf("n=");
scanf("%d", &n);
}while(n<=0);
option=menu();
switch(option){
case 1: fibo_var(n); break;
case 2: fibo_arr(n); break;
case 3: for(i=1;i<=n;i++)
188

10 User-defined functions
printf("%d ",fibo_rec(i));
break;
case 0: exit(0);
default: printf("Wrong option!");
}
getch();
}
}

10.4 Questions and exercises


A. Find the error.
1. #include <stdio.h>
//and other necessary libraries
void calculate(void){
//do something
}
void main(void){
int x;
printf("x="); scanf("%d",&x);
calculate(x);
}
2. #include <stdio.h>
void calculate(int a, int b){
x=a+b;
}
void main(void){
int x, a, b;
printf("a="); scanf("%d",&a);
printf("b="); scanf("%d",&b);
calculate(a,b);
printf("x=%d",x);
}
3. #include <stdio.h>
void calculate(int a, int b){
int c;
c=a+b;
return c;
189

Computer Programming The C Language


}
void main(void){
int x, a, b;
printf("a="); scanf("%d",&a);
printf("b="); scanf("%d",&b);
x=calculate(a,b);
printf("x=%d",x);
}
4. #include <stdio.h>
int x;
void calculate(void){
x=a+b;
}
void main(void){
int a, b;
printf("a="); scanf("%d",&a);
printf("b="); scanf("%d",&b);
calculate();
printf("x=%d",x);
}
5. #include <stdio.h>
void calculate(int x){
x++;
}
void main(void){
int x;
printf("x="); scanf("%d",&x);
calculate(&x);
printf("x=%d",x);
}
6. #include <stdio.h>
void calculate(int *a, int *b){
int aux;
aux=*a;
*a=*b;
*b=aux;
}
void main(void){
int a, b;
190

10 User-defined functions
printf("a="); scanf("%d",&a);
printf("b="); scanf("%d",&b);
calculate(a,b);
printf("a=%d, b=%d",a, b);
}
7. #include <stdio.h>
void calculate(int x){
x++;
}
void main(void){
int x;
printf("x="); scanf("%d",&x);
calculate(x)=100;
}
8. #include <stdio.h>
int calculate(int x, int y){
return x+y;
}
void main(void){
int sum, a=2, b=3;
sum=calculate(a+b);
}
9. #include <stdio.h>
int calculate(void){
int counter=0;
//counts how many times the function is called
counter++;
return counter;
}
void main(void){
int i, c;
for(i=1;i<=10;i++) c=calculate();
printf("Number of calls: %d",c);
}
10. #include <stdio.h>
int calculate(int x){
if(x==1) return 1;
else return x*calculate();
191

Computer Programming The C Language


}
void main(void){
int i;
for(i=1;i<=7;i++)
printf("%d ",calculate(i));
}
B. Considering the following programs, specify what will be printed on the
screen once these programs are executed.
11. #include <stdio.h>
float calculate(int a, int b){
return a/b;
}
void main(void){
int a=1, b=2;
printf("%.2f",calculate(a,b));
}
12. #include <stdio.h>
void calculate(int x){
x++;
}
void main(void){
int a=1;
calculate(a);
printf("%d",a);
}
13. #include <stdio.h>
void calculate(int *x){
(*x)++;
}
void main(void){
int a=1;
calculate(&a);
printf("%d",a);
}
14. #include <stdio.h>
int x;
void calculate(int a){
x=++a;
192

10 User-defined functions
}
void main(void){
int y=1;
calculate(y);
printf("%d %d",x,y);
}
15. #include <stdio.h>
int x;
int calculate(int a){
x=++a;
return a;
}
void main(void){
int y=1,z;
z=calculate(y);
printf("%d",z);
}
16. #include <stdio.h>
void calculate(int x, int *y){
x++;
(*y)++;
}
void main(void){
int a=1, b=1;
calculate(a,&b);
printf("%d %d",a,b);
}
17. #include <stdio.h>
#include <conio.h>
void function(void){
char c;
printf("\nA letter or / to finish ");
c=getch();
if(c!='/'){
function();
putch(c);
}
}
void main(void){
193

Computer Programming The C Language


function();
}
C. Choose the correct answer (one only).
18. The prototype of a function contains:
a) the name of the function; b) the type of the returned value; c)
the type and the name of each argument; d) the answers a, b and c are
correct; e) all answers are wrong.
19. A function that has the prototype count(float mark) returns:
a) nothing; b) an int; c) a float; d) a char; e) a pointer.
20. A variable that is available to the entire program is called:
a) local; b) national; c) international; d) global; e) universal.
21. A variable that is created each time a function is called and that is destroyed when the function is left is named:
a) local; b) national; c) international; d) global; e) universal.
22. Which of the following calls of the function with the prototype int
f1(void); is wrong?
a) n=f1();; b) n=2*f1();; c) f1()=n;; d)
printf("%d",f1());; e) if(f1()==n) n++;.
23. The function with the prototype void f2(int x); is considered.
Which of the following calls is wrong?
a) f2(7);; b) int n=1; f2(n);; c) f2(3+4);; d) int
a=1, b=2; f2(a+b);; e) int a=1, b=2; f2(a,b);.
24. Which of the following categories of variables dont exist in the C programming language?
a) local; b) global; c) static; d) automatic; e) all answers are
wrong.
25. The arguments of a function can be passed by:
a) value; b) address; c) mail; d) fax; e) the answers a and b
are correct.
D. Write programs to solve the following problems.
194

10 User-defined functions
26. There is considered a vector of real numbers. Write a function that returns the maximum value.
27. Two natural numbers are read from the keyboard. Write a function that
finds and returns the greatest common divisor of these two numbers
(Euclids algorithm).
28. Write a function that verifies if a number n received as argument is
prime or not.
29. Perform the product of two matrices (with user defined functions).
30. Write a function that counts how many times a character c occurs within a string s.
31. Three real numbers (a, b and c) are read within main() function and
are passed to another function that verifies if they can be the sides of a
triangle (a+b>c, a+c>b and b+c>a); the function returns 1 if the
numbers can form a triangle and 0 otherwise.
32. Write a function that receives as argument a vector of real numbers,
representing the coefficients of a polynomial function (f(x)=anxn+an-1xn1
+ +a1x+a0) and a number x and returns the value of that function for
the number x.
33. Write a function that receives as argument a vector of real numbers,
representing the coefficients of a polynomial function (f(x)=anxn+an-1xn1
+ +a1x+a0) and creates, in another vector, the coefficients of the
functions derivative.

195

Chapter 11
User-defined types
Besides the standard data types (char, int, float, double), C programming language provides several mechanisms for creating customized data types
(user-defined types). Two of these mechanisms are the subject of this chapter:
the structure an entity that gathers several variables that are related from a
logical point of view, under a single name;
the enumeration a list of named integer constants.

11.1 The structure


A structure is a collection of variables referred through a single name. Structures are successfully used when complex data must be organized because they
allow gathering different variables (that have a certain relation in a given context) and handling them as a unit not as separated entities [BK03].
The variables that belong to a structure are called members or fields and can
have different data types. Each member has a name of its own, used in order to
select it within the structure.

11.1.1 Definition and use


The keyword struct is used to define a structure. The instruction that performs this action has the following general form [BH92]:
struct structure_name{
type1 var11, var12;
type2 var2;

typen varn;
} list_of_variables;
where:

11 User-defined types
structure_name is an optional label; the new data type can be used to
declare variables through this label;
var11, var12, var2, , varn are the members of the structure;
type1, type2, , typen represent the types of the structures members;
the variables that have the same type can be defined in a single instruction,
separated by comma (,);
the variables that dont have the same type are defined in different instructions, separated by semicolon (;);
the members are declared within a block enclosed by curly brackets ({});
list_of_variables is also optional and can contain one or more
variables;
the structures definition ends with semicolon (;), because it is an instruction, on the whole;
though both structure_name and list_of_variables are optional, they cannot be omitted in the same time; at least one of them should be
present, otherwise the structures definition has no sense (since neither variables are declared, nor the structure receives a name to be used later).
A first example of a structure, quite simply, is represented by the coordinates of
a point in a plane. The structure can be defined as:
struct point{
int x;
int y;
};
or as:
struct point{
int x, y;
};
The members of a structure can have different types, as shown in the following
example that defines several features of a student:
struct student{
197

Computer Programming The C Language


int id;
char name[20];
float mark;
};
The definition of a structure doesnt allocate memory space. It only describes a
new data type that can be considered a pattern.
The variables of a structure type can be declared right within the instruction that
defines the type. The following example declares two variables A and B of type
point:
struct point{
int x;
int y;
}A,B;
If the structure received a name, then the variables can be declared later in the
program, wherever the structure is visible. The name of the structure, preceded
by the keyword struct is used when a variable is declared. The following
instruction declares a variable using the type student previously declared:
struct student stud1;
In C++ programming language a variable can also be declared without the
keyword struct, the name of the type being enough. Therefore, the previous
variable can be declared as: student stud1;.
The members of a structure variable can receive initial values right when the
variable is declared. The following instruction declares and initializes two
points: A with the coordinates (3,4) and B with the coordinates (10,4):
struct point A={3,4}, B={10,4};
Each member of a structure can also be used as an independent variable, but its
name is a little bit longer, because it also includes the name of the structure
variable that contains the member. The operator ., placed between the name
of the structure variable and the name of the member variable is used to access
the members of a structure:
A.x=3;
A.y=4;
198

11 User-defined types
stud1.mark=9.75;
strcpy(stud1.name,"Ritchie");
printf("%s %.2f",stud1.name,stud1.mark);
The name of a member variable can be identical with the name of a usual variable (non-member) without creating conflicts; the difference between the two
variables is made by the context where they are accessed [BK03] (the member
variable is always preceded by the name of the structure variable that contains
it). Based on the same reasoning, a member of a structure can have the same
name with a member of another structure (this is not recommended; it could be
used only if the elements have a very close meaning for instance, the radius
can be a variable that belongs to a structure that describes a circle and also to
one that describes an arc).
Program 11.1.1 is a complete example where the structure student is used.
The structure is global (it is defined outside any function) in order to extend its
visibility on the entire program (because this program contains a single function
main() the structure could also be defined within this function). A variable s of type student is defined and some of its features are read (id, name,
exam mark, laboratory mark). The final mark is calculated and displayed. The
program is very simple, being only an exercise of defining and using a structure.
Program 11.1.1
#include <stdio.h>
#include <conio.h>
struct student{
int id;
char name[20];
float exam, lab, final;
};
void main(void){
struct student s;
clrscr();
printf("Id: ");
scanf("%d",&s.id);
printf("The name: ");
199

Computer Programming The C Language


scanf("%s",s.name);
printf("The exam mark: ");
scanf("%f", &s.exam);
printf("The laboratory mark: ");
scanf("%f", &s.lab);
s.final=(2*s.exam+s.lab)/3;
printf("%s has the final mark %.2f",s.name,s.final);
getch();
}
The entire information contained in a structure variable can be copied into
another variable of the same type through a single assignment (it is not necessary to perform separated assignments for each member variable). The structure
point is used in program 11.1.2 in order to illustrate this aspect. Two variables A and B are defined using this structure. The coordinates x and y of the
variable A are initialized with the values 3 and 4, respectively. Then, the variable A is assigned to the variable B, which is displayed; B(3,4) is printed on
the screen.
Program 11.1.2
#include <stdio.h>
#include <conio.h>
struct point{
int x;
int y;
};
void main(void){
struct point A, B;
clrscr();
A.x=3; A.y=4;
B=A;
printf("B(%d,%d)",B.x,B.y);
getch();
}
The members of a structure can have standard types or user-defined types.
Therefore, within a structure, variables that have a structure type can be defined. For instance (program 11.1.3), it can be imagined a structure called cir200

11 User-defined types
cle that contains a member of type point, representing the coordinates of the
circles center, and a member of type float, representing the radius of the
circle:
struct circle{
struct point center;
float radius;
}c;
Three names are required to access the coordinates of the circles center: the
coordinates name (x), the centers name (center) and the circles name (c):
c.center.x=10;
Program 11.1.3
#include <stdio.h>
#include <conio.h>
struct point{
int x;
int y;
};
struct circle{
struct point center;
float radius;
};
void main(void){
struct circle c;
clrscr();
c.center.x=10;
c.center.y=20;
c.radius=5.37;
printf("center: (%d,%d)",c.center.x,c.center.y);
printf("\nradius: %.2f",c.radius);
getch();
}
A structure can also contain an array (with one or more dimensions):
struct vector{
201

Computer Programming The C Language


int v[10];
int max;
}v_str;
An element of the array (for instance, that with the index 3) is naturally accessed this way:
v_str.v[3];
Program 11.1.4 uses this structure that contains a vector of integers and a variable that stores the maximum value of the array. The functions of the program
(read(), write() and maximum()) operate on a global variable, v_st, of
a structure type.
Program 11.1.4
#include <stdio.h>
#include <conio.h>
const n=10;
struct vector{
int v[n];
int max;
}v_st;
void read(){
int i;
for(i=0;i<n;i++){
printf("v[%d]=",i);
scanf("%d",&v_st.v[i]);
}
}
void write(void){
int i;
for(i=0;i<n;i++)
printf("%d ",v_st.v[i]);
}
void maximum(void){
202

11 User-defined types
int i;
v_st.max=v_st.v[0];
for(i=1;i<n;i++)
if(v_st.v[i]>v_st.max)
v_st.max=v_st.v[i];
}
void main(void){
clrscr();
read();
write();
maximum();
printf("\nMax: %d", v_st.max);
getch();
}

11.1.2 Structures and functions


As any other variables, the structure variables can be passed as arguments to
functions (by value or by address) or returned from functions. In these cases the
structure must have a global declaration in order to be available to many elements of the program.
Program 11.1.5 illustrates how a structure variable can be returned from a function. The features of a student are read within the function; they are stored in a
structure variable that is returned to main() function. This reading is called
for two variables of type student.
Program 11.1.5
#include <stdio.h>
#include <conio.h>
struct student{
int id;
char name[20];
float mark;
};
struct student read(void){
203

Computer Programming The C Language


struct student stud;
printf("Id: ");
scanf("%d",&stud.id);
printf("Name: ");
scanf("%s",stud.name);
printf("Mark: ");
scanf("%f", &stud.mark);
return stud;
}
void main(void){
struct student s1,s2;
clrscr();
s1=read();
s2=read();
printf("%s: %.2f\n",s1.name,s1.mark);
printf("%s: %.2f",s2.name,s2.mark);
getch();
}
Program 11.1.6 is an example of passing by value some structure variables.
Two variables A and B of type point are declared and initialized within
main(). Then the variables are passed to a function that calculates and returns
the distance between these two points (d
xB xA
yB yA ).
Program 11.1.6
#include <stdio.h>
#include <conio.h>
#include <math.h>
struct point{
int x;
int y;
};
float distance(struct point a, struct point b){
return sqrt(pow((b.x-a.x),2)+pow((b.y-a.y),2));
}
void main(void){
204

11 User-defined types
struct point A={3,4}, B={10,4};
clrscr();
printf("AB=%.2f", distance(A,B));
getch();
}
Program 11.1.7 passes by address a structure variable. A point A is declared and
initialized within main(). This point must be moved to other coordinates. In
order to have a real movement, the point must be passed by address to the function that performs this movement. The new coordinates are passed by value. On
return from the function the new location of the point is displayed to verify that
the movement was made. It is found that the values of the structures variables
were changed.
Program 11.1.7
#include <stdio.h>
#include <conio.h>
struct point{
int x;
int y;
};
void move(struct point *a, int new_x, int new_y){
(*a).x=new_x;
(*a).y=new_y;
}
void main(void){
struct point A={3,4};
clrscr();
move(&A,10,14);
printf("A(%d,%d)", A.x,A.y);
getch();
}

205

Computer Programming The C Language

11.1.3 Arrays of structures


The structure types can be used to create arrays, each element of the array being
in fact a structure (a group of variables). Obviously, the structure should be
defined before the array.
If the number of occurrences of each vowel (a, e, i, o, u) in a text should be
counted, then an array of 5 elements with the following structure can be used:
struct count_vowels{
char vowel;
int counter;
};
Program 11.1.8 solves this problem. First, the structure count_vowels is
defined and then an array v of 5 elements of the previously defined type. The
elements of the array are also initialized at declaration: the members vowel
with a vowel and the members counter with 0. A text declared as string is
read within main() and then it is passed to the function count(). Within
this function the vowels are traversed and each vowel v[i].vowel is
searched into the text, comparing each letter of the text (text[i]) with the
searched vowel. If they are identical, then the counter connected to that vowel
(v[i].counter) is incremented. In order to ignore the difference between
uppercases and lowercases, each letter of the text is transformed to lowercase
(tolower(text[j])), as it is stored into the array of vowels. At the end of
the program, a function that displays the vowels and their counters is called.
Program 11.1.8
#include
#include
#include
#include

<stdio.h>
<conio.h>
<string.h>
<ctype.h>

struct count_vowels{
char vowel;
int counter;
};
struct count_vowels v[5]={
{'e',0},

{'a',0},

206

11 User-defined types
{'i',0},
{'o',0},
{'u',0}};
void count(char *text){
int i, j;
for(i=0;i<5;i++)
for(j=0;j<strlen(text);j++)
if(tolower(text[j])==v[i].vowel)
v[i].counter++;
}
void display(void){
int i;
for(i=0;i<5;i++)
printf("\n%c: %d",v[i].vowel,v[i].counter);
}
void main(void){
char text[50];
clrscr();
printf("Enter the text: ");
gets(text);
count(text);
display();
getch();
}

11.1.4 Pointers to structures


C programming language allows the declaration of pointers to structures as any
other pointers are declared. Considering the structure student, created at the
beginning of this chapter, the following instruction declares a pointer:
struct student *p;
The address of a variable of the same structure type can be assigned to a pointer:
p=&stud;
207

Computer Programming The C Language


where stud is a variable of type student.
There are two ways of accessing the members of a structure through a pointer:
the classic version, through the dereferenced pointer (*p) and using the
operator .: (*p).mark;; this version was illustrated when a structure
was passed by address;
the special version, using the operator ->: p->mark;; program 11.1.9
emphasizes this way of accessing a structure. A variable stud and a pointer p are declared using the structure student; the address of the variable
stud is assigned to the pointer. Then, the members of the structure receive
values through the pointer. At the end, the variable stud is displayed in order to verify if it was correctly accessed.
Program 11.1.9
#include <stdio.h>
#include <conio.h>
#include <string.h>
struct student{
int id;
char name[20];
float mark;
};
void main(void){
struct student stud, *p;
clrscr();
p=&stud;
p->id=1;
strcpy(p->name,"Ritchie");
p->mark=10;
printf("%s: %.2f",stud.name, stud.mark);
getch();
}

208

11 User-defined types

11.2 The enumeration


An enumeration is a set of named integer constants that specifies all the legal
values that can be taken by a variable of that type [HS98]. The general form of
an instruction that defines an enumeration is [BH92]:
enum enumeration_name{
const1_name=val1;
const2_name=val2;

constn_name=valn;
} list_of_variables;
where:
enum is the key word used to define the enumeration;
enumeration_name is an optional label associated to the enumeration;
const1_name, const2_name, , constn_name are the names of the
constants that form the enumeration;
val1, val2, , valn are the values associated to the constants; these
values are optional; if they are present, they should be integers; if they are
omitted, then it is considered that the value associated to a constant is the
value associated to the previous constant plus 1 and the value 0 is associated by default to the first constant (if nothing else is specified);
list_of_variables is an optional way of declaring variables using the
enumeration that has just been defined.
As example, an enumeration that contains the days of a week is considered:
enum day {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};
and two variables of this type:
enum day today, tomorrow;
The variable of enumeration type can be used in instructions as:
today=Sunday;
if(today==Sunday) tomorrow=Monday;
209

Computer Programming The C Language


else tomorrow=today+1;
printf("%d", today); //a number between 0 and 6
It is important to emphasize that each constant of an enumeration is associated
(by default or not) to an integer value. Therefore, these constants can be used
wherever an integer is necessary.
The explicitly association of values to the constants of an enumeration can be
made as in the following example:
enum month {Jan=31, Feb=28, Mar=31, Apr=30, May=31,
Jun=30, Jul=31, Aug=31, Sep=30, Oct=31, Nov=30,
Dec=31};
An enumeration where only some constants have explicitly associated values is
also correct. Each of the rest will have a value with a unit greater than the previous constant. In the following example, the constant fifth will have by
default the value 5 because it follows the constant fourth that has explicitly
associated the value 4:
enum
perfect_intervals{unison=1,
octave=8};

fourth=4,

fifth,

Program 11.2.1 defines, within an enumeration, the three colors of the traffic
light. The values 0, 1 and 2 are, by default, associated to these colors. An
integer number (0, 1 or 2) is randomly generated in main() and then it is
passed to the function traffic_light().When submitting, the number is
identified with one of the three constants of the enumeration. The function only
generates a command (simulated by a text message) according to the color of
the traffic light received as argument. The command is returned and displayed
by main() function.
Program 11.2.1
#include
#include
#include
#include
#include

<stdio.h>
<conio.h>
<stdlib.h>
<time.h>
<string.h>

enum color{RED,YELLOW,GREEN};
char *traffic_light(enum color tl_color){
210

11 User-defined types
char *command;
switch(tl_color){
case RED:
strcpy(command,"Stop!");
break;
case YELLOW:
strcpy(command,"Stop if possible!");
break;
case GREEN:
strcpy(command,"Pass!");
break;
}
return command;
}
void main(void){
clrscr();
randomize();
printf("%s",traffic_light(random(3)));
getch();
}

11.3 Questions and exercises


A. Find the error.
1. struct person{
char name[20];
int age;
}
2. struct circle{
int x;
int y;
float radius;
aCircle;
};
3. struct
char name[20];
211

Computer Programming The C Language


float salary;
}anEmployee;
4. struct{
char name[20];
float salary;
};
5. struct employee{
char name[20];
float salary;
};
struct employee anEmployee;
salary=2500;
6. struct employee{
char name[20];
float salary;
};
struct employee anEmployee, *aPointer;
aPointer=&anEmployee;
aPointer.salary=2500;
7. enum cardinal_point{east,west,north,south};
enum cardinal_point point=east;
printf("%s", point);
B. Considering the following programs, specify what will be printed on the
screen once these programs are executed.
8. #include <stdio.h>
#include <conio.h>
struct product{
char name[20];
float quantity, price;
};
void main(void){
struct product prod1={"bread",20,1.5}, prod2;
clrscr();
prod2=prod1;
printf("%.2f",prod2.price);
getch();
}
212

11 User-defined types
9. #include <stdio.h>
#include <conio.h>
#include <string.h>
struct polygon{
char name[20];
int sides;
};
void modify(struct polygon pol){
strcpy(pol.name,"heptagon");
pol.sides=7;
}
void main(void){
struct polygon p={"square",4};
clrscr();
modify(p);
printf("The %s has %d sides", p.name, p.sides);
getch();
}
10. #include <stdio.h>
#include <conio.h>
#include <string.h>
struct polygon{
char name[20];
int sides;
};
void modify(struct polygon *pol){
strcpy((*pol).name,"heptagon");
(*pol).sides=7;
}
void main(void){
struct polygon p={"square",4};
clrscr();
modify(&p);
printf("The %s has %d sides", p.name, p.sides);
getch();
}
11. #include <stdio.h>
#include <conio.h>
enum boolean{false,true};
213

Computer Programming The C Language


void main(void){
enum boolean f;
float nota=7.25;
clrscr();
if(nota<5) f=false;
else f=true;
printf("%d",f);
getch();
}
C. Choose the correct answer (one only).
12. A structure contains:
a) a single variable; b) several variables of the same type; c) several variables gathered under the same name; d) several variables with
the same initial value; e) several constants.
13. A structure is defined by the keyword:
a) user; b) defined; c) type; d) struct;
e) structure.
14. Which of the following operators can be used to access the members of
a structure:
a) .; b) &; c) *; d) #; e) \.
15. In the context of a structure, a member is:
a) the data type of the structure; b) a variable of the structure; c) a
pointer to the structure; d) an array of structures; e) all answers are
wrong.
16. Which of the following instructions accesses in a correct manner a
member m of a structure variable s?
a) s.m; b) s&m; c) s(m); d) s[m]; e) none of them.
17. Which of the following instructions accesses in a correct manner a
member m through a pointer p to a structure?
a) p.m; b) p[m]; c) p&m; d) p*m; e) p->m.
18. The enumeration is:

214

11 User-defined types
a) a list of integer constants; b) a list of variables of the same type;
c) a waiting list; d) a list of variables that can have different types;
e) all answers are wrong.
19. What will be printed on the screen once the following program is executed?
#include <stdio.h>
void main(void){
enum season{spring=1,summer,autumn,winter};
enum season now=autumn;
printf("%d",now);
}
a) autumn; b) 3; c) 2; d) 4; e) the program contains an error.
D. Write programs to solve the following problems.
20. A bouquet of flowers must be created. It may contain several types of
flowers and several flowers of each type (for example: 5 roses, 3 fern
leaves, and a bamboo). Simulate the content of a bouquet. Suggestion:
the bouquet can be an array of structure variables, the structure containing two fields: the name of a flower and the number of flowers with that
name used for the bouquet.
21. Calculate, using Herons formula, the surface of a triangle that is described by three points whose coordinates are read from the keyboard.
Suggestion: there will be used a structure of type point (with the two
coordinates); then structures of type segment (two points) or triangle
(three points) can be used. The lengths of the three segments that form
the triangle are calculated. Then the surface can be found with Herons
formula A
s s a s b s c , where a, b and c are the lengths
of the sides and s is the semi-perimeter.
22. Define a structure that describes a date through three fields (year,
month, and day). Write a function that compares two dates received as
argument. The function will have three versions:
a. it returns 0 if the dates are equals and 1 otherwise;
b. it returns 0 if the dates are equals, -1 if the first date is less than
the second and 1 if the first date is greater than the second;
215

Computer Programming The C Language


c. it returns the number of years, months and days between the two
dates.
23. Imagine a card game with two players. There will be used an enumeration containing the four kinds of cards (club, diamond, heart, spade),
each one having associated a value set by the programmer. Each player
receives a card that is randomly generated and the player that has the
card with a greater value wins.

216

Chapter 12
Files
The programs created in the previous chapters are operating on data stored in
RAM (Random Access Memory). This data is lost at the end of the programs.
The files are a method of storing data on disk. Thus, data is maintained and it is
available even after the execution of the current program. Therefore, a file is a
collection of data, it has a name and a location. The management of files is
performed by the operating system.
The connection between a C program and a file is made through a stream. This
stream is created once the file is opened and it is destroyed when the file is
closed. Some other operations can be performed between these two actions:
reading data from a file (this is an input action that brings data from disk to
RAM), processing this data and writing it into the file (an output action that
transfers the data from RAM back to disk).
Although there are many types of files (documents, images, databases, programs), all of them are represented by two basic types associated with two
streams [HS98], [CH96]:
text sequence of characters organized by lines;
binary sequence of 1s and 0s.

12.1 File handling


The stream that represents the connection between a C program and a file uses a
pointer to a new data type, FILE, which is part of the stdio.h header file.
The functions that operate with files are also part of this header file. The file
pointer is used by all the actions performed on the file. Its declaration is made
by an instruction as:
FILE *f;

Computer Programming The C Language

12.1.1 File opening


In order to access the content of a file, a program must open that file first. This
action is performed by the function fopen() that creates the connection between the program and the file. This function has the following prototype:
FILE *fopen(const char *file_name, const char mode);
where:
file_name is a string containing the name of the file that is opened. If the
file is not placed in the current folder, then the entire path must be specified.
If the operating system that is used is based on DOS (as Microsoft Windows
is) then the components of the file path are separated by backslash (\):
C:\Documents\Programs\ex1.txt. Unfortunately, the \ character has a special meaning within a string; the compiler will try to understand
the entity that follows this character (it expects to find sequences as \n,
\t). In these cases (when the file path is literally mentioned), the backslash must be doubled: C:\\Documents\\Programs\\ex1.txt. If
the path is read from the keyboard, then it is not necessary to double the
character \;
mode defines how the file is opened. This parameter contains two components:
o the first one specifies if the file is opened for reading (r read),
writing (w write), appending (a append) or for a mixture of
these (table 12.1.1 [HS98], [CH96], [BH92]);
o the second one is a letter that follows right after the first component and specifies if the file is opened in text mode (t) or in binary mode (b). If this second component is omitted, then the file
is considered of text type.
Table 12.1.1 Possible values of parameter mode
Mode

Meaning

Opens a file only for reading. The file must exist; otherwise, the
function returns NULL. After the opening action, the position
indicator (the file pointer) is placed at the beginning of the file.
218

12 Files

Opens a file only for writing. If the file doesnt exist, it is


created; if it exists, its content is overwritten (the entire content
prior of opening is lost).

Opens a file for appending. If the file doesnt exist, it is created;


if it exists, the appending is made at the end of the file (therefore, its content is not lost). After this opening, the position
indicator is placed at the end of the file.

r+

Opens a file for reading and writing. If the file doesnt exist, the
function returns NULL; if it exists, a writing without repositioning the file pointer will alter the prior content of the file, because this opening places the position indicator at the beginning
of the file.

w+

Opens a file for reading and writing. If the file doesnt exist, it
is created; if it exists, its content is overwritten.

a+

Opens a file for reading and writing. If the file doesnt exist, it
is created; if it exists, the appending is made at the end of the
prior content (because the opening places the position indicator
at the end of the file).

Function fopen() returns a file pointer or NULL if an error is encountered.


The following sequence of code opens a text file for reading:
FILE *f;
f=fopen("test.txt","r");
//actions performed on the file
Though the previous sequence doesnt contain compilation errors, it is not a
complete one. Function fopen() returns a valid pointer if it is able to open the
file, but if some errors are encountered during the opening action, then the
function returns NULL and no other actions can be performed on that file. For
these reasons, the program must verify if the opening action succeeded. Therefore, fopen() function is usually called within a sequence of code as follows:

219

Computer Programming The C Language


FILE *f;
if((f=fopen("test.txt","r"))==NULL){
printf("The file cannot be opened");
getch();
return;
}
// actions performed on the file
This way, a message is displayed if some errors are encountered during the
opening action and that area of the program is left because it is impossible to
execute any actions on the file. This method will detect any error that can occur
when a file is opened (e.g.: opening a file that doesnt exist for reading, opening
a read-only file for writing, creating a file within a location where the user
doesnt have the permission to write or where there is not enough free space).

12.1.2 File closing


Function fclose() is used to close a file. It has the following prototype:
int fclose(FILE *f);
where f is the file pointer returned by function fopen(). The function returns
0, if the action of closing the file can be performed or EOF, in case of an error
(fclose() usually fails only if there is not enough space on the disc or if the
file is on a removable disk that is extracted before the closing action is finished).
The files are automatically closed when the program ends its execution. Nevertheless, their explicit closing is recommended for several reasons:
it ensures that all data from the temporary memory is written into the file (a
reading of the files content without closing and reopening it may not catch
the last data that is sent for writing);
it frees the file pointer, making it available for reuse; the operating systems
have a limit regarding the number of files that can be simultaneously
opened, therefore it could be necessary to close a file in order to open
another one (there is a constant, FOPEN_MAX, which returns the maximum
number of files that can be simultaneously opened);
220

12 Files
if the program crashes, then the automatic closing of the files is not executed; in this case the files that were not explicitly closed could remain
opened, being temporary inaccessible to other programs.
The following instruction closes in a correct manner the file that was previously
opened by fopen():
fclose(f);

12.1.3 File input/output actions


The functions that perform the reading from a file and the writing into a file are
similar to those used for reading from the keyboard and writing on the screen.
The differences are that the name of the functions has the prefix f and that
they have an extra argument: the file pointer.
Char input/output
The characters can be read and written through functions fgetc() and
fputc(), respectively. These have the prototypes:
int fgetc(FILE *f);
int fputc(int c, FILE *f);
Function fgetc() returns the next character from the file indicated by pointer
f or constant EOF (End Of File) if the end of the file is reached or if a reading
error is encountered.
Function fputc() writes character c received as argument into the file indicated by pointer f. If an error occurs, then the function returns EOF.
Program 12.1.1 copies character by character the content of a text file (input.txt) into another text file (output.txt). In order to verify the reading, the characters are also displayed on the screen. The input file is opened for
reading (r) and the output file for writing (w). Because the number of the elements in a file is usually unknown, the reading is performed within a while
instruction, as long as the reading function (this time fgetc()) doesnt return
EOF. When the end of the file is reached, the while is left.

221

Computer Programming The C Language


Program 12.1.1
#include <stdio.h>
#include <conio.h>
void main(void){
FILE *fin, *fout;
char c;
clrscr();
if((fin=fopen("input.txt","r"))==NULL){
printf("Error: input file.");
getch();
return;
}
if((fout=fopen("output.txt","w"))==NULL){
printf("Error: output file.");
getch();
return;
}
while((c=fgetc(fin))!=EOF){ //file reading
fputc(c, fout); //file writing
putch(c); //writing on the screen
}
getch();
fclose(fin); fclose(fout);
}

String input/output
Functions fgets() and fputs() are used to read and to write, respectively,
a string from/into a file. Their prototypes are:
char *fgets(char *s, int n, FILE *f);
int fputs(const char *s, FILE *f);
Function fgets() reads characters from the file indicated by pointer f and
stores them into string s. The reading stops when n-1 characters were read or
when the end of the line is reached. If the reading stops because the end of the
line was reached, meaning that the new line character was read, then this character will be part of the string too. The terminator \0 is added at the end of
222

12 Files
the string s. The function returns the string s or NULL if the position indicator
is at the end of the file or if an error occurs.
Function fputs() writes string s into the file indicated by pointer f. The last
written character is returned or EOF if an error occurs.
Program 12.1.2 considers an input file (courses.txt) that contains on each
row the name of a discipline from the curricula, written on maximum 40 characters. Each discipline is read into string s and the user is asked to enter the
name of the teacher, which is then concatenated to the name of the discipline.
The resulted string is written into the output file (tutors.txt). The program
finishes when the end of the input file is reached and the function fgets()
returns NULL.
Program 12.1.2
#include <stdio.h>
#include <conio.h>
#include <string.h>
void main(void){
FILE *fin, *fout;
char s[80],teacher[30];
clrscr();
if((fin=fopen("courses.txt","r"))==NULL){
printf("Error: input file.");
getch();
return;
}
if((fout=fopen("tutors.txt","w"))==NULL){
printf("Error: output file.");
getch();
return;
}
while((fgets(s,40,fin))!=NULL){//file reading
printf("Teacher for: %s", s);
gets(teacher); //keyboard reading
strcat(s,teacher);
strcat(s,"\n");
fputs(s, fout); //file writing
}
223

Computer Programming The C Language


fclose(fin); fclose(fout);
}

Formatted input/output
If a formatted reading or writing is needed, then functions fscanf() and
fprintf() will be used. These are similar to functions scanf() and
printf() that are used for the reading/writing of the standard devices (keyboard and screen); for this reason they will not be detailed once again here. The
single difference is an extra parameter that specifies the file pointer. The prototypes of the functions that perform formatted input/output actions on a file are:
int fscanf(FILE *f, const char* format [, addr,...]);
int fprintf(FILE *f, const char* format [, arg,...]);
Function fscanf() returns EOF if the end of the file is reached and function
fprintf() returns EOF if a writing error occurs.
A first example of using these two functions (program 12.1.3) considers a file
that contains several numbers separated by space (numbers.txt). The numbers are read, their average is calculated and the result is displayed on the
screen and it is also written into another file (result.txt). If the input file is
empty, a message is displayed accordingly.
Program 12.1.3
#include <stdio.h>
#include <conio.h>
void main(void){
FILE *f,*g;
int n, sum=0,counter=0;
float average;
clrscr();
//the input file is opened
if((f=fopen("numbers.txt","r"))==NULL){
printf("Error input file");
getch();
return;
}
//the numbers are read from the file
224

12 Files
while(fscanf(f,"%d",&n)!=EOF){
printf("%d ",n);//they are displayed
sum=sum+n;//their sum is calculated
counter++;//they are counted
}
if(counter==0) printf("The file is empty");
else{
average=(float)sum/counter;
printf("\nThe average is: %.2f", average);
//the output file is created/opened
if((g=fopen("result.txt","w"))==NULL){
printf("Error output file");
getch();
return;
}
//the average is written into the result file
fprintf(g,"Average: %.2f",average);
}
getch();
fclose(f); fclose(g);
}
Program 12.1.4 is an example of both using formatted input/output functions
and opening a file to append information at the end of its content. The first
name and the last name of a student are read from the keyboard and then they
are appended to the content of a text file (students.txt).
Program 12.1.4
#include <stdio.h>
#include <conio.h>
void main(void){
FILE *f;
char first_name[20], last_name[20];
clrscr();
//opens the file for appending
if((f=fopen("students.txt","a"))==NULL){
printf("Error output file");
getch();
return;
225

Computer Programming The C Language


}
//keyboard reading
printf("The first name: ");
scanf("%s", first_name);
printf("The last name: ");
scanf("%s", last_name);
//file writing
fprintf(f,"%s %s\n",first_name, last_name);
printf("Data was written into the file");
getch();
fclose(f);
}
Program 12.1.5 reads the first name and the last name of several students from
the file students.txt. The user is asked to enter a mark for each student.
The data of a certain student is stored in the program using a variable of type
structure. All this data is then written in a formatted way into the file
marks.txt: the first name on 20 characters, the last name on 20 characters
also, the mark on 5 characters (two of them allocated for the decimal part);
there is also one space between each two fields, therefore each line has 47
characters. Because through the formatted writing a certain number of characters were allocated to each field, the file looks like a table of a database (the
data seems to be written on columns):
Dennis

RITCHIE 10.00

Brian

KERNIGHAN

9.90

Clint

HICKS

9.75

Herbert

SCHILDT

9.85

Program 12.1.5
#include <stdio.h>
#include <conio.h>
struct student{
char fname[21];
char lname[21];
float mark;
};
226

12 Files
void main(void){
FILE *in, *out;
struct student s;
int flag=0;
clrscr();
if((in=fopen("students.txt","r"))==NULL){
printf("Error input file");
getch();
return;
}
if((out=fopen("marks.txt","w"))==NULL){
printf("Error output file");
getch();
return;
}
//the names are read from file in
//the marks are read from the keyboard
//everything is written into file out
while(fscanf(in,"%s%s",s.fname,s.lname)!=EOF){
printf("\n%s %s",s.fname,s.lname);
printf("\nThe mark: "); scanf("%f",&s.mark);
fprintf(out,"%20s %20s %5.2f\n", s.fname,
s.lname, s.mark);
//the flag shows that at least one row was read
flag=1;
}
if(flag==0) printf("The file is empty");
getch();
fclose(in); fclose(out);
}

12.1.4 Repositioning the file pointer


When a file is opened for reading or for writing the file pointer is positioned at
the beginning of that file. If the file is opened for appending, the file pointer is
placed at the end of the file. The file pointer can also be located wherever within the file during an action that traverses it.

227

Computer Programming The C Language


If random access is needed for reading or writing the content of a file, then the
file pointer must be repositioned. This action is performed by function
fseek() that has the prototype:
int fseek(FILE *f, long offset, int whence);
where:
f is a file pointer returned by function fopen();
offset is the difference (in bytes) between the location specified by the
parameter whence and the new position of the file pointer; if offset is
positive, then the file pointer is moved to the right towards whence and if
it is negative, then the file pointer is moved to the left;
whence specifies the starting point for the movement and can have one of
the following three values:
o 0 (or constant SEEK_SET) the movement is made towards the
beginning of the file;
o 1 (or constant SEEK_CUR) the movement is made towards the
current position of the file pointer;
o 2 (or constant SEEK_END) the movement is made towards the
end of the file.
The function returns 0 if the file pointer is successfully moved. A non-zero
value is returned if an error occurs.
Several calls of function fseek() are hereby presented. It is noticed that both
the values 0, 1, 2 or the associated constants SEEK_SET, SEEK_CUR,
SEEK_END can be used for argument whence.
fseek(f,7,SEEK_SET); moves the file pointer with 7 characters to the
right towards the beginning of the file.
fseek(f,0,SEEK_END); moves the file pointer at the end of the file.
fseek(f,-10,SEEK_CUR); moves the file pointer with 10 characters to
the left of its current position.
fseek(f,7,1); moves the file pointer with 7 characters to the right of its
current position.
In order to illustrate through a complete program how fseek() function can
be used, several data from a file is changed. The modifying is performed once
228

12 Files
the value that must be changed is read, therefore the file pointer should be
moved back in order to overwrite that information.
File students.txt is considered. The features of a student (id,
first_name, last_name, mark) are written in a formatted manner: the id
on 5 characters, empty space, the first name on 20 characters, empty space, the
last name on 20 characters, empty space and the mark on 5 characters (two of
them allocated to the decimal part). Program 12.1.6 changes the mark of a
student. Field id is used to uniquely identify a student. The input file looks like
this:
LM214

Dennis

RITCHIE 10.00

LM209

Brian

KERNIGHAN

9.90

LM205

Clint

HICKS

9.75

LM237

Herbert

SCHILDT

9.85

The id of the searched student is read within main() and then function modify() is called. The file is opened with the mode r+, which allows both reading and writing and doesnt remove the content of the file when this is opened.
Data of each student is read (within a while instruction) and is stored into a
variable of type structure. The id of the student from the file (s.id) is compared to the id of the searched student (specified through the argument
searched received by modify() function). If these two strings are identical, then the mark of this student must be changed. The new mark is read from
the keyboard and the file pointer is repositioned. It must be moved back with 5
characters towards its current position; this is performed through the instruction
fseek(f,-5,SEEK_CUR);. Then the new mark is written (also in a formatter manner) over the old one. If the file is empty or the student is not found,
according messages are displayed.
Program 12.1.6
#include <stdio.h>
#include <conio.h>
#include <string.h>
struct student{
char id[6];
char first_name[21];
char last_name[21];
float mark;
229

Computer Programming The C Language


}s;
void modify(char *searched){
/*the function receives as argument the id of the
searched student*/
FILE *f;
float new_mark;
int flag=0, found=0;
//the file is opened for reading and writing
if((f=fopen("students.txt","r+"))==NULL){
printf("Error the file cannot be opened");
getch();
return;
}
//the file is read line by line
while(fscanf(f,"%s%s%s%f", s.id, s.first_name,
s.last_name, &s.mark)!=EOF){
if(strcmp(s.id,searched)==0){
//if this is the searched student
printf("\n%s %s %s %.2f", s.id, s.first_name,
s.last_name, s.mark);
printf("\nThe new mark: ");
scanf("%f",&new_mark);
//the file pointer is moved back
fseek(f,-5,SEEK_CUR);
//the mark is overwritten
fprintf(f,"%5.2f", new_mark);
found=1; //the student was found
}
flag=1; /*the flag shows that the file contains
at least one student */
}
if(flag==0) printf("The file is empty");
else
if(found==0)
printf("The student was not found");
getch();
fclose(f);
}
230

12 Files

void main(void){
char id[6];
clrscr();
printf("The id of the searched student: ");
scanf("%s", id);
modify(id);
}

12.1.5 File renaming and removing


Two functions that can be used in a C program in order to rename or to remove
a file are hereby presented. These functions act on a file as a whole, not only on
the information it contains and they are closely related to the operating system
[CH96]. It is better to let these operations be performed by the operating system; the accidental renaming or removing of certain files during the execution
of the programs can create serious problems. However, sometimes it is necessary to create temporary files that should be removed from the disk when they
become useless.
File renaming
Function rename(), which has the following prototype, should be used when
the name of a file must be changed.
int rename(const char *old, const char *new);
Variables old and new can contain a simple file name (in this case the file
belongs to the current folder and remains there) or the entire path of the file. In
the second case, the folders of the path can be different, therefore function
rename() can also be used to move a file from a folder to another one.
The function returns 0 if the renaming succeeds and -1 otherwise. The errors
can emerge if: the file with the old name doesnt exist, a file with the new
name already exists or the user has not enough rights to change the name or to
move the file (rights to write on the new folder).
File removing
A file can be deleted from the disk through function remove(). This action is
permanent, therefore the function should be carefully used. Its prototype is:
int remove(const char *file_name);
231

Computer Programming The C Language


The function returns 0 if the file was deleted and -1 if an error is encountered.
The deleting can fail if: the file doesnt exist or the user doesnt have the rights
to delete.
Program 12.1.7 uses the functions for deleting and renaming a file. A text file
with features of students (id, first_name, last_name, mark) is considered. The requirement is to delete a student (with the id read from the keyboard) from the file. Because a text file is not a table of a database, it is impossible to delete a record from that file; in fact it is impossible to delete anything
from a text file through a C program. A trick is used in order to solve this problem: all the records of the initial file (students.txt), excepting the one that
must be deleted, are copied into a temporary file (temp.txt). At the end, the
initial file is removed and the temporary file receives the name of the initial file.
Program 12.1.7
#include <stdio.h>
#include <conio.h>
#include <string.h>
struct student{
char id[6];
char first_name[21];
char last_name[21];
float mark;
}s;
void delete(char *searched){
/*the function receives as argument the id of the
student that must be deleted*/
FILE *f,*g;
int flag=0, found=0;
if((f=fopen("students.txt","r"))==NULL){
printf("Error the file cannot be opened");
getch();
return;
}
if((g=fopen("temp.txt","w"))==NULL){
printf("Error the file cannot be created");
getch();
return;
}
232

12 Files
//the features of each student are read
while(fscanf(f,"%s%s%s%f", s.id, s.first_name,
s.last_name, &s.mark)!=EOF){
if(strcmp(s.id,searched)==0){
printf("\n%s %s %s %.2f",s.id, s.first_name,
s.last_name, s.mark);
found=1;
}
else
/*if this is not the searched student, its
features are written into the temporary file*/
fprintf(g,"%5s %20s %20s %5.2f\n", s.id,
s.first_name, s.last_name, s.mark);
flag=1;
}
if(flag==0) printf("The file is empty");
else
if(found==0) printf("The student was not found");
getch();
fclose(f); fclose(g);
//the initial file is removed
remove("students.txt");
/*the temporary file is renamed with the name of
the initial file*/
rename("temp.txt", "students.txt");
}
void main(void){
char id[6];
clrscr();
printf("The id of the searched student: ");
scanf("%s", id);
delete(id);
}

12.2 A complete example


Program 12.2.1 gathers in an extensive application some of the previous examples and also adds other functionalities. Several actions performed on a table of
233

Computer Programming The C Language


a database are simulated; the table is represented by a text file. It contains formatted data about students (id, fname, lname, group, mark). This data is
handled within the program through a structure with five members (struct
student). The program provides a menu where the user can find the following options (figure 12.2.1):
1 Adds a student to the file (figure 12.2.2);
2 Lists the content of the file (figure 12.2.3);
3 Displays the students with scholarship those
with the average mark greater than a certain value
(figure 12.2.4);
4 Displays the students that belong to a certain
group (figure 12.2.5);
5 Searches a student using its id (figure 12.2.6);
Figure 12.2.1 Menu
6 Modifies the information about a student
(figure 12.2.7);
7 Deletes a student (figure 12.2.8);
0 Ends the program.
Apart from the option of ending the program (which is performed by a simple
call of function exit()), separated functions were implemented for all the
other options. These functions, together with the user interfaces associated to
each option, are hereby presented.
The file is opened in mode a when a student is
added. The user is asked to enter all information
about that student; these are written into the file
through function fprintf(). The writing is
performed in a formatted manner, so as the file
preserves a tabular form (the id on 5 characters,
Figure 12.2.2 Add
the first name on 20 characters, the last name
also on 20 characters, the group on a single char and the average mark on 5
characters, two of them for the decimal part; there is a space between each two
of this five fields). The field that is used to identify a student is the id (it is
supposed that its impossible to have more than one student with a certain id).

234

12 Files
In order to see the entire information
from the file, it is opened in mode r.
The file is traversed line by line, until
its end (EOF). Variable flag is used
to identify the case when the file is
empty. It has the initial value 0; if at
Figure 12.2.3 List
least one line is read from the file, the
flag receives the value 1. At the end
of the function this variable is checked and if it still has the value 0, then this
means that the file is empty and the user is notified through a message about
this situation.
The third option displays the students
that have the average mark greater
than or equal to a value specified by
the user (sch_mark). The file is
opened (r), it is traversed line by line
and the average mark of each student
Figure 12.2.4 Students with scholarship
(s.mark) is compared to the value
that is required to obtain scholarship. Variable flag is used here, too, in order
to point out that the file is empty. Another variable, found, is used to determine if there is at least one student with scholarship. If at the end of the function variable found still has its initial value 0, this means that no students with
the required mark were found.
If the user chooses the forth option,
he/she is asked to specify a group; all
the students that belong to that group
are displayed. The file is opened in
mode r and it is traversed line by line.
Figure 12.2.5 Students of a group
The students that have their group
(s.group) identical to the one specified by the user (group) are displayed. In order to identify the cases when the
file is empty or a certain group doesnt exist, variables flag and found are
used here, too.

235

Computer Programming The C Language


A student is searched using an id
specified by the user. It is considered that its impossible to have
more than one student with a
certain id, therefore any student
Figure 12.2.6 Search
can be identified. Function
strcmp() is used because the id is a string. Variables flag and found point
out that the file is empty or that the student was not found.
The user has the
possibility to change
the group and/or the
average mark of a
student that is identified through his id in
a process similar to
Figure 12.2.7 Modify
the one from the
searching function. This time the file is opened for reading and writing (r+). If
the student is found, his old data is displayed. The user enters (if he/she wants)
new values for the group (s.group) and/or for the average mark (s.mark).
The file pointer is moved back with 7 characters (1 for group, a space and 5 for
mark) and the new data overwrites the old information. Variables flag and
found are set in order to notify if the file is empty or if the student doesnt
exist in the file.
In order to delete a student
(together with all his information) from a file, the student
must be identified using his id
(the process is similar to the
Figure 12.2.8 Delete
one used by the searching
function). The file is opened for reading. A temporary file is created, and
opened for writing; it will store all students, except for the one that should be
deleted. In order to notify the user whether the file is empty or the student
doesnt exist, this function uses variables flag and found too. At the end of
the function the initial file is removed and the temporary file is renamed, receiving the name of the initial file.

236

12 Files
Function main() only displays the menu (in a repetitive manner) and, according to the users option, executes one of the implemented functions. The entire
program is hereby presented.
Program 12.2.1
#include
#include
#include
#include
#include

<stdio.h>
<conio.h>
<stdlib.h>
<string.h>
<ctype.h>

struct student{
char id[6];
char fname[21];
char lname[21];
int group;
float mark;
};
int menu(void){
int option;
printf("1-Add\n");
printf("2-List\n");
printf("3-Scholarship\n");
printf("4-Group\n");
printf("5-Search\n");
printf("6-Modify\n");
printf("7-Delete\n");
printf("0-Exit\n");
printf("Your option: ");
scanf("%d",&option);
return option;
}
void add(void){
FILE *f;
struct student s;
if((f=fopen("students.txt","a"))==NULL){
printf("Error - file cannot be opened");
getch();
237

Computer Programming The C Language


return;
}
printf("Id: "); scanf("%s", s.id);
printf("First name: "); scanf("%s", s.fname);
printf("Last name: "); scanf("%s", s.lname);
printf("Group: "); scanf("%d", &s.group);
printf("Average mark: "); scanf("%f", &s.mark);
fprintf(f,"%5s %20s %20s %1d %5.2f\n", s.id,
s.fname, s.lname, s.group, s.mark);
fclose(f);
}
void list(void){
FILE *f;
struct student s;
int flag=0;
if((f=fopen("students.txt","r"))==NULL){
printf("Error - file cannot be opened");
getch();
return;
}
while(fscanf(f,"%s%s%s%d%f", s.id, s.fname,
s.lname, &s.group, &s.mark)!=EOF){
printf("%s %s %s %d %.2f\n", s.id, s.fname,
s.lname, s.group, s.mark);
flag=1;
}
if(flag==0) printf("Empty file");
fclose(f);
getch();
}
void scholarship(void){
FILE *f;
struct student s;
int flag=0, found=0;
float sch_mark;
if((f=fopen("students.txt","r"))==NULL){
printf("Error - file cannot by opened");
getch();
238

12 Files
return;
}
printf("Mark for scholarship: ");
scanf("%f", &sch_mark);
while(fscanf(f,"%s%s%s%d%f", s.id, s.fname,
s.lname, &s.group, &s.mark)!=EOF){
if(s.mark>=sch_mark){
printf("%s %s %s %d %.2f\n", s.id, s.fname,
s.lname, s.group, s.mark);
found=1;
}
flag=1;
}
if(flag==0) printf("Empty file");
else if(found==0)
printf("No students with scholarship");
fclose(f);
getch();
}
void gr(void){
FILE *f;
struct student s;
int flag=0, found=0;
int group;
if((f=fopen("students.txt","r"))==NULL){
printf("Error - file cannot be opened");
getch();
return;
}
printf("Group: ");
scanf("%d", &group);
while(fscanf(f,"%s%s%s%d%f", s.id, s.fname,
s.lname, &s.group, &s.mark)!=EOF){
if(s.group==group){
printf("%s %s %s %d %.2f\n", s.id, s.fname,
s.lname, s.group, s.mark);
found=1;
}
flag=1;
239

Computer Programming The C Language


}
if(flag==0) printf("Empty file");
else if(found==0)
printf("The group doen's exist");
fclose(f);
getch();
}
void search(void){
FILE *f;
struct student s;
int flag=0, found=0;
char searched[6];
if((f=fopen("students.txt","r"))==NULL){
printf("Eroare - deschidere fisier");
getch();
return;
}
printf("Id of the searched student: ");
scanf("%s", searched);
while(fscanf(f,"%s%s%s%d%f", s.id, s.fname,
s.lname, &s.group, &s.mark)!=EOF){
if(strcmp(s.id, searched)==0){
printf("%s %s %s %d %.2f", s.id, s.fname,
s.lname, s.group, s.mark);
found=1;
}
flag=1;
}
if(flag==0) printf("Empty file");
else if(found==0)
printf("The student doesn't exist");
fclose(f);
getch();
}
void modify(void){
FILE *f;
struct student s;
int flag=0, found=0;
240

12 Files
char searched[6];
char answer;
if((f=fopen("students.txt","r+"))==NULL){
printf("Error - file cannot be opened");
getch();
return;
}
printf("Id of the searched student: ");
scanf("%s", searched);
while(fscanf(f,"%s%s%s%d%f", s.id, s.fname,
s.lname, &s.group, &s.mark)!=EOF){
if(strcmp(s.id, searched)==0){
printf("%s %s %s %d %.2f\n", s.id, s.fname,
s.lname, s.group, s.mark);
found=1;
printf("Do you modify the group (Y/N)?");
answer=getch();
if(toupper(answer)=='Y'){
printf("\nNew group: ");
scanf("%d",&s.group);
}
printf("Do you modify the average mark (Y/N)?");
answer=getch();
if(toupper(answer)=='Y'){
printf("\nNew average mark: ");
scanf("%f",&s.mark);
}
fseek(f,-7,SEEK_CUR);
fprintf(f,"%1d %5.2f",s.group,s.mark);
}
flag=1;
}
if(flag==0) printf("Empty file");
else if(found==0)
printf("The student doesn't exist");
fclose(f);
getch();
}
void del(void){
241

Computer Programming The C Language


FILE *f, *g;
struct student s;
int flag=0, found=0;
char searched[6];
if((f=fopen("students.txt","r"))==NULL){
printf("Error - file cannot be opened");
getch();
return;
}
if((g=fopen("temp.txt","w"))==NULL){
printf("Error - file cannot be opened");
getch();
return;
}
printf("Id of the searched student: ");
scanf("%s", searched);
while(fscanf(f,"%s%s%s%d%f", s.id, s.fname,
s.lname, &s.group, &s.mark)!=EOF){
if(strcmp(s.id, searched)==0){
printf("This record will be deleted:\n");
printf("%s %s %s %d %.2f", s.id, s.fname,
s.lname, s.group, s.mark);
found=1;
}
else
fprintf(g,"%s %s %s %d %.2f\n", s.id,
s.fname, s.lname, s.group, s.mark);
flag=1;
}
if(flag==0) printf("Empty file");
else if(found==0)
printf("The student doesn't exist");
remove("students.txt");
rename("temp.txt","students.txt");
fclose(f); fclose(g);
getch();
}
void main(void){
int o;
242

12 Files
while(1){
clrscr();
o=menu();
switch(o){
case 1: add(); break;
case 2: list(); break;
case 3: scholarship(); break;
case 4: gr(); break;
case 5: search(); break;
case 6: modify(); break;
case 7: del(); break;
case 0: exit(0);
default: printf("Wrong option!"); getch();
}
}
}

12.3 Questions and exercises


A. Find the error.
1. int x=7;
fprintf("%d", x);
2. int x=7;
fprintf("aFile.txt", "%d", x);
3. FILE *f;
int x=7;
f=fopen("aFile.txt","r");
fprintf(f, "%d",x);
4. FILE *f;
int x=7;
f=fopen("aFile.txt","w");
fprintf(f,"%d",x);
f=fclose();
5. FILE *f;
int x;
243

Computer Programming The C Language


f=fopen("aFile.txt","w+");
fscanf(f,"%d",&x);
6. FILE *f;
int x;
f=fopen("aFile.txt","r+");
fscanf(f,"%d",&x);
fseek(f,SEEK_CUR,-5);
fprintf(f, "%d",++x);
B. Considering the following programs, specify what will be printed on the
screen once these programs are executed.
7. #include <stdio.h>
void main(void){
FILE *f;
float a=1.234, b=5.678, x;
f=fopen("aFile.txt","w+");
fprintf(f,"%6.2f %6.2f",a,b);
fseek(f,-13,SEEK_CUR);
fscanf(f,"%f",&x);
printf("%.3f",x);
fclose(f);
}
8. #include <stdio.h>
void main(void){
FILE *f;
char word[20]="File";
f=fopen("aFile.txt","w");
fprintf(f,"Programming");
fclose(f);
f=fopen("aFile.txt","w+");
fscanf(f,"%s",word);
printf("%s",word);
fclose(f);
}
9. #include <stdio.h>
void main(void){
FILE *f;
char word[20]="File";
f=fopen("aFile.txt","a+");
244

12 Files
fprintf(f,"Programming");
fscanf(f,"%s",word);
printf("%s",word);
fclose(f);
}
C. Choose the correct answer (one only).
10. How many arguments does function fopen() have?
a) 0; b) 1; c) 2; d) 3; e) the number of arguments is undefined.
11. Which should be the value of mode argument of function fopen() if a
text file must be opened for reading?
a) "r"; b) "w"; c) "a"; d) "r+"; e) "r-".
12. Function fopen() returns:
a) a structure; b) constant EOF if the end of the file is reached; c)
the name of the file; d) the content of the file; e) a pointer of type
FILE.
13. Which function should be used to print in a formatted manner an argument into a file?
a) fscanf(); b) fprintf(); c) printf(); d) fgets();
e) all answers are wrong.
14. Which of the following letters cannot be used within mode argument of
function fopen()?
a) a; b) b; c) c; d) r; e) w.
15. Once fscanf() function reaches the end of a file, it returns:
a) EOF; b) NULL; c) SOS; d) nothing; e) all answers are
wrong.
16. Argument whence of function fseek() can have the value:
a) SEEK_SET; b) SEEK_CUR; c) SEEK_END; d) the answers
a, b and c are correct; e) all answers are wrong.
17. The argument of function fclose() is:
a) the name of the file (including the path, if necessary); b) the file
pointer returned by function fopen(); c) the content of the file;
245

Computer Programming The C Language


d) function fclose() doesnt have arguments; e) all answers are
wrong.
18. The type of a file pointer is:
a) file_pointer; b) NULL; c) FILE; d) EOF; e) file.
D. Write programs to solve the following problems.
19. Text file numbers.txt contains real numbers separated by space.
Find out how many numbers the file contains, which are the minimum
and the maximum; store these three elements into another file, result.txt.
20. Several words, separated by space, are stored into file words.txt.
Find out and display the longest word.
21. File employee.txt contains the name and the age of the employees
of a company. Calculate the average age in that company.
22. Text file phonebook.txt contains information (name, address,
phone number, etc.) about the clients of a telephone company. Display the phone number of a person whose name is read from the keyboard.
23. File accounts.txt contains information about bank accounts (account_number, owner, sum, and currency). The program allows
the deposit or the withdrawal from an account identified by its number.
If a withdrawal is requested, it must be verified if the account contains
the required sum.
24. Create a program that acts on a text file with information about the
products from a store (id, name, features, quantity, and
price). The program should allow, through a repetitive menu, the following actions:
a. add a product the user is responsible to enter unique values for
the id, which is the field that identifies a product;
b. list the products all data about a product is displayed;
c. display the total value of the products from the store;
d. search a product by its id the result is, at most, one product,
because the id is unique;
246

12 Files
e. search a product by its name all products that have the specified name are displayed (for instance, it is possible to have two
products with the name bread, but with different features: one
could be rice bread, 500g and the other corn bread, 300g);
f. display the cheapest product the user enters a name; the minimum is only searched for that category (for instance, if the user
enters bread, the cheapest bread is displayed);
g. display the products that need supply products with the quantity zero;
h. modify the price and/or the quantity of a product the product is
identified by id;
i. delete a product identified by id;
j. exit.

247

Appendix 1
The set of characters (together with their ASCII codes)
This appendix contains the usual characters, together with their ASCII codes.
There are totally 256 characters. Besides the characters listed here, there is a set
of 32 characters (from 0 to 31), associated to the control codes (for instance, 9
stands for horizontal tab and 10 for new line) and also a second part of the
domain (codes from 128 to 255), which differs from one computer to another
(, , ).

blank

&

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

<

>

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

Appendix 1 Set of characters


h

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

249

Appendix 2
The keywords of the C programming language
The following table contains the keywords of the standard C language. These
keywords cannot be used as names for variables, constants, functions or userdefined types because they are already in use.
Keyword

Description

auto

it shows that a variable has a local lifetime (this is the default)

break

it causes a jump out of the instructions block where it is placed

case

it is a branch of the switch alternative instruction; it creates a


block of instructions that is executed if a certain condition is
accomplished

char

data type (character)

const

used to declare constants

continue

it executes a jump to the next iteration, at the beginning of the


loop where it is placed

default

it is a branch of the switch alternative instruction; it specifies


what is happening if none of the case conditions is accomplished

do

repetitive instruction

double

data type (real double precision)

else

branch of the if alternative instruction, which is executed if the


result of the condition is false

Appendix 2 The keywords of the C programming language

enum

it defines a set of constants that forms an enumeration

extern

it shows that an element is defined somewhere else

float

data type (real simple precision)

for

repetitive instruction

goto

unconditional jump (it modifies the execution of a program to a


location specified by a label)

if

alternative instruction

int

data type (integer)

long

modifier related to a data type

register

it specifies that the variable will be stored in a register

return

it exits from the currently executing function

short

modifier related to a data type

signed

modifier related to a data type (with sigh)

sizeof

it returns the dimension (number of bytes) of an expression or of


a data type

static

it preserves a variable or a function even its objective is ended

struct

it gathers several variables in a single record, creating a structure

switch

alternative instruction

typedef

it creates a new data type

251

Computer Programming The C Language

union

it gathers variables in an union

unsigned

modifier related to a data type (without sign)

void

the empty data type

volatile

it shows that a variable can be changed in an unpredictable way


(e.g. by an interrupt)

while

repetitive instruction

252

Appendix 3
Answers to questions and exercises
Chapter 2 Logical diagrams
A. 1. The x value was displayed using a decisional element instead of an output
element. 2. The condition x>0 is verified by a processing element; a decisional
element should be used. 3. A decisional element has two branches, not three.
B. 4. The diagram calculates and displays the distance between two points, the
coordinates of which are read. 5. The coefficients of a third degree polynomial
function are read, the function is displayed, the coefficients of its derivative are
calculated and the derivative is displayed. 6. The logical diagram calculates and
displays the last digit of an integer number n (the last digit of an integer is the
reminder of the division of that number to 10). 7. The diagram calculates and
displays n! (factorial); at the beginning, n is validated as a positive number.
C. 8. e). 9. c) it is possible to create a repetitive structure using a decisional
element within a loop, but a repetitive element doesnt exist. 10. b). 11. d). 12.
a). 13. c).
Chapter 3 Data and data types
A. 1. Because alpha is a constant, it cannot change its value. The instruction
alpha=beta+10; could only be executed if alpha would be a variable, not
a constant. 2. In C programming language, double is a keyword and cannot be
used as a variables name. 3. The increment operator (++) can only be applied
to integers; therefore, its impossible to execute x++; because x is a float
variable. 4. Variable x wasnt declared. 5. Variable y is declared as unsigned
int, therefore it cannot have a negative value. 6. Variable x must be declared
before it is used, not after. 7. The multiplication operator (*) is missing; the
correct expression is: e=x+2*y-z;. 8. The modulo operator can only be
applied to integer numbers, therefore the expression y=x%2; cannot be executed because x is float. 9. Digits are not allowed at the beginning of the
variables names; therefore, variables 1_mark and 2_mark dont have correct names.

Computer Programming The C Language


B. 10. E=a/5+1=3/5+1=0+1=1. a/5 is 0 because a is integer and the operator / returns the quotient of the division when it is applied to integers. 11.
E=(a++)-(a%2)=(3++)-(3%2)=3-1=2. The value of a is increased by
one after a is used in the expression. 12. E=(a++)-(--b)=(3++)-(-4)=3-3=0. The value of variable a is modified after it is used in the expression; variable b is decremented before it is used (because ++ operator is a
prefix of b variable). 13. E=(-a)-(--a)=-3-(--4)=-3-3=-6. 14.
E=(a==b)=0. This is a logical expression; its value is zero because a==b is a
false statement. 15. E=(a+b)%4=(3+4)%4=7%4=3. 16. E=((-b)+a++)%2=((--4)+3++)%2=(3+3++)%2=6%2=0.
C. 17. e) since int, float, double and char are data types that exist in C
programming language. 18. b) because the name of a variable cannot be
formed by two unbound words. 19. a). 20. c) because a is an integer number,
therefore the result of the division will also be an integer. 21. e) since three
parentheses are opened and only two are closed. 22. e) because modulo operator (%) can only be applied to integer numbers. 23. the expressions are evaluated
as follows: a) true&&false=false, b) true||false=true, c)
(false||false)&&true=false&&true=false, d) false||false
=false; therefore, the correct answer is b). 24. e) because the name of a
variable cannot contain the symbol #. 25. e) since all the other choices are
names of modifiers in C programming language. 26. c). 27. d). 28. a) the
floating point variable with the value 3.1415 is transformed by a type casting to
an integer value. 29. the expressions are evaluated as follows: a) not
false=true, b) not (false||false) = not false = true, c)
false||(true&&true)=false||true=true, d) not true=false;
therefore, the correct answer is d). 30. c).
Chapter 4 A first C program
A. 1. The semicolon separator at the end of the third line is missing. 2. A curly
bracket must be opened for main() function (at the end of the first line should
be an opening curly bracket). 3. The multi line comment is not closed; */
should be used at the end of the text that is considered the comment. 4. Variable
surface is not declared.
B. 5. Expression E1 has the value 3 because an integer number is obtained by
the division of two integer numbers (even if E1 is declared as float); regarding expression E2, the first number is the subject of a type casting, therefore a
254

Appendix 3 Answers to questions and exercises


float number is divided to an integer and the result will be 3.5. 6. Variable
a is incremented after it is used and variable b before it is used, therefore
E=7+4=11. 7. This is a logical expression and its value is 1 because the sentence a>b is true.
C. 8. b). 9. c). 10. c) the answers a and b are wrong because include is a
preprocessor directive and void is the name of the empty data type. 11. b). 12.
c) the curly brackets are used in C programming language in order to group
instructions. 13. a). 14. a) in a C program, the instructions must be delimited
and the semicolon is used in order to do this. 15. d).
Chapter 5 Library functions
A. 1. The format descriptor %f from printf() function is missing; the correct instruction is printf("The result is: %f",x);. 2. The header
file for printf() function was omitted; the directive #include
<stdio.h> must be placed at the beginning of the program. 3. The addressing
operator & is missing in the function that reads the value of variable a; the
correct instruction is scanf("%d",&a);. 4. The format descriptor %5d must
be placed inside the string that is sent as argument to printf() function; the
correct instruction is printf("The result is: %5d",x);. 5. x is a
float variable, therefore the letter that must be used in the format descriptor
of the printing function is f, not d; the correct instruction is printf("The
result is: %5.2f",x);. 6. Variable x is an integer, therefore the format
descriptor used for its printing is wrong; the correct form is printf("The
result is: x=%d",x);. 7. Variable a has a negative value; this will
interrupt the execution of the program when function sqrt() is called; in
order to have a functional program, variable a must be non-negative.
B. 8. The format descriptor %.1f specifies that the number is displayed with
one decimal, therefore the result is 9.8. 9. The displayed text is Sunday \7
PM\
"Tosca" - Giacomo PUCCINI, written on a single line, with
a tab before the word Tosca. 10. The program doesnt display anything because exit(0) instruction ends it before the call of printf() function.
C. 11. c). 12. a). 13. e). 14. e). 15. d) the value read for variable x cannot be
stored in the memory because the addressing operator & is missing; therefore,
an error will be generated when the function is executed; if the value returned
255

Computer Programming The C Language


by scanf()function is not verified, then the program will stop. 16. c). 17. e)
because all the enumerated format descriptors are correct. 18. b).
Chapter 6 Instructions
A. 1. The curly brackets (that group the instructions in blocks) are missing. For
this reason, the compiler will report an error, saying that else is improperly
placed. Therefore, curly brackets must be placed on both if and else
branches. 2. The separator of the three entities of for instruction is semicolon,
not comma. 3. The condition evaluated by if must be enclosed by parentheses.
4. This is not a compilation error. If the semicolon is placed right after for,
then for instruction ends there (this means that it has an empty body). Therefore, the block of instructions that follows it is not considered the loop of for
and wont be repeated; it will be executed only once, after for is left. 5. The
logical operator AND is &&, not &. 6. The condition while(n<=100) must be
placed at the end of the block of instructions. 7. The control variable receives its
initial value in a wrong way. The assignment operator (i=0) must be used, not
that one used to verify the identity (i==0). 8. This is not a compilation error.
The program can be executed, but it wont stop, because the condition evaluated by for is always true. A break instruction should be placed inside the
loop or the entities of for should be changed. 9. The semicolon separator is
required after the condition evaluated by do while.
B. 10. The program will print the values 12 for x and 0 for y. The condition of
the first if is true, therefore the instruction on that branch is executed (the
assignment x=a+b). The else branch is ignored, so the second if is not
executed and neither the assignment on its branch (y=a*b). 11. The program
wont display anything because the condition of for is false from the beginning. 12. The perimeter of a circle whose radius is read from the keyboard is
calculated and displayed. Through the do while instruction the user is forced
to enter a positive value for the radius.
C. 13. c) it is an assignment operator. 14. b). 15. d) when i reaches the
value 5, the condition of for becomes false and the instruction ends; therefore,
after for instruction, the control variable has the value 5. 16. a). 17. e) the
first one is the simple assignment operator and the rest of them are compound
assignment operators. 18. e) from logical point of view, any nonzero value is
considered true. 19. b) else is the branch that is executed if the condition
evaluated by an if instruction is false. 20. b) the condition of the first if is
256

Appendix 3 Answers to questions and exercises


true, therefore the second if is executed; its condition is false, so the instruction of the else branch of the second if is performed (the decrement of x);
the else branch of the first if is ignored, therefore the third if is not executed. 21. a). 22. d) default marks the sequence of code that is executed if
none of the values associated to case branches of switch instruction fits the
value of the considered variable. 23. c) in the do while instruction the
condition is evaluated at the end of each iteration; this ensures that the loop is
executed at least once. 24. d). 25. a) do while has final test, for has a preknown number of iterations, continue is not a repetitive instruction, and
repeat is not a C instruction.
Chapter 7 Arrays
A. 1. The two instructions within for should be gathered using curly brackets.
2. The sequence of code prints each number on a separated line. In order to
have a correctly displayed matrix, printf("\n"); instruction must belong
to the outside for, not to the inside one; therefore the outside for needs curly
brackets; the inside for contains only printf("%7.2f", a[i][j]);
function. 3. In C, the indexes of the elements start from 0, not from 1. The
sequence of code that was considered loses the first element of the array and it
will print something more (a value without meaning for the program, which is
contained by the memory location adjacent to the end of the array). In order to
have a correct printing, the index of for should traverse the range [0,10).
B. 4. Displays how many null values the matrix contains. 5. Displays how many
null values the main diagonal of a square matrix contains. 6. Prints the elements
of a vector from right to left. 7. Displays the elements of a matrix in a vertical
traversing.
C. 8. c). 9. d). 10. e). 11. d). 12. b). 13. a). 14. c).
Chapter 8 Strings
A. 1. The variable is correctly declared, but it is not correctly initialized because
the double quotes are used (these indicate to the compiler that a string is initialized) instead of apostrophes. The compiler tries to add the string terminator
'\0', but it wont be able to store that value because the variable is defined as
a character, not as a string. 2. The character is displayed in a wrong way. The
format descriptor "%d" is used to display integer numbers, therefore the ASCII
257

Computer Programming The C Language


code of that character is printed, not the desired character. In order to print the
character, the format descriptor "%c" should be used. 3. Variable str doesnt
have enough space allocated to store the given value. There are two solutions
for this problem: either the number of characters allocated to the string is increased to fit the desired value, or this number is deleted and the compiler will
calculate the desired space. 4. The comparison of two strings cannot be made by
the operator ==; function strcmp() should be used.
B. 5. A key is repetitively read within a do while loop. The section of code is
ended when the user presses 'X' or 'x'. 6. The value "abc" is assigned to
string s1; string s2 receives the same value "abc". Because the two strings
are equal, function strcmp() returns the value 0, which means false from the
logical point of view; therefore, the else branch of if instruction is executed
and variable flag receives the value 2. 7. It is displayed "abc, 3", meaning
that the string is abc and it has the length 3 because the created string ends
when the character '\0' is encountered. 8. The value "abc" is assigned to
string s1; string s2 receives the value "123". Function strcmp() is not
zero, because the strings are not identical. Therefore, the condition of if instruction is false and function strcat() on the else branch is executed.
Thus, string s1 becomes "abc123" and string s2 remains "123".
C. 9. e). 10. c) strings a and b are concatenated; the result is returned in string
a and string b retains its initial value. 11. b) the two strings are identical,
function strcmp() returns the value 0, therefore the condition of if is true;
variable a is incremented and b remains at its value 0. 12. d). 13. e). 14. b). 15.
a). 16. d). 17. b).
Chapter 9 Pointers
A. 1. The operator * should be used in order to declare a pointer (not &). 2. The
initialization of a pointer with the address of a variable should be made using
the addressing operator & (m=&x). 3. In order to obtain the value stored at the
address indicated by a pointer, the pointer must be dereferenced (x=*m). 4.
Pointer m and variable average should have the same data type (float, in
this case). 5. Only integer numbers can be added to the value of a pointer (in
order to indicate to other memory locations); therefore the expression p+0.5
has no sense.

258

Appendix 3 Answers to questions and exercises


B. 6. It will be printed 17, the value that is stored at the address indicated by the
pointer p (the address of the variable a). 7. p+1 points to the second location of
the vector, therefore the value -12 is displayed. 8. Two strings indicated by
pointers s1 and s2 are concatenated. The displayed result is Abracadabra.
C. 9. a). 10. e). 11. c) pointers cannot be multiplied. 12. a). 13. c). 14. a)
only an integer number can be added to a pointer.
Chapter 10 User-defined functions
A. 1. Function calculate() is called with parameter, but its prototype specifies that it doesnt accept parameters. 2. Variable x, which is a local variable
of function main(), is not visible within function calculate(), therefore it
cannot be used there (it could only be used if it would be declared). 3. Function
calculate() is a void function, therefore it cannot return anything. 4.
Variables a and b are local variables of function main()and cannot be used
within other functions. 5. Variable x is passed by address when function calculate() is called, but it is not handled as a pointer by the function. 6. Function calculate() works with arguments passed by address, but when the
function is called these are sent by value. 7. The call of a function cannot be the
left side member of an assignment. 8. Function calculate() needs two
parameters, but receives only one (through the expression a+b). 9. In order to
count how many times the function was called, variable counter should be
declared static; otherwise it receives the initial value 0 each time the function is
called. 10. The passing of the parameter is omitted when the recursive function
calculate() is called by itself.
B. 11. Though function calculate() performs the action 1/2, the result is
0, because the operands are passed through integer variables; this result is
returned as a float and it is displayed with two decimals, therefore 0.00. 12.
Variable a has the initial value 1 and it is passed to function calculate()
that increments it; because this argument is passed by value, the increment is
not visible within main(), where variable a maintains its value 1, which is
displayed. 13. Variable a is passed by address; for this reason the increment
executed within function calculate() is performed right on the variable
(not on a copy of it); therefore, the value 2 is displayed. 14. Variable x is a
global variable, therefore it is available to the entire program. This variable
receives, within function calculate(), the value ++1, meaning 2; this value
259

Computer Programming The C Language


is also visible in main(). Variable y is a local variable of function main();
the increment ++a performed on its value that was passed to function calculate() is not visible in main(), therefore y maintains its initial value 1. 15.
Variables x and y behave as in the previous program. Variable z receives the
incremented value returned by function calculate(), meaning 2. 16. Variable a is passed by value, while b is passed by address; therefore, once the function that increments both received values is left, a maintains its initial value 1,
while b has the value 2. 17. The program displays the read characters in reverse
order.
C. 18. d). 19. b). 20. d). 21. a). 22. c) the call of a function cannot be the left
side member of an assignment. 23. e) the defined function accepts a single
parameter and it is called with two parameters. 24. e) the variables can be
local or global; in turn, the local variables can be automatic (the default category) or static. 25. e).
Chapter 11 User-defined types
A. 1. The semicolon separator is required after the closing curly bracket. 2.
Variable aCircle is misplaced; it should be declared between the closing
curly bracket and the semicolon separator. 3. The opening curly bracket after
the struct is missing. The name of the structure is also missing, but this is
not an error, because the instruction that defines the structure also declares a
variable of this type, which is enough. 4. Though both the structures name and
the list of variables are optional, they cannot be omitted in the same time. In
order to obtain a correct definition for the structure, it is necessary to have
either a label for the structure or one or more variables declared at the end of
the instruction that defines the structure. 5. Variable salary has no meaning
by itself. It is a member of a structure and should be accessed through variable
anEmployee: anEmployee.salary=2500;. 6. The operator -> should
be used to access a member of a structure through a pointer; therefore, the
correct instruction is: aPointer->salary=2500;. 7. The value associated
to a constant of an enumeration is an integer, therefore the constant should be
printed with the descriptor "%d", not "%s".
B. 8. The entire content of variable prod1 was copied to variable prod2,
therefore 1.50 is printed on the screen. 9. The polygon is passed by value,
therefore the changes that are made within function modify() are not visible
in main(); The square has 4 sides is displayed on the screen. 10.
260

Appendix 3 Answers to questions and exercises


This time the polygon is passed by address to function modify(), therefore
the changes are visible in main(); The heptagon has 7 sides is
displayed on the screen. 11. The value 1 is printed on the screen because the
enumeration variable f indicates to the constant true that is associated to the
value 1.
C. 12. c). 13. d). 14. a). 15. b). 16. a). 17. e). 18. a). 19. b)
Chapter 12 Files
A. 1. The first argument of function printf(), which should be the file pointer, is missing. 2. The functions that act on the content of a file (as printf()
does) receive as argument the file pointer returned by function fopen() when
the file is opened, not the name of the file. 3. The file is opened for reading
(mode r), but a writing is attempted (fprintf()). 4. Function fclose()
should receive as argument the file pointer f, not to return it. 5. The sequence
of code doesnt generate a compilation error, but the reading (fscanf()) is
useless if it is performed right after the file is opened. Even the mode w+ allows
both reading and writing, the content of the file is deleted by the opening
process, therefore fscanf() doesnt have anything to read at that moment
and it returns EOF. 6. The last two parameters of fseek() function are not
correctly placed; the first one of them is the offset (-5) and then the whence
(SEEK_CUR).
B. 7. Numbers a and b are written into the file on 6 characters, but with only 2
decimals (therefore the values from the file are 1.23 and 5.68). There is also
a space between the two values. Function fseek() moves back the file pointer with 13 characters, right where the first number was written; therefore, this
number is read by fscanf(). Though the printing on the screen is made with
3 decimals, the number read from the file has only two decimals; for this reason, 1.230 is displayed on the screen. 8. The file is opened in mode w, the
word "Programming" is written and the file is closed. Then the reading of
the written word is attempted, but the file is reopened in mode w+, which means
that its content is erased. Therefore, function fscanf() has nothing to read
and returns EOF, without changing variable word; "File" is displayed on the
screen. 9. The file is opened in mode a+, which allows both appending and
reading. Once function fprintf() adds the text "Programming", the file
pointer is positioned at the end of the file, therefore function fscanf(), that
261

Computer Programming The C Language


follows, doesnt have anything to read and variable word maintains its value
"File", which is displayed.
C. 10. c) function fopen() has two arguments: the name of the file and the
opening mode. 11. a). 12. e). 13. b). 14. c). 15. a). 16. d). 17. b). 18. c).

262

References
[BH92]

Borland C++ Help, Version 3.1, Borland International, Inc., 1992

[BK03]

Brian KERNIGHAN, Dennis RITCHIE: Limbajul C, Teora


Printing House, 2003, ISBN 973-20-0476-2, Authorized translation
from the English Language Edition entitled The C Programming
Language, 2nd Edition, by Brian W. Kernighan, Dennis M. Ritchie,
Prentice-Hall, 1988, ISBN 0-13-110370-9

[CH96]

Clint HICKS: Utilizare C. Uor i repede, Teora Printing House,


1996, ISBN 973-601-335-9

[DEX98] Dicionarul explicativ al limbii romne, Romanian Academy,


Iorgu IORDAN Institute of Linguistics, Univers Enciclopedic
Printing House, 1998, http://dexonline.ro
[DL06]

Doina LOGOFTU: Bazele programrii n C. Aplicaii, Polirom


Printing House, 2006, ISBN 973-46-0219-5

[GP00]

Greg PERRY: Iniiere n programarea calculatoarelor, Teora


Printing House, 2000, ISBN 973-20-0538-6

[HS98]

Herbert SCHILDT: C manual complet, Teora Printing House,


1998, ISBN 973-601-471-1

[NR01]

Nicolae ROBU: Arhitectura calculatoarelor, Politehnica Printing


House, 2001, ISBN 973-8247-01-2

[PT12]

Programming Tutorials C Tutorial,


http://www.cprogramming.com/tutorial/c-tutorial.html, accessed:
February 2012

[SL12]

The C Standard Library,


http://www.utas.edu.au/infosys/info/documentation/C/CStdLib.html
accessed: February 2012

S-ar putea să vă placă și