Docsity
Docsity

Prepare for your exams
Prepare for your exams

Study with the several resources on Docsity


Earn points to download
Earn points to download

Earn points by helping other students or get them with a premium plan


Guidelines and tips
Guidelines and tips

Computing in C++ Part I : An introduction to C, Exercises of C programming

This course will give an introduction to the programming language C. It runs in the autumn term and is addressed to students with no or little programming ...

Typology: Exercises

2021/2022

Uploaded on 09/12/2022

robinhood05
robinhood05 🇬🇧

4.8

(16)

229 documents

1 / 52

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
MSc in Mathematics and Finance, Imperial College London Dr Robert urnberg
Computing in C++
Part I : An introduction to C
Dr Robert urnberg
Introduction
This course will give an introduction to the programming language C. It runs in the autumn term and is
addressed to students with no or little programming experience in C. Attending this course will enable
you to write simple C/C++ programs and complete possible practical assignments of other courses that
run alongside this course. In this term, there will be no separate coursework assignments for the course
“Computing in C++”.
The course will be followed in the second term by an introduction to Object Oriented Programming in
C++. That is why from the start, we will be using a C++ compiler, even though the programs are really
written in C or at least in “C-like C++”. Concepts that are unique to C++ and do not form part of the C
programming language will be marked with a footnote like this (). This will help you adapt your code
to a C compiler, if you ever have to.
Throughout this script, new concepts and ideas will be illustrated with easy to understand example
programs. These examples can be compiled as they are and, if your pdf-viewer allows you to, you can
even copy and paste the code into your editor without having to type it in yourself.
These lecture notes are organised as follows. Chapter 1 gives a short overview over the main techniques
and features of C and is designed to enable you to start programming straight away. The remaining
chapters will then cover each topic in more detail.
Recommended books and sites
C only: - Tony Zhang and John Southmayd, Teach Yourself C in 24 Hours, 2000
- Bradley Jones and Peter G. Aitken, Teach Yourself C in 21 Days, 2003
- Brian W. Kernigham and Dennis M. Ritchie, The C Programming language, 1988
- Richard Johnsonbaugh and Martin Kalin, C for Scientists and Engineers, 1996
- Steven R. Lerman, Problem solving and computations for scientists and engineers,
an introduction using C, 1993
-publications.gbdirect.co.uk/c book (The C Book online)
C++: - Steve Oualline, Practical C++ Programming, 1995
- Herbert Schildt, Teach yourself C++, 1992
- Jesse Liberty, Teach yourself C++ in 24 hours, 1999
-www.cplusplus.org,www.cplusplus.com,www.cppreference.com
Compilers
Windows: ·Microsoft Visual C++ .NET with Integrated Development Environment (IDE)
·GNU C++ compiler (g++) as part of Cygwin or MinGW, without IDE
·Dev-C++ free compiler/IDE that is GNU compatible
Linux: ·GNU C++ compiler (g++) part of any distribution
·Intel C++ compiler (icc) free for students
Mac: ·Xcode free compiler/IDE that is GNU compatible
Windows/Linux/Mac: ·Code::Blocks free compiler/IDE that is GNU compatible
·NetBeans free compiler/IDE that is GNU compatible
A footnote to highlight parts that are not pure C.
1v/2016/11/24
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b
pf2c
pf2d
pf2e
pf2f
pf30
pf31
pf32
pf33
pf34

Partial preview of the text

Download Computing in C++ Part I : An introduction to C and more Exercises C programming in PDF only on Docsity!

MSc in Mathematics and Finance, Imperial College London Dr Robert N¨urnberg

Computing in C++

Part I : An introduction to C

Dr Robert N¨urnberg

Introduction

This course will give an introduction to the programming language C. It runs in the autumn term and is addressed to students with no or little programming experience in C. Attending this course will enable you to write simple C/C++^ programs and complete possible practical assignments of other courses that run alongside this course. In this term, there will be no separate coursework assignments for the course “Computing in C++”. The course will be followed in the second term by an introduction to Object Oriented Programming in C++. That is why from the start, we will be using a C++^ compiler, even though the programs are really written in C or at least in “C-like C++”. Concepts that are unique to C++^ and do not form part of the C programming language will be marked with a footnote like this (∗). This will help you adapt your code to a C compiler, if you ever have to. Throughout this script, new concepts and ideas will be illustrated with easy to understand example programs. These examples can be compiled as they are and, if your pdf-viewer allows you to, you can even copy and paste the code into your editor without having to type it in yourself. These lecture notes are organised as follows. Chapter 1 gives a short overview over the main techniques and features of C and is designed to enable you to start programming straight away. The remaining chapters will then cover each topic in more detail.

Recommended books and sites

  • C only: - Tony Zhang and John Southmayd, Teach Yourself C in 24 Hours, 2000
    • Bradley Jones and Peter G. Aitken, Teach Yourself C in 21 Days, 2003
    • Brian W. Kernigham and Dennis M. Ritchie, The C Programming language, 1988
    • Richard Johnsonbaugh and Martin Kalin, C for Scientists and Engineers, 1996
    • Steven R. Lerman, Problem solving and computations for scientists and engineers, an introduction using C, 1993
    • publications.gbdirect.co.uk/c book (The C Book online)
  • C++: - Steve Oualline, Practical C++^ Programming, 1995
    • Herbert Schildt, Teach yourself C++, 1992
    • Jesse Liberty, Teach yourself C++^ in 24 hours, 1999
    • www.cplusplus.org, www.cplusplus.com, www.cppreference.com

Compilers

  • Windows: · Microsoft Visual C++^ .NET with Integrated Development Environment (IDE) · GNU C++^ compiler (g++) as part of Cygwin or MinGW, without IDE · Dev-C++^ – free compiler/IDE that is GNU compatible
  • Linux: · GNU C++^ compiler (g++) – part of any distribution · Intel C++^ compiler (icc) – free for students
  • Mac: · Xcode – free compiler/IDE that is GNU compatible
  • Windows/Linux/Mac: · Code::Blocks – free compiler/IDE that is GNU compatible · NetBeans – free compiler/IDE that is GNU compatible

∗A footnote to highlight parts that are not pure C.

Contents

1 Basics

A C/C++^ program is nothing other than a text file with a very special syntax. In order to distinguish these files from other text files, they are usually given the ending .cpp (for windows) or .cc (for linux). These files are also called source files, as they are the source for the actual program. A C/C++^ compiler is then needed to translate the source files into an executable (or binary) file format, that can be executed by the operating system. This binary file is then the actual program. When working under windows in most cases you will not be aware of the executable file, as the compiler will allow you to run the code immediately after compilation. The following syntax guidelines you need to know, before you can start to write your first C++^ program. Each C/C++^ program needs to have a main() program. Inside this main() program we define what the code is supposed to do. The commands that are to be executed are grouped together inside some “{ }” brackets. Each statement in C must be terminated by a semi-colon “;”. See the first example programs in the next subsection.

1.1 “Hello World!”

There are two ways to output things on the screen. One uses the C++^ stream cout (on the left) and the other uses the C function printf() (on the right). (∗)

#include using namespace std;

int main() { cout << "Hello World!" << endl; return 0; }

#include

int main() { printf("Hello World!\n"); return 0; }

During the course, I may make use of both of these possibilities and you are free to use whatever you prefer. Note, however, that in the second term we will almost exclusively be using the C++^ stream cout.

1.1.1 Waiting for input

Under Windows, the terminal screen often disappears quickly after the last output of the program. To prevent this, you can make the program wait until you press Enter as follows.

#include using namespace std;

int main() { cout << "Press Enter to continue" << endl; cin.get(); return 0; }

#include

int main() { printf("Press Enter to continue\n"); scanf("%*c"); return 0; }

1.2 Comments

Comments are parts of the code that will be ignored by the compiler. They are used to add descriptions and explanations to the source code. One can either comment parts or all of a single line with //, or comment bigger parts of the code by using /* at the beginning and */ at the end. Here an example. (†)

#include using namespace std;

/***************************************

  • Example for using Comments in C/C++ * ***************************************/ ∗The stream cout is unique to C++. Also note that when including header files in a pure C program, the syntax is e.g. #include <stdio.h>. †Commenting code with // is not part of ANSI C. However, most C compilers accept it.

int main() { int i; // an integer int sum; /* used to add up i’s */

sum = 0; for (i = 0; i<10; i++) { // a for loop sum = sum + i; }

cout << "The sum is " << sum << endl; return 0; }

1.3 Variables and types

Variables are the very basis of every programming language. Without them you could not do computa- tions and you could not program anything meaningful. Variables allow you to store and recall numerical values, much like the memory register on modern hand- held calculators. Only in C you can have almost infinitely many of these registers, and you can also name them whatever you like. All you have to do is to declare any variable you want to use, before actually using it. In C there is a strong notion of separation of variables from different types. For instance, by default you can only assign to a variable values of the same type. So, when you introduce a variable, you have to declare its type. A variable can be declared with the following syntax.

type variable_name;

Here type specifies the variable’s type, and variable_name defines the name under which you can use the variable in your program. The two most important types in C are int and double. The former is used to store integer numbers and is used for e.g. counters. The latter stores floating point numbers and is used for scientific computations. Here is an example of how to use them.

#include #include // include math.h using namespace std;

int main() { int i,j; // a declaration of two integers ... double x,y; // ... and two doubles

i = 5; // an assignment j = 2*i + 3; // use value of i for assignment of j

x = 3.14; // an assignment of a floating point number y = sin(x) * exp(-5*x);

cout << "The value of i is " << i << ", while y = " << y << endl; return 0; }

Note that before the variables are used they are declared. Once a variable has been declared with its name and its type, it can be assigned values, and these values can be recalled or updated later on in the program.

1.4 User input

The C++^ input stream cin can be used to allow the user to type in values from the keyboard. Here is an example to illustrate this. (∗)

∗The cin stream is unique to C++.

used when the processing is sequential and when there is a well defined notion of an increment between one pass through the loop and the next. The following example shows how to use the two types of loops. It also includes an example of another control flow construction, the if-else statement.

#include using namespace std;

int main() { double rate, pounds, euro, sum; int i;

cout << "Please enter current exchange rate for GBP to EURO: "; cin >> rate;

pounds = 1.0; // any positive value while (pounds > 0.0) { // while loop cout << "Enter amount in pounds to convert (0 to quit) : "; cin >> pounds; if (pounds > 0.0) { // if - then euro = pounds * rate; cout << pounds << " GBP are " << euro << " in EURO." << endl; } else { // else cout << "Now quitting this part." << endl; } }

sum = 0.0; for (i = 0; i < 1000; i++) { // for loop sum = sum + 1.0 / (i + 1.0); } cout << "The sum 1 + 1/2 + 1/3 + ... + 1/1000 is " << sum << endl; return 0; }

More details on control flow can be found in Chapter 3.

1.6 Basic operators

In our example programs, we have already come across the assignment operator =, the logical operator < and the arithmetic operators *, /, + and -. The meaning of these operators is fairly clear. The assignment operator = evaluates the expression on the right hand side and assigns the value to the variable on the left hand side. Strictly speaking, the variable on the left and the expression on the right always have to be of the same type. For example,

int i; i = 1.234;

is not allowed. Any logical operator, like ==, <=, >=, > or !=, compares the two operands and returns either true or false. This result can then be used in order to control the program flow (see the previous section for details). Note also that results from logical operators can be combined with the logical and and or statements. In C/C++^ they are represented by && and ||, respectively. Finally, some less obvious operators we have come across already are the so called inserter operator <<, that is used to direct output to the output stream cout, and the postfix increment operator ++, as in the statement i++. The latter statement is equivalent to writing i = i + 1. More information on operators can be found in Chapter 4.

1.7 Arrays

Arrays are a special form of variables in C and they are the natural representations of vectors in C. An array is declared with the syntax

type name[SIZE];

where type is any of the basic types and SIZE is a constant integer. You cannot declare an array with a variable size. The technical term for this is that arrays are statically allocated, and not dynamically. We will see more on this later. For example, the statement

double x[100];

allocates in memory the space for 100 double numbers, and these are stored sequentially in memory. They are referred to as x[0] to x[99], and inside the “[ ]” brackets any integer expression can be used. Note that x[100] refers to the first space in memory after the array, so it is not well defined. Trying to access this number can lead to catastrophic results when running the program. Unfortunately, the compiler will not warn you about this. So extra care has to be taken when using arrays in C. The following program shows an example of how to use arrays.

#include using namespace std;

int main() { int i; double x[100], y[100]; // declaration of two arrays for (i = 0; i < 100; i++) { x[i] = 2.0*i; y[99-i] = i; } for (i = 0; i < 100; i++) cout << i << ". x = " << x[i] << ", y = " << y[i] << endl; return 0; }

1.8 Functions

Functions or subroutines are parts of the code, that perform a certain well defined task within the program. Defining functions allows you to re-use these parts of the code in other programs. Moreover, your program will be better structured and your source code will be easier to read. Functions can have a return value. An example for this is the call to the sin() function in the example on page 4. The function returns a value of type double and this is used to compute the variable y. If a function is not expected to return a value, then it needs to be declared as void. Moreover, each function takes a fixed number of arguments. The number and the type of these arguments has to be declared when defining the function. Here is a short example.

#include using namespace std;

void welcome() { cout << "Hi there." << endl; }

int input() { int in; cout << "Please enter a number: "; cin >> in; return in; }

void goodbye(int number) { cout << "You typed in: " << number << "." << endl; cout << "Thanks and goodbye!" << endl; }

int main() { int i;

#include #include using namespace std;

int main() { double x = 12.345678; cout << "Floating point number" << endl; cout << "Default: " << x << endl; cout << setprecision(10); cout << "Precision of 10: " << x << endl; cout << scientific << "Scientific notation: " << x << endl << endl; cout << setprecision(5) << fixed << "Back to fixed notation: " << x << endl;

cout << "With setw(35) and right: " << setw(35) << right << x << endl; cout << "With width(20) and left: "; cout.width(20); cout << left << x << endl << endl;

bool b = true; cout << "Boolean Number" << endl; cout << "Default: " << b << endl; cout << boolalpha << "BoolAlpha set: " << b << endl << endl;

return 0; }

1.10 File I/O

Input and output to files in C++^ is very straightforward. You can write to a file in exactly the same way that you write to the output stream cout, and similarly you can read from a file as if you read from the input stream cin. Take a look at the following example. (∗)

#include #include // include fstream for file I/O using namespace std;

int main() { ofstream fout("output.txt"); // creates an ofstream called fout if (! fout.is_open()) { // test that file is open cout << "Error opening output file." << endl; return -1; } fout << "Hello World" << endl; fout.close(); // close ofstream fout

ifstream fin("input.txt"); // creates an ifstream called fin if (! fin.is_open()) { // test that file is open cout << "Error opening input file." << endl; return -1; } int number; fin >> number; fin.close(); // close ifstream fin cout << "Read the number: " << number << endl; return 0; }

Note that we closed each file stream after its use, although C++^ will close all open file streams automati- cally at the end of the program. But it is good programming practice to close your streams yourself, also

∗File I/O in C is slightly more complicated. You need the variable type FILE *f; and can e.g. open files for writing with the command f = fopen("output.txt","w");. Then use fprintf(f,"...") instead of printf("...") and close the file with fclose(f);.

because the machine your program is running on will slow down if too many file streams are open at the same time. Moreover, when dealing with variable length input data files, it is beneficial to note that the insertion operator >> itself evaluates to true if the last reading operation has been successful. In C++^ this is the recommended way to check for correct input, rather than using e.g. the functions fin.eof() and fin.good() for the input file stream fin, which return true when the end of a file has been reached, and when the last input via >> was successful, respectively.

1.11 Namespaces

So far, we have used the command using namespace std; in each of our programs, without really knowing why. Namespaces are a feature of C++^ and roughly speaking they group together certain variables and functions under one name. We will learn more about namespaces in the second part of this course. For now, it suffices to know that the namespace std groups together all the objects needed for input and output that are provided by the system library iostream. It is possible to not make use of the namespace std. For the sake of completeness, here is what e.g. the first program in §1.4 would then look like.

#include // no ’using namespace std’! Watch out for ’std::’.

int main() { int i, number; double x; double sum = 0.0; // initialize sum with 0.

std::cout << "How many numbers do you want to add up: "; std::cin >> number; // input an integer

for (i = 0; i < number; i++) { // a for loop std::cout << "Input next number: "; std::cin >> x; // input a double sum = sum + x; } std::cout << "Final sum: " << sum << "." << std::endl; return 0; }

2 Variables

2.1 Basic types

For each variable that is used inside a program, a suitable type has to be found. This choice will depend on the meaning of the variable, e.g. whether it is an integer or a floating point number, but also on the required accuracy or range of the variable. When a variable is used by a program, it occupies some part of the main memory of the machine the program is running on. The amount of space it will occupy depends on the type of the variable. It is considered good programming practice to not “waste” the computer’s memory by using variable types that use more memory than is actually needed for the purpose of the variable. However, this really only plays a role if huge amounts of data are used. The amount of space a variable occupies is measured in bytes. One byte consists of 8 bits, and hence can store up to 2^8 = 256 different states. The following table gives an overview of the basic types, what they can store and their range of values. The list is not exhaustive. The size of any type can be assessed with the sizeof() function. Note that if for input and output you want to use the C functions printf() and scanf(), you will need different format descriptors, like %d for int and %e, %g for double. A full list can be found in Kernighan & Ritchie, p244. See also www.cplusplus.com/ref/cstdio/printf.html and www.cplusplus.com/ref/cstdio/scanf.html.

∗The type bool is only defined in C++.

(1.0 / 3.0) * 2.5 == 5.0/6.

is false, since the floating point representation of 56 obtained by dividing the two floating point numbers 5 .0 and 6.0 is not the same as the representation which is arrived at by first taking 13 and then multiplying by 2.5. This example illustrates that one should never test floating point numbers for equality, and one should never rely on equality for termination of a while or a for loop. For termination tests, a strict inequality like < should be used, while in place of an equality test between floating point numbers one should use something like

if (x - y < tol && x - y > - tol) // x and y are equal up to tol

where tol is a given tolerance, e.g. 10−^16. Another precision problem is the occurrence of so called overflows and underflows. The former are events, where the maximum range of a type is reached. This can cause unpredictable outcomes for your program. Underflows, on the other hand, are events where information that was stored in floating point numbers is lost, either because the lower end of the range of the type was reached, or because a much larger value was added, say, to a small number. Since only a finite number of digits can be stored for every number, some or all digits of the smaller number will be erased and lost in the process. The number of significant decimal digits for the discussed types are 7 digits for the type float and 16 digits for double, respectively. For long double this value is approximately 33.

2.2.2 Type conversion

It is clear by now that if C/C++^ in an assignment involving different types simply equated the values stored in memory, this would have undesired effects. Often the amount of memory needed to store the different types is not even the same. Hence a meaningful conversion has to take place, when e.g. an int value is assigned to a double variable, and vice versa. This is done via type conversion, and in most cases, the programmer need not worry about them. That is because the compiler invokes these conversions automatically, wherever the desired conversion is obvious. Here is a program with a list of examples.

#include using namespace std;

int main() { int i = 7; unsigned int j = i; // from int to unsigned int short int k = i; // from int to short double x = i; // from int to double

cout << i << " " << j << " " << k << " " << x << endl; return 0; } In some cases, the compiler is going to give a warning, when types in an assignment do not match. Then it is possible to enforce a conversion, by using a technique called casting. Here is an example, where a double is cast to an int, and similarly a char is converted to an int.

#include using namespace std;

int main() { double x = 1.999; int i = (int) x; // cast from double to int char c = ’a’;

cout << i // ’1’ << " " << x // ’1.999’ << endl; cout << c // ’a’ << " " << (int) c // ’97’ << endl; return 0; }

2.2.3 Rounding functions

As one can see from the previous example, simple type casting is usually not enough when converting floating point values to integers. To do this scientifically, one can use one of the rounding functions that are available in the C system header file math.h. The following program demonstrates their use.

#include #include // include math.h using namespace std;

int main() { double i, j; double x = 3.14, y = -3.14;

i = floor(x); j = floor(y); // largest int <= x cout << i << " " << j << endl; // ’3 -4’ i = ceil(x); j = ceil(y); // smallest int >= x cout << i << " " << j << endl; // ’4 -3’ i = round(x); j = round(y); // round to nearest int cout << i << " " << j << endl; // ’3 -3’ i = trunc(x); j = trunc(y); // nearest int i with |i| < |x| cout << i << " " << j << endl; // ’3 -3’ i = (int) (x + 0.5); j = (int) (y + 0.5); // math.h not needed for this cout << i << " " << j << endl; // ’3 -2’ return 0; }

Note that all of the functions floor(), ceil(), round() and trunc() return a double value, even though the number itself is integral. It is for this reason, that the variables i and j in the example were declared as double. If you want to use int, then — in order to avoid a compiler warning message — you would have to cast the result from the rounding function to an integer type.

2.3 Names of variables

The following names are reserved by the C language. These have predefined uses and cannot be used for any other purpose in a C program.

auto double int struct break else long switch case enum register typedef char extern return union const float short unsigned continue for signed void default goto sizeof volatile do if static while

In addition, the C++^ language reserves the following keywords.

asm export private true bool false protected try catch friend public typeid class inline reinterpret cast typename const cast mutable static cast using delete namespace template virtual dynamic cast new this wchar t explicit operator throw

Other than these names, you can choose any names of reasonable length for variables and functions. The names must begin with a letter, and then can contain letters, numbers and underscores. It is also possible to start names with an underscore, but because the compiler and many system libraries use this for their variables and functions, this should be avoided at all costs.

Variables, whose scope is a single user defined function, are also called local variables, see Chapter 5. One consequence of the above concept is, that in none of your subroutines can you directly make use of variables that were defined in the main() program. Variables that you want to use inside of subroutines have to be passed to them as parameters. See Chapter 5 for more details.

2.5.1 Global variables

The exceptions to the rule are so called global variables. These are variables, that have as scope the whole source file in which they are defined. That means that all the subroutines inside the source file — including the main() program — have access to these variables. However, the use of global variables is considered a bad programming practice and their use should be avoided if at all possible. The main reason being that programs that make use of global variables are difficult to debug and difficult to read, since it is not immediately clear where they have been changed last, for instance. For the sake of completeness, here is an example for the use of global variables.

#include using namespace std;

int max_number; // this is a global variable

void initialize() { max_number = 10; // max_number is global }

void print() { int i; for (i = 0; i < max_number; i++) // max_number is global cout << "*"; }

int main() { initialize(); print(); cout << "Global variable max_number = " << max_number << endl; return 0; }

2.6 Arrays and strings

As mentioned in §1.7, arrays are a special form of variables in C/C++. They are the natural implemen- tation of fixed length vectors in C. When an array like double x[100] is declared in C, the space for 100 double variables is reserved in the memory of the machine. As we know from §2.1, in this case this amounts to 800 bytes. The space for the array is allocated sequentially in memory, and the elements of the array can be referred to as x[0], x[1],... , x[99]. It is important to remember that the element x[100] no longer belongs to the array x. Instead, it points to the first 8 bytes in memory after the array x. This could be anything from other data of your program, your program code itself, or data from another program that is running on the machine at the time. Recall the program in §1.7 for an example on how to use arrays.

2.6.1 Initialization of arrays

As is the case with normal variables, by default arrays are not initialized when they are declared. The compiler only allocates the necessary space in memory, without checking or changing the contents of that part of the memory. However, as with variables it is possible to initialize arrays with meaningful values, if this is what the programmer wants. Check the following example for the syntax.

#include using namespace std;

void print(double a[], int length) { int i; for (i = 0; i < length; i++) cout << a[i] << " "; cout << endl; }

int main() { double a[5] = {1, 0.1, 3.5, 0.7, -0.5}; double x[10]; // not initialized double y[10] = {1, 2, 3}; // ’1 2 3 0 0 0 0 0 0 0’ double z[10] = {}; // ’0 0 0 0 0 0 0 0 0 0’ cout << "a = "; print(a, 5); cout << "x = "; print(x, 10); cout << "y = "; print(y, 10); cout << "z = "; print(z, 10); return 0; }

Note that you can specify every entry of the array when initializing it. If you give less values than the array is long, the remaining entries are initialized with 0. The arrays y and z in the above program are an example for this. Finally, the function print() in the example above demonstrates how one can pass arrays to a function. More details on that will follow in §5.3.

2.6.2 Strings in C

A special type of arrays in C are arrays of type char. They are also called strings. They work exactly the same way as all the other arrays in C. In particular, you need to be careful to not write more characters to a string, than it was declared for. This would cause your program to terminate with an error. There are many predefined functions in C that let you manipulate and work with strings. For example strcat to concatenate two strings, strcpy to copy a string, strcmp to compare two strings lexicographi- cally, strchr to find the first occurrence of a character in a string and strstr to find the first occurrence of a string in another string. For some of these functions you need to have knowledge of pointers, see Chapter 6 for details. Internally, C marks the end of a string with the \0 termination character. This is necessary, because the length of the string and the memory that is allocated for it can be different. All of the above functions rely on this termination character to work properly. When initializing a string with a sequence of characters, C will automatically append the termination character \0 to the end. Note also that the format descriptor for the printf() function for a string is %s. See the example program below.

#include #include // include string.h for C strings #include // include stdio.h for printf using namespace std;

int main() { char s[10] = "Hi there.", r[20]; // C strings char *t; // pointer to char

cout << "Second character of s is ’" // [] works as for other arrays << s[1] << "’." << endl; strcpy(r, s); cout << "r = " << r << endl; // "Hi there." strcat(r, s); cout << "r = " << r << endl; // "Hi there.Hi there." t = strstr(r, "re."); cout << "t = " << t << endl; // "re.Hi there."

printf("Value of string s = ’%s’\n",s); // "Hi there."

strcpy(s, r); // causes program termination

cout << endl; return 0; }

2.7 Constants

A constant is similar to a variable in the sense that it has a type and it represents a memory location. The difference is, of course, that it cannot be reassigned a new value after initialization. I.e. you cannot change its value after the constant was declared and initialized. In general, constants are a useful feature that can prevent program bugs and logic errors. Unintended modifications to a supposedly constant value in your program are prevented from occurring. The compiler will catch attempts to reassign new values to constants. In order to declare a constant, you only have to add the keyword const to the definition. This will turn a variable into a constant. For instance,

const double pi = 3.14159265;

will create the constant double value pi. You can now use the name pi anywhere in the scope of this constant, instead of the numerical value 3.14159265. Note that in C++^ you can use integer constants to define the length of an array. (∗) However, if you work with C compilers, this does not work. That is because in many ways, the compiler still treats constants as variables. So while a constant is really only initialized once the program is executed and that line of code is reached, the dimension of an array, on the other hand, has to be known at compile time already. An alternative way to have a constant expression in your source code that defines the length of an array, that also works in C, is to use the #define preprocessor directive. The preprocessor is a program that modifies your source file just prior to compilation. Another preprocessor directive that we have already seen is the #include directive. The #define directive is used to define macros, e.g. as follows.

#define LENGTH 100

Now, wherever the macro LENGTH appears in your source file, the preprocessor replaces it by its value. So, every “LENGTH” in your source code will be replaced by “100”. The compiler will only see the value 100 in your code, not “LENGTH”. Here is an example program to demonstrate the use of the described techniques.

#include using namespace std;

#define LENGTH 100 // define macro LENGTH

int main() { int i; const double pi = 3.14159265; double x[LENGTH]; // LENGTH used here

for (i = 0; i < LENGTH; i++) { // LENGTH used here x[i] = pi*i; } for (i = 0; i < 100; i++) cout << i << ". x = " << x[i] << endl;

return 0; }

3 Control flow

Most of the control flow statements we have already come across by now. See §1.5 for a short introduction. We will now look at all of the control flow constructs available in C/C++^ in a bit more detail. Any control flow construct enables you in some way to control how the execution of the program flows from one instruction to the next, hence their name.

∗This only works in C++. In C you need to use macros. Some C++ (^) compilers, e.g. g++, even allow you to use integer variables to define the length of an array. But this is a nonstandard addition. g++ -pedantic deactivates this.

3.1 The while loop

The while loop is the simplest loop in C/C++. The syntax is

while (continuation) { instructions; }

and the instructions inside the loop are executed until the boolean expression continuation is false. Note that the while loop will not be executed at all, if this expression is false on encountering the while loop for the first time. Here is a short example program for a while loop.

#include using namespace std;

void important_stuff() { // some important code }

int main() { char answer; cout << "Do you want to start the program? (y/n) : "; cin >> answer;

while (answer == ’Y’ || answer == ’y’) { important_stuff(); cout << "Do you want to continue? (y/n) : "; cin >> answer; } return 0; }

3.2 The for loop

The for loop can be viewed as a specialized version of the while loop. The syntax is

for (initialization; continuation; increment) { instructions; }

and similar to the while loop, the given instructions are repeated, until the continuation evaluates to false. In addition, this loop allows the programmer to initialize a variable or several variables before the first execution of the loop. Furthermore, the programmer can execute certain statements after each execution of the loop, before the next evaluation of continuation. Both initialization and continuation may include more than one statement. In this case, different statements are separated by commas. Here is an example.

#include #include using namespace std;

int main() { double sum; int i;

for (i = 0, sum = 0.0; i <= 100; cout << i << endl, i++) { sum += pow(2, - (double) i); }

cout << "The sum of 1/2^i for i = 0,...,100 is " << sum << endl;

for (int j = 10; j > 0; j--) { cout << j << endl;