Sie sind auf Seite 1von 90

The C++ Programming

Language
Evaluation

The final evaluation will include: Percent in %


{Total = 100%}

Homework 10.00%

Hand-on lab, test and quiz 20.00%

Final project 20.00%

Examination (final evaluation) 50.00%


Bibliography

Recommended lectures
[1] Bjarne Stroustrup, The C++ Programming Language, Addison-Wesley
Professional, 2000 (3rd edition)
[2] Scott Meyers, Effective C++, Addison-Wesley, 2005 (3rd edition).

Lab work
[1] James T. Smith, C++ Toolkit for Engineers and Scientists, Springer; 1999
(2nd edition)
[2] Andi Klein, Alexander Godunov, Introductory Computational Physics,
Cambridge University Press, 2006.
[3] Daoqi Yang, C++ and Object-oriented Numeric Computing for Scientists
and Engineers, Springer, 2000
Outline
Basics of C++
 Structure of a program.
 Variables.
 Data Types.
 Constants. Operators.

 Basic Input/Output.

Control Structures in C++


 Conditional structure.
 Iteration structure.
 Jump statements.
 The selective structure.
 Functions.

Compound Data Types in C++


 Arrays.
 Pointers.
 Classes.
Development Environment in the
Laboratory
In terminal window, type: kate or gedit

KATE and GEDIT are two different text editor which are installed on the laboratory machine. The text
editor used for writing the source code must save the plain-text files, with no word processing commands
embedded in the text.
Examples of safe editors include Windows Notepad, the DOS Edit command, Brief, Epsilon, EMACS, and
vi. Many commercial word processors, such as WordPerfect, Word, and dozens of others, also offer a
method for saving simple text files.

The files you create with your editor are called source files, and for C++ they typically are named with the
extension .CPP, .CP, or .C. During our lectures , we'll name all the source code files with the .CPP
extension.

Exemple: test.cpp

NOTE: Most C++ compilers don't care what extension you give your source code, but if you don't
specify otherwise, many will use .CPP by default.

For working at home!


DO use a simple text editor to create your source code, or use the built-in editor that comes with your
compiler. DON'T use a word processor that saves special formatting characters. If you do use a word
processor, save the file as ASCII text. DO save your files with the .C, .CP, or .CPP extension. DO check
your documentation for specifics about your compiler and linker to ensure that you know how to compile
and link your programs.
Compiling the Source Code
In terminal window type:

c++̺ test.cpp

lunch executable program in terminal window type:

./a.out

In terminal window type:

c++ -o ̺ file_name test.cpp

see output: ./file_name

The syntax: c++ -o ̺ output_file ̺ programm.cpp


A Brief History of C++
The C++ Programming Language is basically an extension of the C Programming
Language. The C Programming language was developed from 1969-1973 at Bell
labs, at the same time the UNIX operating system was being developed there.

In 1971 Dennis Ritchie at Bell Labs extended the B language (by adding types) into
what he called NB, for "New B". After restructuring the language and rewriting the
compiler for B, Ritchie gave his new language a name: "C".

In 1983, with various versions of C floating around the computer world, ANSI
(American National Standards Institute) established a committee that eventually
published a standard for C in 1989.

In 1983 Bjarne Stroustrup at Bell Labs created C++. C++ was designed for the UNIX
system environment, it represents an enhancement of the C programming language
and enables programmers to improve the quality of code produced, thus making
reusable code easier to write.
Our first C++ programm
C++ is a programming language of many different “dialects”.
In C++, “dialects” corresponds to the different compilers that support slightly different
features.
There are several common compilers: in particular, Borland C++, Microsoft C++, and
GNU C++.

A C++ program begins with a function, a collection of commands that do "something".

The function that begins a C++ program is called main; this function is always called
when the program first executes.

From main, we can also call other functions whether they be written by us or by
others.

To access a standard function that comes with the compiler, you include a
header with the #include directive. What this does is effectively take everything
in the header and paste it into your program.
#include <iostream>

using namespace std; #include <iostream>

int main() using namespace std;

{ int main() { cout << “My first C++ program !! “<<endl; return 0; }

cout << “My first C++ program !! “<<endl;

return 0; Be sure you’re


saving, compiling
}
and lunch the
program from the
same place!!!!!
Save as: first.cpp

In terminal window type: c++ ̺ -o ̺ first ̺ first.cpp If you are saving the
file first.cpp in one
place, then trying to
See output: ./first
compile from another
My first C++ program place in terminal
widows, an error you
will obtain.
#include <iostream>
Line 1: using namespace std;
int main()
#include <iostream.h> {
cout << “My first C++ program !! “<<endl;
return 0;
This line is read "pound include i-o-stream dot h". }

The effect of this line is to essentially "copy and paste" the entire file iostream.h into your own file at this line.
So you can think of this syntax as replacing the line #include <iostream.h> with the contents of the file iostream.h.

Each time you start your compiler, the preprocessor is run.

The preprocessor reads through your source code, looking for lines that begin with the pound symbol (#), and acts on those
lines before the compiler runs.

#include is a preprocessor instruction

The angle brackets around the filename tell the preprocessor to look in all the usual places for this file. If your compiler is set up
correctly, the angle brackets will cause the preprocessor to look for the file iostream.h in the directory that holds all the H files
for your compiler.

.
Why do I need to include iostream.h?
In this case, iostream.h is a file containing code for input/output operations. You need to include iostream.h so that the compiler
knows about the word cout, which appears a couple of lines below.

Obs: The preprocessor runs before your compiler each time the compiler is invoked. The preprocessor translates any
line that begins with a pound symbol (#) into a special command, getting your code file ready for the compiler
#include <iostream>
using namespace std;
int main()
{
cout << “My first C++ program !! “<<endl;
Line 2: return 0;
}
using namespace std;

This line tells the compiler to use a group of functions that are part of the standard
library (std).

By including this line at the top of a file, you allow the program to use functions such
as cout.

The semicolon ( ; ) is part of the syntax of C++. It tells the compiler that you're at the
end of a command.

You will see later that the semicolon is used to end most commands in C++.
#include <iostream>
using namespace std;
Line 3 Line 3 int main()
{
cout << “My first C++ program !! “<<endl;
return 0;
int main() int main() { … } }
{

}

Line 3 begins the actual program with a function named main(). Every C++ program has a main() function!!!!!

In general, a function is a block of code that performs one or more actions.

Usually functions are invoked or called by other functions, but main() is special.

When your program starts, main() is called automatically.


If your main is empty, then your program will do nothing.

The "curly braces" ({ and }) signal the beginning and end of functions. A good way to think about their meaning is as BEGIN
and END.

There are essentially four parts to a function definition: the return type, the function name, the parameter list, and the
function body, in that order.

In this case:

•return type: int


•function name: main
•parameter list: ()
•function body: { ... }
#include <iostream>
using namespace std;
Line 4 int main()
{
cout << “My first C++ program !! “<<endl;
return 0;
cout << “My first C++ program!! “<<endl; }

In C++ the cout object is used to display text.

It uses the << symbols, known as "insertion operators", to indicate what to output.

You can print out any series of text strings by separating them with <<.

So, instead of saying

cout << “My first C++ program !!“<<endl;

you could say

cout << “My”<< “first C++”<< “program”<<“ !!“<<endl;

The endl simply adds a carriage return (stands for "end-line").


#include <iostream>
using namespace std;
Line 5 int main()
{
cout << “My first C++ program !! “<<endl;
return 0;
return 0; }

Upon reaching the end of main, the closing brace, our program will return the value of 0 to the operating system.

This line is necessary because the return type of main is int . We'll talk more about functions and return types later,
but for now understand that because the function's return type is int, the function must return an int (integer). To

return 0 (which is an integer, we simply write return 0;.

All ANSI-compliant programs declare main() to return an int. This value is "returned" to the operating system when your
program completes. Some programmers signal an error by returning the value 1. During the lectures we hope for all the
programs, main() will always return 0
Comments

When you are writing a program, it is always clear and self-evident what you are trying to do. Funny thing, though--a month
later, when you return to the program, it can be quite confusing and unclear. I'm not sure how that confusion creeps into your
program, but it always does.
To fight the onset of confusion, and to help others understand your code, you'll want to use comments. Comments are simply
text that is ignored by the compiler, but that may inform the reader of what you are doing at any particular point in your
program.

Types of Comments
To create a comment use either

// which tells the compiler that the rest of the line is a comment,
or
/* and then */ to block off everything between as a comment.

Using Comments
As a general rule, the overall program should have comments at the beginning, telling you what the program does. Each
function should also have comments explaining what the function does and what values it returns. Finally, any statement in
your program that is obscure or less than obvious should be commented as well.

#include <iostream.h>
using namespace std;
int main()
{
/* this is a comment
and it extends until the closing
star-slash comment mark */
cout <<“ My first C++ program !! “<<endl; // this comment ends at the end of the line
cout << "That comment ended!“<<endl;
// double slash comments can be alone on a line
/* as can slash-star comments */
return 0;
}
Variables and Constants
Starting from now all the examples which will be presented during the lectures will have only the main part or the new one!

Each student must know what to add at the program in order to run it in the laboratory work.

Example: if I give you a program which display the output from multiple output statements all on one line then

#include <iostream>
I can give you only int main()
using namespace std;
{
int main() cout << “ I hope, ";
{ cout << “you all have understood!" << endl;
cout << " I hope, "; }
cout << " you all have understood!" << endl;
return 0;
}
OR, only cout << “ I hope, “ ;
cout << “you all have understood!" << endl;
Definition:
a variable is a place to store a piece of information.
- just as you might store a friend's phone number in your own memory, you can store this information in a computer's
memory. Variables are your way of accessing your computer's memory.
Of course, your memory changes over time. Your friend moves across country and has a new phone number, and your friend's
new phone number will replace the old one in your memory. Over time, as you acquire new friends, your memory will keep
changing to store different pieces of information. Likewise, a computer's memory can change over time, if you tell it to. Since
variables are your access point to your computer's memory, it makes sense that you'd be able to change the information in a
computer's memory; otherwise, they wouldn't be called variables (they'd be called statics).

Variables are the essence of any computer program! Without variables, computers would be useless.

Although there are similarities between a person's memory and a computer's memory, there are some pretty big differences.

In C++, you need to grab a little piece of the computer's memory before you can use it.

In other words, you have to tell the computer that you're planning to store a number in a variable before you can actually do it.

This is called declaring a variable.

To declare a variable, you need to know what kind of information it will store
-will it store a number,
-a text-string,
-something else,
and how you plan to refer to the variable : the variable's name (also called identifiers).
.
C++ imposes fairly strict rules on how you can name your variables:
variable names must begin with a letter
variable names are "case-sensitive" : variable "myNumber“ variable "MYNUMBER“ variable "mYnUmBeR"
variable names can't have spaces
variable names can't have special characters (typographic symbols)
In general, variable names (or identifiers) can be composed of letters, numbers, and underscores (_).

However, C++ reserves certain keywords which have special meaning to the language, and you are not
allowed to use any of these keywords as variables names.
Examples of C++ keywords: int, for, else, etc

Very important:

The C++ language is a "case sensitive" language. That means a identifier written in capital letters is not equivalent to
another one with the same name but written in small letters.
For example:

area // valid identifier


Area2 // valid identifier
2area // invalid identifier (begins with a digit)
_ area // valid identifier
Area // valid but distinct from area

Variable Types
A variable type is a description of the kind of information a variable will store.

Programming languages vary regarding how strict they require you to be when declaring a variable's type. Some
languages, like Perl, do not require you to announce the type of a variable. Other languages require you to declare
some variables as numbers and others as text-strings, for example.

C++, a strongly-typed language, requires you to be even more specific than that.

Instead of declaring a variable as a number, you must say whether it will store integers or decimals. In C++, the
type of an integer is int and the type of a decimal is float (floating-point number).
Type Description Values
Fundamental Variable Types unsigned short int 0 to 65,535
short int Short Integer -32,768 to 32,767
unsigned long int 0 to 4,294,967,295
long int Short Integer -2,147,483,648 to
2,147,483,647
int (16 bit) Integer -32,768 to 32,767

Declaration of variables int (32 bit) -2,147,483,648 to


2,147,483,647

You define or create a variable by: unsigned int (16 bit) 0 to 65,535
stating its type, unsigned int (32 bit) 0 to 4,294,967,295
followed by one or more spaces,
followed by the variable name Char Character or small 256 character values
followed by a semicolon. integer
float Floating point 1.2e-38 to 3.4e38
number. (~7 digits)
double Double precision 2.2e-308 to 1.8e308
Floating point (~15 digits)
The following statement defines a: number
bool Boolean value. It can true or false
int myNumber; take one of two
values: true or false.
char letter;
The first one declares a variable of type int with the identifier myNumber
float one, two; If you are going to declare more than one variable of the same type, you can declare all of
them in a single statement by separating their identifiers with commas. Ex: double i, j, k;
double i, j, k;

Once declared, the variables myNumber and i can be used within the rest of their scope in the program.
You can also assign values to your variables upon declaration. When we assign values to a variable using the assignment
operator (equals sign), it’s called an explicit assignment:

int myNumber = 5;

You can also assign values to variables using an implicit assignment:

int myNumber (5);

Mistakes that new programmers tend to make when declaring variables.

declaring each variable as int (or whatever type it is) in sequence


int myNumber1, int myNumber2; // wrong (compiler error)
int myNumber1, myNumber2; // correct

declare two variables of different types on the same line. Variables of different types must be declared in separate
statements

int myNumber1, double myNumber2; // wrong (compiler error)


int myNumber1; double myNumber2; // correct (but not recommended)

// correct and recommended (easier to read)


int myNumber1;
double myNumber2;

the programmer mistakenly tries to initialize both variables by using one assignment statement:

int myNumber1, myNumber2=100; // wrong (myNumber1 is uninitialized!)


int myNumber1=300, myNumber2=100; // correct
Where to declare variables

C++ compilers do not require all variables to be declared at the top of a function. The proper C++ style is to declare variables
when and where they are needed:

int main()
{
// then code

cout << "Enter a number: ";


int x; // we need x starting here.
cin >> x;

cout << "Enter another number: ";


int y; // we don't need y until now
cin >> y;

cout << "The sum is: " << x + y << endl;


return 0;
}

This has quite a few advantages. First, variables that are declared only when needed are given context by the
statements around them. If x were declared at the top of the function, we would have no idea what it was used for until
we scanned the function and found where it was used. Declaring x amongst a bunch of input/output statements helps
make it obvious that this variable is being used for input and/or output.
Second, declaring a variable only where it is needed tells us that this variable does not affect anything above it,
making our program easier to understand and requiring less scrolling. Finally, it reduces the likelihood of inadvertently
leaving a variable uninitialized, because we can declare and then immediately initialize it with the value we want it to
have.
Character variables
-type char are enough to hold 256 values. A char can be interpreted as a small number (0-255) or as a member of the ASCII set.
-ASCII stands for the American Standard Code for Information Interchange. The ASCII character set and its ISO (International
Standards Organization) equivalent are a way to encode all the letters, numerals, and punctuation marks.
-in the ASCII code, the lowercase letter "a" is assigned the value 97.
-all the lower- and uppercase letters, all the numerals, and all the punctuation marks are assigned values between 1 and 128.
-another 128 marks and symbols are reserved for use by the computer maker,

A literal character is written by enclosing the character between a pair of single quotes.
Example
char ch = ‘a’;

Nonprintable characters are represented using escape sequences.


Example:
‘ \n ‘ // new line
‘ \r ‘ // carriage return
‘ \t ‘ // horizontal tab
‘ \v ‘ // vertical tab
‘ \b ‘ // backspace
‘ \f ‘ // formfeed

Characters and Numbers

-when you put a character, for example, ‘a’, into a char variable, what is really there is just a number between 0 and 255.

-The compiler knows, however, how to translate back and forth between characters (represented by a single quotation mark and
then a letter, numeral, or punctuation mark, followed by a closing single quotation mark) and one of the ASCII values.

-The value/letter relationship is arbitrary; there is no particular reason that the lowercase "a" is assigned the value 97. As long as
everyone (your keyboard, compiler, and screen) agrees, there is no problem. It is important to realize, however, that there is a big
difference between the value 5 and the character ‘5’. The latter is actually valued at 53, much as the letter ‘a’ is valued at 97.
Boolean variables
The types we have seen so far are pretty big. There are a lot of integers in the world, and even more floating-point numbers. By
comparison, the set of characters is pretty small. Well, there is another type in C++ that is even smaller. It is called boolean, and
the only values in it are true and false.

Boolean variables work just like the other types:

bool fred; the first line is a simple variable declaration;

fred = true; the second line is an assignment,

bool testResult = false; the third line is a combination of a declaration and as assignment.

Constants
Like variables, constants are data storage locations. Unlike variables, and as the name implies, constants don't change. You
must initialize a constant when you create it, and you cannot assign a new value later.

Defined constants (#define)


You can define your own names for constants that you use very often without having to resort to memory-consuming
variables, simply by using the #define preprocessor directive. Its format is: #define identifier value
Example:
#define PI 3.14159
#define NEWLINE '\n'

Declared constants (const)


With the const prefix you can declare constants with a specific type in the same way as you would do with a variable:
const int x = 100;
const float pi = 3.14159;
Simple Input/Output
The most common way in which a program communicates with the outside world is through simple, character-oriented
Input/Output (IO) operations.
C++ provides two useful operators for this purpose: >> for input and << for output.

int main()
{
int a;

cout << “Type a number for the a value !! “<<endl; This line outputs Type a number for the a value !! to ask the a value

cin >> a; This line reads the input value typed by the user and copies it to a

cout << “The value you have type is”<<endl;


The input operator >> takes an input stream as its left operand
cout<<a<<endl; (cin is the standard C++ input stream which corresponds to data
entered via the keyboard) and a variable (to which the input data
return 0; is copied) as its right operand.
}

… This line reads two input values typed by the user and copies them to
int a,b; a and b, respectively. The two values should be separated by white
… space (i.e., one or more space or tab characters).
cin>>a>>b; This statement is equivalent to: (cin >>a) >>b;
cout << “The value you have type is” << a << b << endl;

Operators
Operators are special symbols that are used to represent simple computations like addition and multiplication. Most of the operators
in C++ do exactly what you would expect them to do, because they are common mathematical symbols.
In C++ there are several different categories of operators. Two of these categories are
•Assignment operators.
•Mathematical operators.

Assignment Operator

The assignment operator (=) causes the operand on the left side of the assignment operator to have its value changed to the
value on the right side of the assignment operator.
The expression x = a + b; assigns the value that is the result of adding a and b to the operand x.

An operand that legally can be on the left side of an assignment operator is called an l-value. That which can be on the right
side is called (you guessed it) an r-value.

Constants are r-values. They cannot be l-values. Thus, you can write
x = 35; // ok but you can't legally write 35 = x; // error, not an lvalue!

Mathematical Operators
Except for remainder (%) all other arithmetic operators can accept a mix of integer
Operator Name Example and real operands. Generally, if both operands are integers then the result will be an
+ Addition 12 + 4.9 // gives 16.9 integer. However, if one or both of the operands are reals then the result will be a real
(or double to be exact).
- Subtraction 3.98 - 4 // gives -0.02
When both operands of the division operator (/) are integers then the division is
* Multiplication 2 * 3.4// gives 6.8
performed as an integer division and not the normal division we are used to. Integer
/ Division 9 / 2.0 // gives 4.5 division always results in an integer outcome (i.e., the result is always rounded down).
Modulus For example: 9 / 2 // gives 4, not 4.5!
% 13 % 3 // gives 1
(Remainder) -9 / 2 // gives -5, not -4!
The remainder operator (%) expects integers for both of its operands. It returns the
remainder of integer-dividing the operands. For example 13%3 is calculated by
integer dividing 13 by 3 to give an outcome of 4 and a remainder of 1; the result is
therefore 1.
Combining the Assignment and Mathematical Operators
It is not uncommon to want to add a value to a variable, and then to assign the result back into the variable.
If you have a variable myNumber and you want to increase the value by two, you can write
This method, however, is terribly convoluted and
int myNumber = 5;
wasteful. In C++, you can put the same variable on
int temp;
both sides of the assignment operator, and thus the
temp = myNumber + 2; // add 5 + 2 and put it in temp
preceding becomes myNumber = myNumber+2;
myNumber = temp; // put it back in myNumber
which is much better
In algebra this expression would be meaningless, but in C++ it is read as "add two to the value in myNumber and assign the
result to myNumber."
Even simpler to write, but perhaps a bit harder to read is myNumber += 2;

The self-assigned addition operator (+=) adds the r-value to the l-value and then reassigns the result into the l-value. This
operator is pronounced "plus-equals." The statement would be read "myNumber plus-equals two."

If myNumber had the value 4 to start, it would have 6 after this statement.

There are self-assigned subtraction (-=), division (/=), multiplication (*=), and modulus (%=) operators as well.

Operator Example Equivalent To


= k = 30
+= k += 30 k = k + 30
-= k -= 30 k = k – 30
*= k *= 30 k = k * 30

/= k /= 30 k = k /30

%= k %= 30 k = k % 30
Increment and Decrement Operators
The auto increment (++) and auto decrement (--) operators provide a convenient way of, respectively, adding and subtracting 1
from a numeric variable.
Both operators can be used in prefix and int k = 5; Operator Name Example
postfix form. The difference is significant. ++ Auto Increment (prefix) ++k + 10 // gives 16
When used in prefix form, the operator is first applied and the
++ Auto Increment (postfix) k++ + 10 // gives 15
outcome is then used in the expression.
When used in the postfix form, the expression is evaluated -- Auto Decrement (prefix) --k + 10 // gives 14
first and then the operator applied
-- Auto Decrement (postfix) k-- + 10 // gives 15
Both operators may be applied to integer as well as real variables.

Relational Operators
Operator Name Example

C++ provides six relational operators for comparing numeric == Equality 3 == 3 // gives 1
quantities != Inequality 3 != 3 // gives 0
Relational operators evaluate to 1 (representing the true outcome) < Less Than 3 < 3.3 // gives 1
or 0 (representing the false outcome).
<= Less Than or Equal 3 <= 3 // gives 1
Note that the <= and >= operators are only supported in the form
shown. In particular, =< and => are both invalid and do not mean > Greater Than 3 > 3.3 // gives 0
anything.
>= Greater Than or Equal 6.3 >= 3 // gives 1
The operands of a relational operator must evaluate to a number.
Characters are valid operands since they are represented by numeric values. For example (assuming ASCII coding):
'A' < 'F' // gives 1 (is like 65 < 70)
The relational operators should not be used for comparing strings, because this will result in the string addresses being
compared, not the string contents. For example, the expression
"HELLO" < "BYE"
causes the address of "HELLO" to be compared to the address of "BYE". As these addresses are determined by the compiler (in
a machine-dependent manner), the outcome may be 0 or may be 1, and is therefore undefined.
Logical Operators
C++ provides three logical operators for combining logical expression. The logical operators evaluate to 1 or 0.

Operator Name Example


! Logical Negation !(5 == 5) // gives 0
&& Logical And 5 < 6 && 6 < 6 // gives 1
|| Logical Or 5 < 6 || 6 < 5 // gives 1

Logical negation is a unary operator, which negates the logical value of its single operand. If its operand is nonzero it produce 0,
and if it is 0 it produces 1.

Logical and produces 0 if one or both of its operands evaluate to 0. Otherwise, it produces 1.

Logical or produces 0 if both of its operands evaluate to 0. Otherwise, it produces 1.

Note that here we talk of zero and nonzero operands (not zero and 1). In general, any nonzero value can be used to represent the
logical true, whereas only zero represents the logical false.
!20 // gives 0
The following are, therefore, all valid logical expressions: 10 && 5 // gives 1
10 || 5.5 // gives 1

Precedence

In an expression which involves several operators, the order in which the operators are evaluated depends on the priority
given to them.
The priority given to the operators is called precedence.
The operators such as *, /, % have higher precedence than the operators +,-.
The operators *, / and % have same precedence and operators + and - have same precedence.
For example, in the statement
a+b*c;
b*c is evaluated before and the result of b*c is added to a. It is same as (a+(b*c));
operator name
! boolean not

operators have the same


* multiplication precedence as other operators
/ division
in their group, and higher
% mod
precedence than operators in
+ addition lower groups
- subtraction

< is less than

is less than or
<=
equal to

> is greater than


is greater than or
>=
equal to

== is equal to

!= is not equal to

&& boolean and

|| boolean or

= assignment

*= multiply and assign

/= divide and assign


%= mod and assign
+= add and assign

-= subtract and assign


Input/Output with files

File I/O is reading from and writing to files.

C++ has three basic classes to handle files: To use them, include the header file fstream.
• ofstream: Stream class to write on files
Ifstream handles file input (reading from files),
• ifstream: Stream class to read from files
ofstream handles file output (writing to files).
• fstream: Stream class to both read and write from/to files.

Example: #include <iostream>


#include <fstream>
using namespace std; This code creates a file called example.txt and inserts a sentence into
int main () it in the same way we are used to do with cout, but using the file stream
{ myfile instead.
ofstream myfile;

myfile.open ("example.txt");

myfile << "Writing this to a file.\n";


myfile.close();
return 0;
}

Open a file

The first operation generally performed on an object of one of these classes is to associate it to a real file.

This procedure is known as to open a file.

An open file is represented within a program by a stream object (an instantiation of one of these classes, in the previous
example this was myfile) and any input or output operation performed on this stream object will be applied to the physical file
associated to it.
In order to open a file with a stream object we use its member function open():

open (filename, mode);

Where filename is a null-terminated character sequence of type const char * (the same type that string literals have)
representing the name of the file to be opened, and mode is an optional parameter with a combination of the following flags:

ios::in Open for input operations. All these flags can be


ios::out Open for output operations. combined using the ( | ).
ios::binary Open in binary mode.
Set the initial position at the end of the file.
ios::ate
If this flag is not set to any value, the initial position is the beginning of the file.
All output operations are performed at the end of the file, appending the content
ios::app to the current content of the file. This flag can only be used in streams open for
output-only operations.
If the file opened for output operations already existed before, its previous
ios::trunc
content is deleted and replaced by the new one.

Example:
ofstream myfile;
myfile.open ("example.bin", ios::out | ios::app | ios::binary);

Each one of the open() member functions of the classes ofstream, ifstream and fstream has a default mode that is used
if the file is opened without a second argument:
class default mode parameter For ifstream and ofstream classes, ios::in and ios::out are automatically and
respectively assumed, even if a mode that does not include them is passed as
ofstream ios::out second argument to the open() member function
ifstream ios::in File streams opened in binary mode perform input and output operations
independently of any format considerations. Non-binary files are known as text
fstream ios::in | ios::out
files, and some translations may occur due to formatting of some special
characters (like newline and carriage return characters).
Since the first task that is performed on a file stream object is generally to open a file, these three classes include a constructor
that automatically calls the open() member function and has the exact same parameters as this member. Therefore, we could
also have declared the previous myfile object and conducted the same opening operation in our previous example by writing:

ofstream myfile ("example.bin", ios::out | ios::app | ios::binary);

To check if a file stream was successful opening a file, you can do it by calling to member is_open() with no arguments. This
member function returns a bool value of true in the case that indeed the stream object is associated with an open file, or false
otherwise:
if (myfile.is_open())
{
/* ok, proceed with output */
}

Closing a file

When we are finished with our input and output operations on a file we shall close it so that its resources become available again.

In order to do that we have to call the stream's member function close().

This member function takes no parameters, and what it does is to flush the associated buffers and close the file:

myfile.close();

Once this member function is called, the stream object can be used to open another file, and the file is available again to be
opened by other processes.

In case that an object is destructed while still associated with an open file, the destructor automatically calls the member function
close().
Text files

Text file streams are those where we do not include the ios::binary flag in their opening mode.
These files are designed to store text and thus all values that we input or output from/to them can suffer some formatting
transformations, which do not necessarily correspond to their literal binary value.
Data output operations on text Data input from a file can also
files are performed in the same be performed in the same way
way we operated with cout: that we did with cin:
#include <iostream> #include <iostream>
#include <fstream> This last example reads a text file and prints
#include <fstream>
using namespace std; #include <string> out its content on the screen. Notice how we
int main () using namespace std; have used a new member function, called eof()
{ int main () that returns true in the case that the end of the
ofstream myfile ("example.txt"); { file has been reached. We have created a
if (myfile.is_open()) string line;
{ while loop that finishes when indeed
ifstream myfile ("example.txt");
myfile << "This is a line.\n"; if (myfile.is_open()) myfile.eof() becomes true (i.e., the end of the
myfile << "This is another line.\n"; { file has been reached).
myfile.close(); while (! myfile.eof() )
} {
else getline (myfile,line);
cout << "Unable to open file"; cout << line << endl;
return 0; }
} myfile.close();
}
else
cout << "Unable to open file";
return 0;
}
Statements in C++
Like many other procedural languages, C++ provides different forms of statements for different purposes. Declaration statements are
used for defining variables. Assignment-like statements are used for simple, algebraic computations. Branching statements are used for
specifying alternate paths of execution, depending on the outcome of a logical condition. Loop statements are used for specifying
computations which need to be repeated until a certain logical condition is satisfied. Flow control statements are used to divert the
execution path to another part of the program. We will discuss these in turn.
A simple statement is a computation terminated by a semicolon. Variable definitions and semicolon-terminated expressions are examples:
int i; // declaration statement
++i; // this has a side-effect
double d = 10.5; // declaration statement
d + 5; // useless statement!
The last example represents a useless statement, because it has no side-effect (d is added to 5 and the result is just discarded).
The simplest statement is the null statement which consists of just a semicolon:
; // null statement
Although the null statement has no side-effect, as we will see during the lectures, it has some genuine uses.
Multiple statements can be combined into a compound statement by enclosing them within braces.
Example:
{ int min, i = 10, j = 20;
min = (i < j ? i : j);
cout << min << '\n';
}
Compound statements are useful in two ways:
•they allow us to put multiple statements in places where otherwise only single statements are allowed,
•they allow us to introduce a new scope in the program. A scope is a part of the program text within which a variable remains
defined. For example, the scope of min, i, and j in the above example is from where they are defined till the closing brace of the
compound statement. Outside the compound statement, these variables are not defined.
Because a compound statement may contain variable definitions and defines a scope for them, it is also called a block. The scope of a C++
variable is limited to the block immediately enclosing it. Blocks and scope rules will be described in more detail when we discuss functions.
Control Structures
A program is usually not limited to a linear sequence of instructions. During its process it may bifurcate, repeat code or take decisions. For
that purpose, C++ provides control structures that serve to specify what has to be done by our program, when and under which
circumstances.

Conditional structure: if and else


Normally, your program flows along line by line in the order in which it appears in your source code. It is sometimes desirable to make
the execution of a statement dependent upon a condition being satisfied.
The if statement provides a way of expressing this, the general form of which is:

if (expression)
statement;

The expression in the parentheses can be any expression at all, but it usually contains one of the relational expressions.

If the expression has the value 0, it is considered false, and the statement is skipped.

If it has any nonzero value, it is considered true, and the statement is executed. if ( TRUE )
Execute the next statement
Example: if (x > 0)
cout << "x is positive" << endl;
If we want more than a single statement to be executed in case that the condition is true we can specify a block using braces { }:

The condition can contain any of the comparison operators:


if (expression) if ( TRUE ) Example: x == y // x equals y
{ { if (x == 100) x != y // x is not equal to y
statement1; Execute all {
statement2; statements cout << "x is "; x>y // x is greater than y
statement3; inside the cout << x; x<y // x is less than y
} braces }
} x >= y // x is greater than or equal to y

x <= y // x is less than or equal to y


Often you want to ask more than one relational question at a time. "Is it true that x is greater than y, and also true that y is
greater than z?" A program might need to determine that both of these conditions are true, or that some other condition is true,
in order to take an action.
Logical AND
A logical AND statement evaluates two expressions, and if both expressions
are true, the logical AND statement is true as well.
Operator Symbol Example Examples:
AND && expression1 && expression2 1) If it is true that you have 18 year old, AND it is true that you have driving
license, THEN it is true that you can drive a car.
OR || expression1 || expression2
NOT ! !expression 2) if ( (x == 5) && (y == 5) ) would evaluate TRUE if both x and y are equal to
5, and it would evaluate FALSE if either one is not equal to 5.

Note that both sides must be true for the entire expression to be true.
Logical OR
A logical OR statement evaluates two expressions. If either one is true, the expression is true.
Examples:
1) If you have a car OR you have a motor-cycle, you can go to Bucharest. You don't need both a car and a motor-cycle; you
need only one, although having both would be fine as well.
2) if ( (x == 5) || (y == 5) ) evaluates TRUE if either x or y is equal to 5, or if both are.
Logical NOT
A logical NOT statement evaluates true if the expression being tested is false. If the expression being tested is false, the value
of the test is TRUE!
Example:
if ( !(x == 5) ) is true only if x is not equal to 5. This is exactly the same as writing if (x != 5)
Relational Precedence
Relational operators and logical operators, being C++ expressions, each return a value: 1 (TRUE) or 0 (FALSE). Like all
expressions, they have a precedence order that determines which relations are evaluated first.
if ( x > 5 && y > 5 || z > 5) - although precedence will determine which relation is evaluated first, parentheses can both change
the order and make the statement clearer: if ( (x > 5) && (y > 5 || z > 5) )
In C++, zero is false, and any other value is true. Because an expression always has a value, many C++ programmers take
advantage of this feature in their if statements.
if (x) /* if x is true (nonzero)*/ x = 0; can be read as "If x has a nonzero value, set it to 0." This is a bit of a cheat; it would be
clearer if written if (x != 0) /* if x is nonzero */ x = 0;
if (!x) /*if x is false (zero)*/ if (x == 0) /* if x is zero */
The second statement, however, is somewhat easier to understand and is more explicit.
Alternative execution: else
A variant form of the if statement allows us to specify two alternative statements:
•one which is executed if a condition is satisfied
•one which is executed if the condition is not satisfied. if ( TRUE )
This is called the if-else statement and has the general form: {
// Execute these statements if TRUE
if (expression) If the expression evaluates TRUE }
statement1; statement1 is executed; else
else otherwise {
statement2; statement2 is executed; // Execute these statements if FALSE
}
Example:
if (nX > 10)
if (x == 100)
cout << nX << "is greater than 10" << endl;
cout << "x is 100";
else
else
cout << nX << "is not greater than 10" << endl;
cout << "x is not 100";
int firstNumber, secondNumber;
cout << "Enter two numbers.\nFirst: ";
cin >> firstNumber;
cout << "\nSecond: ";
if (nX > 10) cin >> secondNumber;
{ cout << "\n\n";
// both statements will be executed if nX > 10 if (firstNumber >= secondNumber)
{
cout << "You entered " << nX << endl; if ( (firstNumber % secondNumber) == 0)
cout << nX << "is greater than 10" << endl; {
} if (firstNumber == secondNumber)
else cout << "They are the same!\n";
{ else
cout << "They are evenly divisible!\n“;
// both statements will be executed if nX <= 10 }
cout << "You entered " << nX << endl; else
cout << nX << "is not greater than 10" << endl; cout << "They are not evenly divisible!\n"; 30: }
} else
cout << "Hey! The second one is larger!\n“;
Chained conditionals

Sometimes you want to check for a number of related conditions and choose one of several actions. One way to do this is
by chaining a series of ifs and elses:
if (x > 0) {
cout << "x is positive" << endl;
if (expression1) }
{ else if (x < 0) {
if (expression2) statement1; cout << "x is negative" << endl;
else { if (expression3) statement2; }
else {
else statement3; }
cout << "x is zero" << endl;
} }
else statement4;
if (x == 0) {
cout << "x is zero" << endl;
If expression1 is true and expression2 is true, execute statement1. } else {
If expression1 is true but expression2 is not true, if (x > 0) {
then if expression3 is true execute statement2. cout << "x is positive" << endl;
If expression1 is true but expression2 and expression3 are false, execute statement3. } else {
cout << "x is negative" << endl;
Finally, if expression1 is not true, execute statement4.
}
#include <iostream.h>
}
int main()
Conditional (Ternary) Operator {
int x, y, z;
cout << "Enter two numbers.\n“;
The conditional operator (?:) is C++'s only ternary operator; that is, cout << "First: “;
it is the only operator to take three terms. cin >> x;
The conditional operator takes three expressions and returns a cout << "\nSecond: “;
value: cin >> y;
cout << "\n";
if (x > y)
(expression1) ? (expression2) : (expression3) z = x;
Else
This line is read as If expression1 is true, return the value of z = y;
expression2; otherwise, return the value of expression3 cout << "z: " << z;
cout << "\n";
z = (x > y) ? x : y;
Typically, this value would be assigned to a variable. cout << "z: " << z;
cout << "\n“;
return 0;
}
Loops

Loops are used to repeat a block of code. Being able to have your program repeatedly execute a block of code is one of the
most basic but useful tasks in programming

A loop lets you write a very simple statement to produce a significantly greater result simply by repetition.

There are three types of loops: for, while, and do..while. Each of them has their specific uses.

The for loop

for loops are the most useful type. The syntax for a for loop is

for ( variable initialization; condition; variable update )


{
statement; //Code to execute while the condition is true
}
A for loop works in the following sequence:

•variable initialization is evaluated. Typically, the variable initialization consists of


variable declarations and assignments. This statement is only evaluated once, when the
loop is first executed.
for (int i = 0; i<10; i++)
2. The condition is evaluated. If condition is false, the loop terminates immediately. If cout << "Hello! ";
condition is true, the statement is executed.
for (int i = 0; i < 10; i++)
{
3. After the statement is executed, the variable update is evaluated. Typically, this cout << "Hello!" << endl;
expression consists of incremented/decrementing the variables declared in variable cout << "the value of i is: " << i << endl;
initialization . After variable update has been evaluated, the loop returns to step 2 }

Multiple initialization and increments It is not uncommon to initialize more than one for (int i=0, j=0; i<3; i++, j++)
variable, to test a compound logical expression, and to execute more than one cout << "i: " << i << " j: " << j << endl;
statement. The initialization and the action may be replaced by multiple C++ statements,
each separated by a comma.
The while loop

A while loop causes your program to repeat a sequence of statements as long as the starting condition remains true.

The syntax for a while loop is: while ( condition )


{
statement ; //Code to execute while the condition is true
}
- its functionality is simply to repeat statement while the condition set in expression is true

The true represents a boolean expression which could be y== 0 or while ( y != 5 ) (y does not equal 5).
It can be any combination of boolean statements that are legal.
Even, (while y ==3 || t == 9) which says execute the code while y equals 3 or while t equals 9.
Notice that a while loop is the same as a for loop without the initialization and update sections.

int n;
int x = 0; // Don't forget to declare variables
cout << "Enter the starting number > ";
while ( x < 10 ) // While x is less than 10
cin >> n;
{
while (n>0)
cout<< x <<endl;
{
x++; // Update x so the condition can be met eventually
cout << n << ", ";
}
--n;
}
cout << "FIRE!\n";
When creating a while-loop, we must always consider that it
1 User assigns a value to n has to end at some point, therefore we must provide within
2 The while condition is checked (n>0). At this point there are two posibilities:
* condition is true: statement is executed (to step 3)
the block some method to force the condition to become
* condition is false: ignore statement and continue after it (to step 5) false at some point, otherwise the loop will continue looping
3 Execute statement: forever. In this case we have included --n; that decreases
cout << n << ", "; the value of the variable that is being evaluated in the
--n; condition (n) by one - this will eventually make the condition
(prints the value of n on the screen and decreases n by 1)
4. End of block. Return automatically to step 2
(n>0) to become false after a certain number of loop
5. Continue the program right after the block: print FIRE! and end program. iterations: to be more specific, when n becomes 0, that is
where our while-loop and our countdown end.
The do … while loop

The do...while loop executes the body of the loop before its condition is tested and ensures that the body always executes
at least one time.
The syntax for a do … while loop is: do
{
statement;
}
while ( condition );

- its functionality is exactly the same as the while loop, except that condition in the do .. while loop is evaluated after the
execution of statement instead of before, granting at least one execution of statement even if condition is never fulfilled.

-the condition is tested at the end of the block instead of the beginning, so the block will be executed at least once.
-If the condition is true, we jump back to the beginning of the block and execute it again.
- a do..while loop is basically a reversed while loop.
- a while loop says "Loop while the condition is true, and execute this block of code",
-a do..while loop says "Execute this block of code, and loop while the condition is true".
int x; Its functionality is exactly the same as the while loop, except that condition in the do-
do while loop is evaluated after the execution of statement instead of before, granting at
{ least one execution of statement even if condition is never fulfilled.
cout << "Enter number (0 to end): ";
cin >> x; Enter number (0 to end): 12345
cout << "You entered: " << x << "\n"; You entered: 12345
} Enter number (0 to end): 0
while (x != 0); You entered: 0

The do .. while loop is usually used when the condition that has to determine the end of the loop is determined within the loop
statement itself.

In the previous case, where the user input within the block is what is used to determine if the loop has to end.

In fact if you never enter the value 0 in the previous example you can be prompted for more numbers forever.
Jump statements.

The break statement int n;


Example: for (n=10; n>0; n--)
Using break we can leave a loop even if the condition for its {
end is not fulfilled. cout << n << ", ";
if (n==3)
It can be used to end an infinite loop, or to force it to end {
cout << "countdown aborted!";
before its natural end.
break;
}
}
The continue statement
The continue statement causes the program to skip the Example:
rest of the loop in the current iteration as if the end of the for (int n=10; n>0; n--)
{
statement block had been reached, causing it to jump to if (n==5) continue;
the start of the following iteration. cout << n << ", ";
}
cout << "FIRE!\n";

The goto statement

goto allows to make an absolute jump to another point in the program Example: int n=10;
loop:
cout << n << ", ";
It has the general form: goto label; n--;
if (n>0) goto loop;
label is an identifier which marks the jump destination of goto. The label cout << "FIRE!\n";
should be followed by a colon (:) and appear before a statement within the
same function as the goto statement itself.
The selective structure: switch

You saw how to write if and if/else statements, but these can become quite confusing when nested too deeply, C++
offers an alternative: the switch statement.

The switch statement provides a way of choosing between a set of alternatives, based on the value of an expression.

The syntax for the switch statement is as follows


switch ( <variable> )
{
case constant1 :
group of statements 1; // Code to execute if <variable> == constant1
break;
case constant2 :
group of statements 2 ; //Code to execute if <variable> == constant2
break;
...
default:
default group of statements; //Code to execute if <variable> does not equal the value following any of the cases
break;
}

It works in the following way:


switch evaluates variable and checks if it is equivalent to constant1, if it is, it executes group of statements 1 until it finds the
break statement. When it finds this break statement the program jumps to the end of the switch selective structure.

If expression was not equal to constant1 it will be checked against constant2. If it is equal to this, it will execute group of
statements 2 until a break keyword is found, and then will jump to the end of the switch selective structure.

Finally, if the value of expression did not match any of the previously specified constants, the program will execute the
statements included after the default: label, if it exists (since it is optional).
switch example if-else equivalent The switch statement is a bit peculiar within the C++
if (x == 1) language because it uses labels instead of blocks.
switch (x) { This forces us to put break statements after the
{ cout << "x is 1"; group of statements that we want to be executed for
case 1: }
cout << "x is 1"; else
a specific condition. Otherwise the remainder
break; if (x == 2) statements -including those corresponding to other
case 2: { labels- will also be executed until the end of the
cout << "x is 2"; cout << "x is 2"; switch selective block or a break statement is
break; } reached.
default: else
cout << "value of x unknown"; {
} cout << "value of x unknown";
}

switch (2)
switch (2)
{
{
case 1: // Does not match -- skipped we have to use a case 1: // Does not match -- skipped
cout << 1 << endl; break or a goto cout << 1 << endl;
case 2: // Match! Execution begins at the next statement
cout << 2 << endl; // Execution begins here
statement at the break;
end of our case case 2: // Match! Execution begins at the next statement
case 3:
cout << 2 << endl; // Execution begins here
cout << 3 << endl; // This is also executed statements.
break; // Break terminates the switch statement
case 4:
case 3:
cout << 4 << endl; // This is also executed
cout << 3 << endl;
default:
break;
cout << 5 << endl; // This is also executed
case 4:
}
cout << 4 << endl;
break;
default:
cout << 5 << endl;
break;
}
Functions
Now that you should have learned about variables, loops, and conditional statements it is time to learn about functions.

A function is, in effect, a subprogram that can act on data and return a value.
Every C++ program has at least one function, main().
When your program starts, main() is called automatically. main() might call other functions, some of which might call still others.

Function save work in that having solved a problem once it need not be solved again if there exists a function to solve the problem
given the particular parameters for this instance of the problem. In addition the function can be comprehensively tested and hence
a possible source of error is eliminated in future programs. These reasons are now expanded upon:

•When solving large problems it is usually necessary to split the problem down into a series of sub-problems, which in turn may be
split into further sub-problems etc. This is usually called a top-down approach. This process continues until problems become of
such a size that they can be solved by a single programmer. This top-down approach is essential if the work has to be shared out
between a team of programmers, each programmer ending up with a specification for a part of the system which is to be written as
a function (or functions). While writing a single function the programmer is able to concentrate on the solution of this one problem
only and is thus more likely to be able to solve the problem and make less errors. This function can now be tested on its own for
correctness.
•In a particular organisation or industry it may be found that in carrying out the top-down approach in some tasks occur very
frequently. For example the operation of sorting a file of data into some order occurs frequently in data-processing applications.
Thus a library of such commonly used functions can be built up and re-used in many different programs. This obviously saves
much work and cuts down errors if such functions have already been well tested.
•There are many very specialised problem areas, not every programmer can know every area. For example many programmers
working in scientific applications will frequently use mathematical function routines like sine and cosine, but would have no idea
how to write such routines. Similarly a programmer working in commercial applications might know very little about how an efficient
sorting routine can be implemented. However a specialist can write such routines, place them in a public library of functions and all
programmers can benefit from this expertise by being able to use these efficient and well tested functions.

Before looking at how functions are implemented in C++ the use of the mathematical function routines supplied in C++ is
considered.

Functions come in two varieties:


1.built-in : part of your compiler package
2.user-defined
The mathematical function library in C++

Some of the mathematical functions available in the C++ mathematics library are listed below.

acos(x) inverse cosine, -1 <= x <= +1, returns value in radians in range 0 to PI
asin(x) inverse sine, -1 <= x <= +1, returns value in radians in range 0 to PI
atan(x) inverse tangent, returns value in radians in range -PI/2 to PI/2
cos(x) returns cosine of x, x in radians
sin(x) returns sine of x, x in radians
tan(x) returns tangent of x, x in radians
exp(x) exponential function, e to power x
log(x) natural log of x (base e), x > 0
sqrt(x) square root of x, x >= 0
fabs(x) absolute value of x
floor(x) largest integer not greater than x
ceil(x) smallest integer not less than x
In all these functions the parameter x is a floating point value.

Example:
y = sin(3.14159);
z = cos(a) + sin(a);
factor = sin(theta)/(sin(delta) - sin(delta-theta));
theta = acos(1.0/sqrt(1 - x*x));
if (sin(x) > 0.7071)
cout << "Angle is greater than 45 degrees";
cout << "The value is " << exp(-a*t)*sin(a*t);

The file math.h must be included in any program that is going to use any functions from this library.
Introduction to User-defined functions in C++
C++ allows programmers to define their own functions. For example the following is a definition of a function which given the co-
ordinates of a point (x,y) will return its distance from the origin.
float distance(float x, float y) // Returns the distance of (x, y) from origin
This function has two input parameters, real values x and y, and
{
returns the distance of the point (x,y) from the origin.
float dist; //local variable
dist = sqrt(x * x + y * y);
return dist; In the function a local variable dist is used to temporarily hold the
} calculated value inside the function.

The general form of a function definition in C++ is as follows:

function_type function_name( parameter_list )


{
local_definitions;
function_implementation;
}

• If the function returns a value then the type of that value must be specified in function-type. For the moment this could be
int, float or char. If the function does not return a value then the function-type must be void.

• The function-name follows the same rules of composition as identifiers.

• The parameter-list lists the formal parameters of the function together with their types.

• The local-definitions are definitions of variables that are used in the function-implementation. These variables have no
meaning outside the function.

• The function-implementation consists of C++ executable statements that implement the effect of the function.
Using functions in your program requires that you first declare the function and that you then define the function.

The declaration tells the compiler the name, return type, and parameters of the function.

The definition tells the compiler how the function works.

No function can be called from any other function that hasn't first been declared.

The declaration of a function is called its prototype.


A function provides a convenient way of packaging a computational recipe, so that it can be used as often as required.

A function definition consists of two parts: interface and body.

The interface of a function specifies how it may be used. It consists of three entities:
· The function name. This is simply a unique identifier.
· The function parameters. This is a set of zero or more typed identifiers used for passing values to and from the function.
· The function return type. This specifies the type of value the function returns. A function which returns nothing should have
the return type void.

The body of a function contains the computational steps (statements) that comprise the function.
Many of the built-in functions you use will have their function prototypes already written in the files you include in your program
by using #include. For functions you write yourself, you must include the prototype

The function prototype is a statement, which means it ends with a semicolon. It consists of the function's return type, name, and
parameter list.
The parameter list is a list of all the parameters and their types, separated by commas.

function_type function_name ( parameter_list );


The function prototype and the function definition must agree exactly about the return type, the name, and the parameter list. If
they do not agree, you will get a compile-time error. Note, however, that the function prototype does not need to contain
the names of the parameters, just their types. A prototype that looks like this is perfectly legal:
Note that all functions have a return type. If none is
int addition (int , int) ;
explicitly stated, the return type defaults to int.
#include <iostream> In order to examine this code, first of all remember:
Example: using namespace std; -a C++ program always begins its execution by the main function. So we
int addition (int a, int b)
{
will begin there.
int r;
r=a+b; We can see how the main function begins by declaring the variable z
return (r); of type int. Right after that, we see a call to a function called addition.
}

int main ()
We see the similarity between the structure of the call to the function and
{ the declaration of the function itself some code lines above:
int z;
z = addition (5,3);
cout << "The result is " << z;
return 0;
}

The parameters and arguments have a clear correspondence. Within the main function we called to addition passing two
values: 5 and 3, that correspond to the int a and int b parameters declared for function addition.

At the point at which the function is called from within main, the control is lost by main and passed to function addition. The
value of both arguments passed in the call (5 and 3) are copied to the local variables int a and int b within the function.

Function addition declares another local variable (int r), and by means of the expression r=a+b, it assigns to r the result of a
plus b. Because the actual parameters passed for a and b are 5 and 3 respectively, the result is 8.

The following line of code:


return (r);
finalizes function addition, and returns the control back to the function that called it in the first place (in this case, main). At
this moment the program follows it regular course from the same point at which it was interrupted by the call to addition. But
additionally, because the return statement in function addition specified a value: the content of variable r (return (r);), which
at that moment had a value of 8. This value becomes the value of evaluating the function call.
Variables: global and local
The scope of variables declared within a function or any other inner block is only their own function or their own block and
cannot be used outside of them. For example, in the previous example it would have been impossible to use the variables a, b
or r directly in function main since they were variables local to function addition. Also, it would have been impossible to use the
variable z directly within function addition, since this was a variable local to the function main.

#include <iostream>
Therefore, the scope of local variables is limited to the same
block level in which they are declared. Nevertheless, we also int a,b;
have the possibility to declare global variables; These are char word; global variables
visible from any point of the code, inside and outside all float number;
functions. In order to declare global variables you simply have
to declare the variable outside any function or block; that int main()
means, directly in the body of the program. {

int Integer; local variables


Function parameters and arguments Char WordCharacter;
In common usage, the terms parameter and argument are often float NumberA;
interchanged. However, for the purposes of further discussion, we
will make a distinction between the two: Cout<<“Enter nr:”;
Cin>> Integer; instructions
A function parameter is a variable declared in the prototype or …
declaration of a function:
}
int addition (int a, int b) //prototype≡ declaration– a,b are parameters

An argument is the value that is passed to the function in place of a parameter:

addition (5,3); // 5 and 3 are the arguments passed to parameters a and b

Function arguments do not have to all be of the same type. It is perfectly reasonable to write a function that takes an integer,
two floats, and a character as its arguments.

Although it is legal for one function to take as a parameter a second function that returns a value, it can make for code that is hard
to read.
Arguments passed by value and by reference.

Until now, in all the functions we have seen, the arguments passed to the functions have been passed by value. This means
that when calling a function with parameters, what we have passed to the function were copies of their values but never the
variables themselves.

For example, suppose that we called our first function addition using the following code:

int x=5, y=3, z; What we did in this case was to call to function addition passing the values of x and y, i.e. 5 and
z = addition ( x , y ); 3 respectively, but not the variables x and y themselves.

This way, when the function addition is called, the value of its local variables a and b become 5 and 3 respectively, but any
modification to either a or b within the function addition will not have any effect in the values of x and y outside it, because variables
x and y were not themselves passed to the function, but only copies of their values at the moment the function was called.

But there might be some cases where you need to manipulate from inside a function the value of an external variable. For that
purpose we can use arguments passed by reference, as in the function duplicate of the following example:
#include <iostream>
using namespace std; The first thing that should call your attention is that in the declaration of duplicate the type of
void duplicate (int& a, int& b, int& c) each parameter was followed by an ampersand sign (&). This ampersand is what specifies
{ that their corresponding arguments are to be passed by reference instead of by value.
a*=2;
b*=2; When a variable is passed by reference we are not passing a copy of its value, but we are
c*=2; somehow passing the variable itself to the function and any modification that we do to the
} local variables will have an effect in their counterpart variables passed as arguments in the
int main () call to the function.
{ To explain it in another way, we associate a, b
int x=1, y=3, z=7; and c with the arguments passed on the
duplicate (x, y, z);
cout << "x=" << x << ", y=" << y
function call (x, y and z) and any change that
<< ", z=" << z; we do on a within the function will affect the
return 0; value of x outside it. Any change that we do on
} b will affect y, and the same with c and z.
Functions with no type. The use of void.

Functions with no parameters are of limited use. Usually they will not return a value but carry out some operation. For
example consider the following function which skips three lines on output.

#include <iostream> Note that the function-type has been given as void, this tells the compiler that
Use namespace std; this function does not return any value. Because the function does not take any
// Function prototypes
void skipthree(void);
parameters the parameter-list is empty, this is indicated by the void parameter-
int main() list. No local variables are required by this function and the function
{ implementation only requires the sending of three successive end of line
// Test function skipthree() characters to the output stream cout.
cout << "Testing function skipthree()" << endl;
skipthree(); Note the introductory comment that describes what the function does. All functions should include
cout << "Tested" << endl; this information as minimal comment.
}
// End of main
// Function Definitions Since this function does not return a value it cannot be used in an expression and is
void skipthree(void) called by treating it as a statement as follows:
// skips three lines on output
{ skipthree();
cout << endl << endl << endl;
return 0;
} Even though there are no parameters the empty parameter list () must be inserted.

Functions with parameters and no return value

The function of the previous section is not very useful, what if four lines were to be skipped, or two lines?

It would be much more useful if it was possible to tell the function how many lines to skip. That is the function should have an
input parameter which indicates how many lines should be skipped.

The function skipthree() is now changed to the function skip which has a parameter n indicating how many lines have to be
skipped as follows:
#include <iostream>
As before this function does not return a value hence it is declared as
void skip(int); // Function prototypes having type void.

int main() It now takes an integer parameter n which indicates the number of lines
{
to be skipped.
// Test function skip(n)

cout << "Testing function skip(n)" The parameter list then consists of a type and a name for this formal
<< endl parameter.
<< "Enter a value for n: ";
cin >> n;
Inside the body of the function (enclosed in {}) a loop control variable i is
cout << "Skip " << n << " lines after this line" << endl;
skip(n); declared.
cout << "Tested" << endl;
} // End of main This variable is a local variable to the function. A local variable defined
within the body of the function has no meaning, or value, except within
void skip(int n) // Function Definitions
the body of the function.
// Function skips n lines on output
{
int i; // a local variable to this function It can use an identifier name that is used elsewhere in the program
// now loop n times without there being any confusion with that variable. Thus changing the
for (i = 0; i < n; i++) value of the local variable i in the function skip will not affect the value of
cout << endl;
any other variable i used elsewhere in the program. Similarly changing
return 0;
}
the value of a variable i used elsewhere in the program will not affect the
value of the local variable i in skip.
Functions that return values

One of the most useful forms of function is one that returns a value that is a function of its parameters.

In this case the type given to the function is that of the value to be returned. Thus consider the function, previously
considered, which given the co-ordinates of a point (x,y) will return its distance from the origin:

#include <iostream>
#include <math.h> This function introduces several new features. Note the following:
float distance(float,float); // Function prototypes

int main()
•The function has been given the type float because it is going to
{ return a float value.
float x,y,dist; •The parameter-list now has two parameters, namely, x and y. Each
parameter is declared by giving its type and name and successive
// Test function distance(x,y) parameter declarations are separated by a comma.
cout << "Testing function distance(x,y)" << endl;
•A local variable dist has been declared to temporarily hold the
cout << "Enter values for x and y: "; calculated distance.
cin >> x >> y; •Because this function returns a value it includes a return statement
dist = distance(x,y); which returns the value. In a statement return value the value may be
cout << "Distance of (" << x << ',' << y << ") from origin is " a constant, a variable or an expression. Hence the use of the local
<< dist << endl
<< "Tested"
variable dist was not essential since the return statement could have
<< endl; been written:
return 0; return sqrt(x*x + y*y);
} // End of main
When the function is called the formal parameters x and y are
float distance(float x, float y) // Function Definitions
replaced by actual parameters of type float and in the same order, i.e.
// Returns the distance of (x, y) from origin the x co-ordinate first. Since the function returns a value it can only
{ be used in an expression.
float dist; //local variable
dist = sqrt(x * x + y * y);
return dist;
}
#include <iostream> A function may have several return

float mysqrt(float); // Function prototypes statements. This is illustrated in the following


int main()
function which implements the algorithm for
{
float x, y, dist; // Test function mysqrt(x); evaluating the square root previously
cout << "Testing function mysqrt()" << endl;
cout << "Enter a value for x: ";
considered.
cin >> x;
y = mysqrt(x);
cout << "Square root of " << x << " is "
<< y
<< endl;
cout << "Tested" << endl;
return 0;
} // End of main

float mysqrt(float x) // Function Definitions


// Function returns square root of x.
// If x is negative it returns zero.
{
const float tol = 1.0e-7; // 7 significant figures
float xold, xnew; // local variables
if (x <= 0.0)
return 0.0; // covers -ve and zero case
else
{
xold = x; // x as first approx
xnew = 0.5 * (xold + x / xold); // better approx
while (fabs((xold-xnew)/xnew) > tol)
{
xold = xnew;
xnew = 0.5 * (xold + x / xold);
}
return xnew; // must return float value
}
} // end mysqrt
Return Values
Functions return a value or return void. Void is a signal to the compiler that no value will be returned.

To return a value from a function, write the keyword return followed by the value you want to return. The value might itself
be an expression that returns a value.
For example:
return 5; return (x > 5); return (MyFunction());
These are all legal return statements, assuming that the function MyFunction() itself returns a value. The value in the second
statement, return (x > 5), will be zero if x is not greater than 5, or it will be 1. What is returned is the value of the expression, 0
(false) or 1 (true), not the value of x

When the return keyword is encountered, the expression following return is returned as the value of the function. Program
execution returns immediately to the calling function, and any statements following the return are not executed.

Default Parameters

For every parameter you declare in a function prototype and definition, the calling function must pass in a value. The value
passed in must be of the declared type. Thus, if you have a function declared as

long myFunction(int);

the function must in fact take an integer variable. If the function definition differs, or if you fail to pass in an integer, you will
get a compiler error.

The one exception to this rule is if the function prototype declares a default value for the parameter. A default value is a value
to use if none is supplied. The preceding declaration could be rewritten as

long myFunction (int x = 50);

This prototype says, "myFunction() returns a long and takes an integer parameter. If an argument is not supplied, use the
default value of 50."
Because parameter names are not required in function prototypes, this declaration could have been written as

long myFunction (int = 50);

The function definition is not changed by declaring a default parameter. The function definition header for this function would be

long myFunction (int x)

If the calling function did not include a parameter, the compiler would fill x with the default value of 50. The name of the default
parameter in the prototype need not be the same as the name in the function header; the default value is assigned by position,
not name.

Any or all of the function's parameters can be assigned default values. The one restriction is this: If any of the parameters does
not have a default value, no previous parameter may have a default value.

If the function prototype looks like

long myFunction (int Param1, int Param2, int Param3);

you can assign a default value to Param2 only if you have assigned a default value to Param3. You can assign a default value to
Param1 only if you've assigned default values to both Param2 and Param3. Listing 5.7 demonstrates the use of default values.

#include <iostream>
int AreaCube(int length, int width = 25, int height = 1); area = AreaCube(length);
int main() cout << "Third time area equals: " << area << "\n";
{ return 0;
int length = 100; }
int width = 50; AreaCube(int length, int width, int height)
int height = 2; {
int area; return (length * width * height);
area = AreaCube(length, width, height); }
cout << "First area equals: " << area << "\n";
area = AreaCube(length, width);
cout << "Second time area equals: " << area << "\n";
Overloading Functions

C++ enables you to create more than one function with the same name. This is called function overloading. The functions must
differ in their parameter list, with a different type of parameter, a different number of parameters, or both.

Special Topics About Functions


Because functions are so central to programming, a few special topics arise which might be of interest when you confront unusual
problems. Used wisely, inline functions can help you squeak out that last bit of performance. Function recursion is one of those
wonderful, esoteric bits of programming which, every once in a while, can cut through a thorny problem otherwise not easily solved.

Inline Functions

Suppose that a program frequently requires to find the absolute value of an integer quantity. For a value denoted by n,
this may be expressed as: (n > 0 ? n : -n)

better to define it as a function: The disadvantage of the function version, however, is that its frequent use can
int Abs (int n)
lead to a considerable performance penalty due to the overheads associated with
{
calling a function.
return n > 0 ? n : -n; For example, if Abs is used within a loop which is iterated thousands of times, then it
}
will have an impact on performance.

The overhead can be avoided by defining


Abs as an inline function: The effect of this is that when Abs is called, the compiler, instead of generating
code to call Abs, expands and substitutes the body of Abs in place of the call.
inline int Abs (int n) While essentially the same computation is performed, no function call is
{ involved and hence no stack frame is allocated.
return n > 0 ? n : -n;
}

Because calls to an inline function are expanded, no trace of the function itself will be left in the compiled code. Therefore, if a
function is defined inline in one file, it may not be available to other files. Consequently, inline functions are commonly
placed in header files so that they can be shared.
Recursive

A function which calls itself is said to be recursive. Recursion is a general programming technique applicable to problems
which can be defined in terms of themselves. Take the factorial problem, for instance, which is defined as:
· Factorial of 0 is 1.
· Factorial of a positive number n is n times the factorial of n-1.

The second line clearly indicates that factorial is defined in terms of itself and hence can be expressed as a recursive function:

int Factorial (unsigned int n)


{
return n == 0 ? 1 : n * Factorial(n-1);
}

A recursive function must have at least one termination condition which can be satisfied. Otherwise, the function will call
itself indefinitely until the runtime stack overflows.
The Factorial function, for example, has the termination condition n == 0 which, when satisfied, causes the recursive calls to
fold back. (Note that for a negative n this condition will never be satisfied and Factorial will fail).

An iterative version is therefore preferred in this case:

int Factorial (unsigned int n)


{
int result = 1;
while (n > 0) result *= n--;
return result;
}
Compound Data Types in C++

Arrays

An array consists of a set of objects (called its elements), all of which are of the same type and are arranged contiguously in
memory.

The number of elements must be an integer.

In general, only the array itself has a symbolic name, not its elements. Each element is identified by an index which denotes the
position of the element in the array.

The number of elements in an array is called its dimension. The dimension of an array is fixed and predetermined; it cannot be
changed during program execution. Arrays are suitable for representing composite data which consist of many similar, individual
items.
That means that, for example, we can store 5 values of type int in an array without having to declare 5 different variables, each
one with a different identifier. Instead of that, using an array we can store 5 different values of the same type, int for example,
with a unique identifier.
For example, an array to contain 5 integer values of type int called testArray could be represented like this:

0 1 2 3 4
where each blank panel represents an element of the array,
testArray that in this case are integer values of type int. These elements
are numbered from 0 to 4 since in arrays the first index is
int always 0, independently of its length.

Like a regular variable, an array must be declared before it is used. A typical declaration for an array in C++ is:
type name [elements];

where type is a valid type (like int, float...), name is a valid identifier and the elements field (which is always enclosed in square
brackets , subscript operator ([]) ), specifies how many of these elements the array has to contain.

Therefore, in order to declare an array called testArray as the one shown in the above diagram it is as simple as:
int testArray[5];
The number of elements in an array must be fixed at compile time.

It is best to make the array size a constant and then, if required, the program can be changed to handle a different size of array
by changing the value of the constant,

const int elements_nr = 100;


float annual_temp[elements_nr];

then if more records come to light it is easy to amend the program to cope with more values by changing the value of
elements_nr. This works because the compiler knows the value of the constant elements_nr at compile time and can allocate an
appropriate amount of space for the array. It would not work if an ordinary variable was used for the size in the array declaration
since at compile time the compiler would not know a value for it.
Note that in C++, arrays always count starting from zero! This means an array of size N has array elements 0 through N-1.

int testArray[5]; // allocate 5 integers Note that the subscript operator actually has two uses here:
1.in the variable declaration, the subscript tells how many elements to allocate.
testArray[4] = 89; // put the value 89 in element 4 2.When using the array, the subscript tells which array element to access.

Example:
int testArray[3]; // allocate 3 integers
testArray[0] = 2;
testArray[1] = 3;
testArray[2] = 4;

int nSum = testArray[0] + testArray[1] + testArray[2];


cout << "The sum is " << nSum << endl;
Initializing arrays.

When declaring a regular array of local scope (within a function, for example), if we do not specify otherwise, its elements will
not be initialized to any value by default, so their content will be undetermined until we store some value in them.

The elements of global and static arrays, on the other hand, are automatically initialized with their default values, which for all
fundamental types this means they are filled with zeros.

In both cases, local and global, when we declare an array, we have the possibility to assign initial values to each one of its
elements by enclosing the values in braces { }.
0 1 2 3 4
Example: This declaration 250 5 2 99 1
testArray
int testArray [5] = { 250, 5, 2, 99, 1}; would have
created an array
like this:

The amount of values between braces { } must not be larger than the number of elements that we declare for the array between
square brackets [ ]. For example, in the example of array testArray we have declared that it has 5 elements and in the list of
initial values within braces { } we have specified 5 values, one for each element.

When an initialization of values is provided for an array, C++ allows the possibility of leaving the square brackets empty [ ]. In
this case, the compiler will assume a size for the array that matches the number of values included between braces { }:

int testArray [] = {250, 5, 2, 99, 1}; After this declaration, array testArray would be 5 ints
long, since we have provided 5 initialization values.
Accessing Array Elements

An array element is accessed by writing the identifier of the array followed by the subscript in square brackets.

Example
to set the 90th element of the array above to 18.89 the following assignment is used:
const int elements_nr = 100;
float testArray[elements_nr];
testArray[89] = 18.89;

Note that since the first element is at index 0, then the i-th element
is at index i-1. Hence in the above the 90-th element has index 89.

An array element can be used anywhere an identifier may be used. Here are some examples assuming the following declarations:

const int nr = 100,


n = 50; A value can be read into an array element directly, using cin
int i, j, count[n];
float testArray[nr]; cin >> count[i];
float sum, av1, av2;
The element can be increased by 3, or, using the shorthand form of the assignment

count[i] = count[i] + 3; count[i] += 3;

Array elements can form part of the condition for an if statement, or indeed, for any other logical expression:

if (testArray[j] < 10.0)


cout << “The j-th element is smaller then 10"
<< endl;
for statements are the usual means of accessing every element in an array. Here, the first nr elements of the array testArray
are given values from the input stream cin.

for (i = 0; i < nr; i++) sum = 0.0;


cin >> testArray[i];
for (i = 0; i <10; i++)
The following code finds the average testArray recorded in the first ten elements of the array.
sum += testArray[i];
Notice that it is good practice to use named constants, rather than literal numbers such as 10. If the
av1 = sum / 10;
program is changed to take the average of the first 20 entries, then it all too easy to forget to change
a 10 to 20. If a const is used consistently, then changing its value will be all that is necessary.

For example, the following example finds the average of the last k entries in the array. k could either be a variable, or a
declared constant. Observe that a change in the value of k will still calculate the correct average (provided k<=nr).
sum = 0.0;
for (i = nr - k; i < nr; i++)
sum += testArray[i];
av2 = sum / k;
Important

C++ does not check that the subscript that is used to reference an array element actually lies in the subscript range of the array.
Thus C++ will allow the assignment of a value to testArray[200], however the effect of this assignment is unpredictable.
For example it could lead to the program attempting to assign a value to a memory element that is outside the program's
allocated memory space. This would lead to the program being terminated by the operating system. Alternatively it might actually
access a memory location that is within the allocated memory space of the program and assign a value to that location, changing
the value of the variable in your program which is actually associated with that memory location, or overwriting the machine code
of your program.
Similarly reading a value from testArray[200] might access a value that has not been set by the program or might be the value of
another variable. It is the programmer's responsibility to ensure that if an array is declared with n elements then no attempt is
made to reference any element with a subscript outside the range 0 to n-1. Using an index, or subscript, that is out of range is
called Subscript Overflow. Subscript overflow is one of the commonest causes of erroneous results and can frequently cause
very strange and hard to spot errors in programs.
#include <iostream.h> A set of positive data values (200) are available. It is required to
#include <iomanip.h> find the average value of these values and to count the number
void main() of values that are more than 10% above the average value.
{
const int nr = 200; // maximum no of elements in array Since the data values are all positive a negative value can be used as a sentinel to
float sum = 0.0; // accumulates sum signal the end of data entry. Obviously this is a problem in which an array must be
int count = 0; // number of elements entered used since the values must first be entered to find the average and then each value
int nogt10 = 0; // counts no greater than 10% above average must be compared with this average. Hence the use of an array to store the entered
values for later re-use.
float x; // holds each no as input
float indata[nr]; // array to hold input An initial algorithmic description is:
float average; // average value of input values
int i; // control variable initialise.
enter elements into array and sum elements.
// Data entry, accumulate sum and count number of +ve numbers entered evaluate average. scan array and count number greater than 10% above average.
output results.
cout << "Enter numbers, -ve no to terminate: " << endl;
cin >> x; This can be expanded to the complete algorithmic description:
while (x >= 0.0) set sum to zero.
{ set count to zero.
sum = sum + x; set nogt10 to zero.
indata[count] = x; enter first value.
count = count + 1; while value is positive
cin >> x; {
} put value in array element with index count.
add value to sum.
// calculate average increment count.
average = sum/count; enter a value.
}
// Now compare input elements with average average = sum/count.
for (i = 0; i < count; i++) for index taking values 0 to count-1
{ if array[index] greater than 1.1*average
if (indata[i] > 1.1 * average) then increment nogt10.
nogt10++; output average, count and nogt10.
}
In the above the variable nogt10 is the number greater than 10% above the average
// Output results value. It is easy to argue that after exiting the while loop, count is set to the number
cout << "Number of values input is " << count; of positive numbers entered. Before entering the loop count is set to zero and the
cout << endl first number is entered, that is count is one less than the number of numbers
<< "Number more than 10% above average is " entered. Each time round the loop another number is entered and count is
<< nogt10 incremented hence count remains one less than the number of numbers entered.
<< endl; But the number of numbers entered is one greater than the number of positive
}
numbers so count is therefore equal to the number of positive numbers .
Multidimensional Arrays

The elements of an array can be of any data type, including arrays! An array of arrays is called a multidimensional array.

int biArray[3][5]; // a 3-element array of 5-element arrays

- a bidimensional array can be imagined as a bidimensional table made of elements, all of them of a same uniform data type.

0 1 2 3 4
0
biArray represents a bidimensional
biArray 1 array of 3 per 5 elements of type int.

Initializing Multidimensional Arrays

You can initialize multidimensional arrays.


You assign the list of values to array elements in order, with the last array subscript changing while each of the former holds steady.
Therefore, if you have an array
int biArray[5][3];

the first three elements go into biArray[0]; the next three into biArray[1]; and so forth.
You initialize this array by writing
int biArray[5][3] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };

For the sake of clarity, you could group the initializations with braces.
For example,
int biArray[5][3] = { {1,2,3}, {4,5,6}, {7,8,9}, {10,11,12}, {13,14,15} };

The compiler ignores the inner braces, which make it easier to understand how the numbers are distributed.
Each value must be separated by a comma, without regard to the braces. The entire initialization set must be within braces,
and it must end with a semicolon.
Example:
-creates a two-dimensional array. The first dimension is the set of numbers from 0 to 5. The second dimension
consists of the double of each value in the first dimension.

#include <iostream.h> const int rows = 3;


int main() const int columns = 4;
int seasonTemp[rows][columns] = {
{ {26, 34, 22, 17},
int biArray[5][2] = { {0,0}, {1,2}, {2,4}, {3,6}, {4,8}}; {24, 32, 19, 13},
for (int i = 0; i<5; i++) {28, 38, 25, 20}
for (int j=0; j<2; j++) };
{ int HighestTemp (int temp[rows][columns])
{
cout << “biArray[" << i << "][" << j << "]: "; int highest = 0;
cout << SomeArray[i][j]<< endl; for (register i = 0; i < rows; ++i)
} for (register j = 0; j < columns; ++j)
return 0; if (temp[i][j] > highest)
} highest = temp[i][j];
return highest;
}

Multidimensional arrays are not limited to two indices (i.e., two dimensions). They can contain as many indices as needed.

But be careful!
The amount of memory needed for an array rapidly increases with each dimension. For example:
char century [100][365][24][60][60];
declares an array with a char element for each second in a century, that is more than 3 billion chars. So this declaration would
consume more than 3 gigabytes of memory!

Multidimensional arrays are just an abstraction for programmers, since we can obtain the same results with a simple array just
by putting a factor between its indices:

int biArray [3][5]; // is equivalent to


int testArray[15]; // (3 * 5 = 15)
char Arrays

A new data type is now considered, namely, the character string, which is used to represent a sequence of characters regarded
as a single data item.

In C++ strings of characters are held as an array of characters, one character held in each array element. In addition a special
null character, represented by `\0', is appended to the end of the string to indicate the end of the string.

Hence if a string has n characters then it requires an n+1 element array (at least) to store it. Thus the character `a' is stored in a
single byte, whereas the single-character string "a" is stored in two consecutive bytes holding the character `a' and the null
character.
Example: is an array that can store up to 20 elements of type char. It can be represented as:

char nume [15]; nume

Therefore, in this array, in theory, we can store sequences of characters up to 15 characters long. But we can also store shorter
sequences. For example, nume could store at some point in a program either the sequence "Hello" or the sequence “Huppy",
since both are shorter than 15 characters.

Therefore, since the array of characters can store shorter sequences than its total length, a special character is used to signal
the end of the valid sequence: the null character, whose literal constant can be written as '\0' (backslash, zero).

Our array of 15 elements of type char, called jenny, can be represented storing the characters sequences "Hello" and “Huppy
new" as:
nume H e l l o \0

nume H u p p y n e w \0

Notice how after the valid content a null character ('\0') has been included in order to indicate the end of the sequence. The
panels in gray color represent char elements with undetermined values.
Initialization of null-terminated character sequences

Because arrays of characters are ordinary arrays they follow all their same rules. For example, if we want to initialize an
array of characters with some predetermined sequence of characters we can do it just like any other array:

char myword[] = { 'H', 'e', 'l', 'l', 'o', '\0' };

In this case we would have declared an array of 6 elements of type char initialized with the characters that form the word
"Hello" plus a null character '\0' at the end.

But arrays of char elements have an additional method to initialize their values: using string literals.
Therefore we can initialize the array of char elements called myword with a null-terminated sequence of characters by either one
of these two methods:
char myword [] = { 'H', 'e', 'l', 'l', 'o', '\0' };
char myword [] = "Hello";

In both cases the array of characters myword is declared with a size of 6 elements of type char: the 5 characters that compose
the word "Hello" plus a final null character ('\0') which specifies the end of the sequence and that, in the second case, when
using double quotes (") it is appended automatically

#include <iostream>
using namespace std; As you can see, we have declared three arrays of char elements.
int main ()
{ The first two were initialized with string literal constants, while the
char question[] = "Please, enter your first name: "; third one was left uninitialized.
char greeting[] = "Hello, ";
char yourname [80]; In any case, we have to speficify the size of the array: in the first
cout << question; two (question and greeting) the size was implicitly defined by the
cin >> yourname; length of the literal constant they were initialized to.
cout << greeting << yourname << "!";
return 0; While for yourname we have explicitly specified that it has a size
} of 80 chars.
Pointers
A pointer is a variable that holds the address of another variable.
Pointers are one of the most powerful and confusing aspects of the C++ language.
identifiers
Variables are seen as memory cells that can
be accessed using their identifiers.
x y The memory of
int x; your computer
double y; 5 1.75 can be imagined
as a succession
x=5; of memory cells
y=1.75;

ad=a+y;
So far we did not have to care about the physical location of our data 6.75
within memory, we simply used its identifier whenever we wanted to refer cout>>ad;
to our variable.

x y
5 1.75
The single memory cells are numbered in a
consecutive way, so as, within any block of
memory, every cell has the same number as the
previous one plus one.
2550 2554

address memory

In this way, each cell can be easily located in the memory because it has a unique address and all the memory cells follow a
successive pattern.

For example, if we are looking for cell 2550 we know that it is going to be right between cells 2549 and 2551, exactly two
thousand cells after 550 and exactly one thousand cells before cell 3550.
Reference operator (&)

As soon as we declare a variable, the amount of memory needed is assigned for it at a specific location in memory (its
memory address).

We generally do not actively decide the exact location of the variable within the panel of cells that we have imagined the
memory to be

Fortunately, that is a task automatically performed by the operating system during runtime. However, in some cases we
may be interested in knowing the address where our variable is being stored during runtime in order to operate with
relative positions to it.

The address that locates a variable within memory is what we call a reference to that variable.

This reference to a variable can be obtained by preceding the identifier of a variable with an ampersand sign (&), known as
reference operator (or address-of operator), and which can be literally translated as "address of".

This would assign to x the address of variable y, since when preceding the name of the
Example x= &y; variable y with the reference operator (&) we are no longer talking about the content of the
variable itself, but about its address in memory

From now on we are going to assume that y is placed during runtime in the memory address 2554. This number (2554)
is just an arbitrary assumption we are inventing right now in order to help clarify some concepts, but in reality, we
cannot know before runtime the real value the address of a variable will have in memory.
Example
y = 1.75;
z= y; The values contained in each variable after the execution of this code is:
pnt = &y;
y
1.75

2552 2553 2554 2555 2556

z = & pnt
1.75 2554

First, we have assigned the value 1.75 to y (a variable whose address in memory we have assumed to be 2554).

The second statement copied to z the content of variable y (which is 1.75). This is a standard assignment operation, as
we have done so many times before.

Finally, the third statement copies to pnt not the value contained in y but a reference to it (i.e., its address, which we
have assumed to be 2554).

The reason is that in this third assignment operation we have preceded the identifier y with the reference operator (&), so
we were no longer referring to the value of y but to its address in memory (its reference).

The variable that stores the reference to another variable (like ted in the previous example) is what we call a pointer.

The value of a pointer variable is the address to which it points.

Pointers are a very powerful feature of the C++ language that has many uses in advanced programming. Farther ahead,
we will see how this type of variable is used and declared.
Dereference operator (*)

We have just seen that a variable which stores a reference to another variable is called a pointer.

Pointers are said to "point to" the variable whose reference they store.

Using a pointer we can directly access the value stored in the variable which it points to. To do this, we simply have to precede
the pointer's identifier with an asterisk (*), which acts as dereference operator and that can be literally translated to "value
pointed by".

Example: following with the values of the previous example, if we write:

w= * pnt; // w equal to value pointed by pnt

w would take the value 1.75, since pnt is 2554, and the value pointed by 2554 is 1.75.

You must clearly differentiate that the expression pnt refers to the value 2554, while *pnt (with an asterisk * preceding the
identifier) refers to the value stored at address 2554, which in this case is 1.75.

w= pnt; // w equal to pnt w= 2554


w=*pnt; // w equal to value pointed by pnt w= 1.75

Notice the difference between the reference and dereference operators:

• & is the reference operator and can be read as "address of“


• * is the dereference operator and can be read as "value pointed by"

They have complementary (or opposite) meanings. A variable referenced with & can be dereferenced with *.
Example:

X==1.75
x=1.75; &x==2554
y=&x; y==2554
*y==1.75

The first expression is quite clear considering that the assignment operation performed on x was x=1.75.

The second one uses the reference operator (&), which returns the address of variable x, which we assumed it to
have a value of 2554.

The third one is somewhat obvious since the second expression was true and the assignment operation performed
on y was y=&x.

The fourth expression uses the dereference operator (*) that, as we have just seen, can be read as "value pointed
by", and the value pointed by y is indeed 1.75.

Declaring variables of pointer types

Due to the ability of a pointer to directly refer to the value that it points to, it becomes necessary to specify in its declaration which
data type a pointer is going point to. It is not the same thing to point to a char than to point to an int or a float.

Syntax:

type * name; type is the data type of the value that the pointer is intended to point to.

this type is not the type of the pointer itself ! but the type of the data the pointer points to.
Example: three declarations of pointers

int * number; all of them are pointers and all of them will occupy the same amount of space in memory : the
char * character;
size in memory of a pointer depends on the platform where the code is going to run.
float * greatnumber;

the data to which they point to do not occupy the same amount of space nor are of the same type:

• the first one points to an int


• the second one points to a char

• the last one points to a float.


Therefore, although these three example variables are all of them pointers which occupy the same size in memory, they are
said to have different types: int*, char* and float* respectively, depending on the type they point to.

#include <iostream>
Notice that even though we have never directly set a value to
using namespace std;
either firstvalue or secondvalue, both end up with a value set
int main ()
{ indirectly through the use of mypointer.
int firstvalue, secondvalue;
int * mypointer; -we have assigned as value of mypointer a reference to
mypointer = &firstvalue; firstvalue using the reference operator (&).
*mypointer = 10;
mypointer = &secondvalue; - then we have assigned the value 10 to the memory location
*mypointer = 20; pointed by mypointer, that because at this moment is pointing to
cout << "firstvalue is " << firstvalue << endl; the memory location of firstvalue, this in fact modifies the value
cout << "secondvalue is " << secondvalue << endl; of firstvalue.
return 0;
}
a pointer may take several different values during
#include <iostream>
the same program
using namespace std;
int main ()
{ Notice that there are expressions with pointers p1 and
int firstvalue = 5, secondvalue = 15; p2, both with and without dereference operator (*). The
int * p1, * p2; meaning of an expression using the dereference
p1 = &firstvalue; // p1 = address of firstvalue operator (*) is very different from one that does not:
p2 = &secondvalue; // p2 = address of secondvalue
*p1 = 10; // value pointed by p1 = 10 when this operator precedes the pointer name, the
*p2 = *p1; // value pointed by p2 = value pointed by p1 expression refers to the value being pointed, while when
p1 = p2; // p1 = p2 (value of pointer is copied) a pointer name appears without this operator, it refers to
*p1 = 20; // value pointed by p1 = 20 the value of the pointer itself (i.e. the address of what
the pointer is pointing to).
cout << "firstvalue is " << firstvalue << endl;
cout << "secondvalue is " << secondvalue << endl;
return 0;
}

int * p1, * p2; //both have type int* (pointer to int)

int * p1, p2; // p1 would indeed have int* type, but p2 would have type int

Pointers and arrays

The concept of array is very much bound to the one of pointer.

In fact, the identifier of an array is equivalent to the address of its first element, as a pointer is equivalent to the address of
the first element that it points to, so in fact they are the same concept.
Suppos declarations:

int numbers [20]; // array p = numbers;


The following assignment operation would be valid:
int * p; // pointer

After that, p and numbers would be equivalent and would have the same properties.
The only difference is that we could change the value of pointer p by another one, whereas numbers will always point to the
first of the 20 elements of type int with which it was defined.
Therefore, unlike p, which is an ordinary pointer, numbers is an array, and an array can be considered a constant pointer.

#include <iostream>
using namespace std; numbers = p;
int main ()
{ the following allocation
int numbers[5]; Because numbers is an array, so it operates as
int * p; would not be valid: a constant pointer, and we cannot assign values
p = numbers; to constants.
*p = 10;
p++;
*p = 20;
p = &numbers[2];
*p = 30;
p = numbers + 3;
*p = 40;
p = numbers;
*(p+4) = 50;
for (int n=0; n<5; n++)
cout << numbers[n] << ", ";
return 0;
}
Pointer initialization

When declaring pointers we may want to explicitly specify which variable we want them to point to:

int number;
int number;
int *x;
int *x = &number;
x= &number;

When a pointer initialization takes place we are always assigning the reference value to where the pointer points (x), never
the value being pointed (*x).

You must consider that at the moment of declaring a pointer, the asterisk (*) indicates only that it is a pointer, it is not the
dereference operator (although both use the same sign: *). Remember, they are two different functions of one sign.
we must take care not to confuse the previous code with

int number;
int *x; that is incorrect
*x = &number;

As in the case of arrays, the compiler allows the special case that we want to initialize the content at which the pointer with
constants at the same moment the pointer is declared:
In this case, memory space is reserved to contain "hello" and then a pointer to the first
char *word = "hello"; character of this memory block is assigned to word.

If we imagine that "hello" is stored at the memory locations that start at addresses 3568,
we can represent the previous declaration as:
It is important to indicate that word h e l l o \o
contains the value 3568, and not 'h' nor
"hello", although 3568 indeed is the 3568 3569 3570 3571 3572 3573
address of both of these.
word 3568
The pointer word points to a sequence of characters and can be read as if it was an array
-- remember that an array is just like a constant pointer --
*(word+4) Both expressions have a
We can access the fifth element of the array with any of these two expression:
word[4] value of 'o' (the fifth element
of the array).

Pointer arithmetics

To conduct arithmetical operations on pointers is a little different than to conduct them on regular integer data types.
Only addition and subtraction operations are allowed to be conducted with them.

Others make no sense in the world of pointers. But both addition and subtraction have a different behavior with pointers
according to the size of the data type to which they point

When we saw the different fundamental data types, we saw that some occupy more or less space than others in the memory.

For example, let's assume that in a given compiler for a specific machine, char takes 1 byte, short takes 2 bytes and long takes 4.

Suppose that we define three pointers : char *mychar; and that we know that they point to
short *myshort; memory locations 30, 120 and 180
long *mylong; respectively.

mychar++; mychar, would contain the value 31.


So if we write:
myshort++; myshort, would contain the value 122.
mylong++; mylong, would contain the value 184.

The reason is that when adding one to a pointer we are making it to point to the following element of the same type with which it
has been defined, and therefore the size in bytes of the type pointed is added to the pointer.
The following expression may lead to confusion: *p++

Because ++ has greater precedence than *, this expression is equivalent to *(p++).


Therefore, what it does is to increase the value of p (so it now points to the next element), but because ++ is used as
postfix the whole expression is evaluated as the value pointed by the original reference (the address the pointer pointed to
before being increased).

Notice the difference with: (*p)++

Here, the expression would have been evaluated as the value pointed by p increased by one. The value of p (the pointer
itself) would not be modified (what is being modified is what it is being pointed to by this pointer).

If we write: *p++ = *q++;

Because ++ has a higher precedence than *, both p and q are increased, but because both increase operators (++) are
used as postfix and not prefix, the value assigned to *p is *q before both p and q are increased. And then both are
increased.

It would be roughly equivalent to: *p = *q;++p;++q;

I recommend you to use parentheses () in order to avoid unexpected results and to give more legibility to the code.

Pointers to pointers
C++ allows the use of pointers that point to pointers, that these, in its turn, point to data (or even to other pointers).

In order to do that, we only need to add an asterisk (*) for each level of reference in their declarations: char a;
char * b;
char ** c;
a = 'z';
b = &a;
c = &b;
This, supposing the randomly chosen memory locations for each variable of 260, 5646 and 124543, could be represented as:

a b c
The value of each variable is written inside each cell; under
‘z’ 260 5646
the cells are their respective addresses in memory.
260 5646 124543

The new thing in this example is variable c, which can be used in three different levels of indirection, each one of them
would correspond to a different value:

• c has type char** and a value of 5646


• *c has type char* and a value of 260
• **c has type char and a value of 'z'

void pointers
The void type of pointer is a special type of pointer.

In C++, void represents the absence of type, so void pointers are pointers that point to a value that has no type (and thus
also an undetermined length and undetermined dereference properties).

This allows void pointers to point to any data type, from an integer value or a float to a string of characters.
But in exchange they have a great limitation: the data pointed by them cannot be directly dereferenced (which is logical, since
we have no type to dereference to), and for that reason we will always have to cast the address in the void pointer to some
other pointer type that points to a concrete data type before dereferencing it.
#include <iostream>
using namespace std; sizeof is an operator integrated in the C++ language that
void increase (void* data, int psize) returns the size in bytes of its parameter.
{ For non-dynamic data types this value is a constant.
if ( psize == sizeof(char) )
{ char* pchar; pchar=(char*)data; ++(*pchar); }
Example, sizeof(char) is 1, because char type is one byte long.
else if (psize == sizeof(int) )
{ int* pint; pint=(int*)data; ++(*pint); }
}
int main ()
{
char a = 'x';
int b = 1602;
increase (&a,sizeof(a));
increase (&b,sizeof(b));
cout << a << ", " << b << endl;
return 0;
}

Null pointer

A null pointer is a regular pointer of any pointer type which has a special value that indicates that it is not pointing to any valid
reference or memory address. This value is the result of type-casting the integer value zero to any pointer type.

int * p;
p = 0; // p has a null pointer value

Do not confuse null pointers with void pointers. A null pointer is a value that any pointer may take to represent that it is pointing
to "nowhere", while a void pointer is a special type of pointer that can point to somewhere without a specific type. One refers to
the value stored in the pointer itself and the other to the type of data it points to.
Pointers to functions

C++ allows operations with pointers to functions. The typical use of this is for passing a function as an argument to another
function, since these cannot be passed dereferenced. In order to declare a pointer to a function we have to declare it like the
prototype of the function except that the name of the function is enclosed between parentheses () and an asterisk (*) is inserted
before the name:

#include <iostream> In the example, minus is a pointer to a function that has two
using namespace std; parameters of type int. It is immediately assigned to point to
int addition (int a, int b) the function subtraction, all in a single line:
{ return (a+b); }
int (* minus)(int,int) = subtraction;
int subtraction (int a, int b)
{ return (a-b); }
int operation (int x, int y, int (*functocall)(int,int))
{
int g;
g = (*functocall)(x,y);
return (g);
}
int main ()
{
int m,n;
int (*minus)(int,int) = subtraction;
m = operation (7, 5, addition);
n = operation (20, m, minus);
cout <<n;
return 0;
}
Classes

Classes extend the built-in capabilities of C++ to assist you in representing and solving complex, real-world
problems.

You've already learned about a number of variable types:


integers
doubles
characters

For example, if you declare nr and mynr to be integers, you know that each one can hold a number between -32,768 and
32,767, assuming an integer is two bytes. That is the meaning of saying they are integers; trying to hold anything else in
these variables causes an error.

Just by declaring these variables to be integers, you know that it is possible to add nr to mynr and to assign that number to
another number.

The type of these variables tells you:


Their size in memory.
What information they can hold.
What actions can be performed on them.
More generally, a type is a category. Familiar types include car, house, person, fruit, and shape.

In C++, the programmer can create any type needed, and each of these new types can have all the functionality and

power of the built-in types.

You make a new type by declaring a class. A class is just a collection of variables - often of different types-combined with a
set of related functions.

One way to think about a car is as a collection of wheels, doors, seats, windows, and so forth. Another way is to think about
what a car can do: It can move, speed up, slow down, stop, park, and so on. A class enables you to encapsulate, or bundle,
these various parts and various functions into one collection, which is called an object.

Classes are generally declared using the keyword class, with the following format:

class class_name
{
access_specifier_1:
member1;
access_specifier_2:
member2;
...
}
object_names;
-class_name is a valid identifier for the class,

-object_names is an optional list of names for objects of this class. The body of the declaration can contain members,
that can be either data or function declarations, and optionally access specifiers.

An object is an instantiation of a class. In terms of variables, a class would be the type, and an object would be the
variable

An access specifies is one of the following three keywords: private, public or protected. These specifiers modify the access
rights that the members following them acquire:

• private members of a class are accessible only from within other members of the same class or from their friends.
• protected members are accessible from members of their same class and from their friends, but also from members of
their derived classes.
• public members are accessible from anywhere where the object is visible.

By default, all members of a class declared with the class keyword have private access for all its members. Therefore,

any member that is declared before one other class specifier automatically has private access.

Declares a class (i.e., a type) called Rectangle and an object (i.e., a variable) of this
class Rectangle
{ class called rect. This class contains four members: two data members of type int
int x, y; (member x and member y) with private access (because private is the default access
public:
void set_values (int,int); level) and two member functions with public access: set_values() and area(), of which
int area (void);
for now we have only included their declaration, not their definition.
}
rect;
int a; int is the type name (the class) and a is the variable name (the object).

After the previous declarations of Rectangle and rect, we can refer within the body of the program to any of the public
members of the object rect as if they were normal functions or normal variables, just by putting the object's name followed by

a dot (.) and then the name of the member. rect.set_values (3,4); The only members of rect that we cannot access

myarea = rect.area(); from the body of our program outside the class
are x and y, since they have private access and
they can only be referred from within other

#include <iostream> members of that same class.


using namespace std;
class Rectangle
{ The most important new thing in this code is the operator of scope (::, two
int x, y; colons) included in the definition of set_values(). It is used to define a
public:
member of a class from outside the class definition itself.
void set_values (int,int);
int area ()
{ return (x*y); } The definition of the member function area() has been included directly
}; within the definition of the Rectangle class given its extreme simplicity,
void Rectangle::set_values (int a, int b)
{ whereas set_values() has only its prototype declared within the class, but its
x = a; definition is outside it. In this outside declaration, we must use the operator
y = b; of scope (::) to specify that we are defining a function that is a member of
}
int main () { the class Rectangle and not a regular global function.
Rectangle rect;
rect.set_values (3,4);
cout << "area: " << rect.area(); The scope operator (::) specifies the class to which the member being
return 0; declared belongs, granting exactly the same scope properties as if this
}
function definition was directly included within the class definition.
#include <iostream>
using namespace std;
class Rectangle {
int x, y; One of the greater advantages of a class is that, as any other type,
public: we can declare several objects of it.
void set_values (int,int);
int area () {return (x*y);} For example, following with the previous example of class
}; Rectangle, we could have declared the object rectb in addition to the
void Rectangle::set_values (int a, int b) {
x = a; object rect:
y = b;
} In this concrete case, the class (type of the objects) to which we are
int main () { talking about is Rectangle, of which there are two instances or
Rectangle rect, rectb;
rect.set_values (3,4); objects: rect and rectb.
rectb.set_values (5,6);
cout << "rect area: " << rect.area() << endl;
cout << "rectb area: " << rectb.area() << endl;
return 0;
}

Notice that the call to rect.area() does not give the same result as the call to rectb.area(). This is because each object of class
Rectangle has its own variables x and y, as they, in some way, have also their own function members set_value() and area()
that each uses its object's own variables to operate.

That is the basic concept of object-oriented programming: Data and functions are both members of the object. We no longer use
sets of global variables that we pass from one function to another as parameters, but instead we handle objects that have their
own data and functions embedded as members. Notice that we have not had to give any parameters in any of the calls to rect.area
or rectb.area. Those member functions directly used the data members of their respective objects rect and rectb.
Constructors and destructors
what would happen if in the previous example we called the member function area() before having called function

set_values()?

- we would have an undetermined result since the members x and y would have never been assigned a value.

In order to avoid that, a class can include a special function called constructor, which is automatically called whenever a new
object of this class is created.

This constructor function must have the same name as the class, and cannot have any return type; not even void.

#include <iostream> The result of this example is identical to the previous one. But now
using namespace std; we have removed the member function set_values(), and have
class Rectangle {
int width, height; included instead a constructor that performs a similar action: it
public: initializes the values of width and height with the parameters that are
Rectangle (int,int);
passed to it.
int area () {return (width*height);}
}; Notice how these arguments are passed to the constructor at the
Rectangle::Rectangle (int a, int b) {
width = a; moment at which the objects of this class are created:
height = b; Rectangle rect (3,4);
}
int main () { Rectangle rectb (5,6);
Rectangle rect (3,4);
Rectangle rectb (5,6); Constructors cannot be called explicitly as if they were regular
cout << "rect area: " << rect.area() << endl; member functions. They are only executed when a new object of
cout << "rectb area: " << rectb.area() << endl;
that class is created.
return 0;
}
The destructor fulfills the opposite functionality. It is automatically called when an object is destroyed, either because its scope
of existence has finished (for example, if it was defined as a local object within a function and the function ends) or because it is
an object dynamically assigned and it is released using the operator delete.

The destructor must have the same name as the class, but preceded with a tilde sign (~) and it must also return no value.

The use of destructors is especially suitable when an object


#include <iostream> assigns dynamic memory during its lifetime and at the
using namespace std;
moment of being destroyed we want to release the memory
class Rectangle {
int *width, *height; that the object was allocated.
public:
Rectangle (int,int);
~Rectangle ();
int area () {return (*width * *height);}
};
Rectangle::Rectangle (int a, int b) {
width = new int;
height = new int;
*width = a;
*height = b;
}
Rectangle::~Rectangle () {
delete width;
delete height;
}
int main () {
CRectangle rect (3,4), rectb (5,6);
cout << "rect area: " << rect.area() << endl;
cout << "rectb area: " << rectb.area() << endl;
return 0;

Das könnte Ihnen auch gefallen