[go: up one dir, main page]

0% found this document useful (0 votes)
20 views52 pages

Dca - 104 - C++

The document provides an introduction to C++, highlighting its advantages as a compiled language, including conciseness, maintainability, and portability. It outlines the compilation process, the structure of a basic 'Hello, world!' program, and explains key concepts such as tokens, variables, and input/output operations. Additionally, it discusses debugging, emphasizing the distinction between compilation and runtime errors.

Uploaded by

Mithun N
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views52 pages

Dca - 104 - C++

The document provides an introduction to C++, highlighting its advantages as a compiled language, including conciseness, maintainability, and portability. It outlines the compilation process, the structure of a basic 'Hello, world!' program, and explains key concepts such as tokens, variables, and input/output operations. Additionally, it discusses debugging, emphasizing the distinction between compilation and runtime errors.

Uploaded by

Mithun N
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 52

C++ 1

Introduction

1 Compiled Languages and C++

1.1 Why Use a Language Like C++?

At its core, a computer is just a processor with some memory, capable of running tiny
instructions like “store 5 in memory location 23459.” Why would we express a program as
a text file in a programming language, instead of writing processor instructions?
The advantages:
1. Conciseness: programming languages allow us to express common sequences of com
mands more concisely. C++ provides some especially powerful shorthands.
2. Maintainability: modifying code is easier when it entails just a few text edits, instead
of rearranging hundreds of processor instructions. C++ is object oriented (more on
that in Lectures 7-8), which further improves maintainability.
3. Portability: different processors make different instructions available. Programs writ
ten as text can be translated into instructions for many different processors; one of
C++’s strengths is that it can be used to write programs for nearly any processor.

C++ is a high-level language: when you write a program in it, the shorthands are sufficiently
expressive that you don’t need to worry about the details of processor instructions. C++ does
give access to some lower-level functionality than other languages (e.g. memory addresses).

1.2 The Compilation Process


A program goes from text files (or source files) to processor instructions as follows:

Co m piler
Object File
Link er OS

Librari es
Co m piler Object File
C++ 2

Object files are intermediate files that represent an incomplete copy of the program: each
source file only expresses a piece of the program, so when it is compiled into an object file,
the object file has some markers indicating which missing pieces it depends on. The linker
takes those object files and the compiled libraries of predefined code that they rely on, fills
in all the gaps, and spits out the final program, which can then be run by the operating
system (OS).

The compiler and linker are just regular programs. The step in the compilation process in
which the compiler reads the file is called parsing.

In C++, all these steps are performed ahead of time, before you start running a program.
In some languages, they are done during the execution process, which takes time. This is
one of the reasons C++ code runs far faster than code in many more recent languages.
C++ actually adds an extra step to the compilation process: the code is run through a
preprocessor, which applies some modifications to the source code, before being fed to the
compiler. Thus, the modified diagram is:

Pre proce sso r Processed Code Compiler


Source File Object File
Linker Exe cut able OS
Program in Me mory
Libraries
Pre proce sso r Compiler
Source File Processed Code
Object File
C++ 3

1.3 General Notes on C++

C++ is immensely popular, particularly for applications that require speed and/or
access to some low-level features. It was created in 1979 by Bjarne Stroustrup, at first
as a set of extensions to the C programming language. C++ extends C; our first few
lectures willbasically be on the C parts of the language.
Though you can write graphical programs in C++, it is much hairier and less portable than
text-based (console) programs. We will be sticking to console programs in this course.
Everything in C++ is case sensitive: someName is not the same as SomeName.

2 Hello World
In the tradition of programmers everywhere, we’ll use a “Hello, world!” program as an
entrypoint into the basic features of C++.

1 // A He llo W or ld pr ogra m
2 # include < iostrea m >
4 3 int m ain () {
5 std :: cout << " Hello , w or ld !\ n" ;
6
7 return 0;
8 }

2.1 Tokens

Tokens are the minimals chunk of program that have meaning to the compiler – the
smallest meaningful symbols in the language. Our code displays all 6 kinds of tokens,
though the usual use of operators is not present here:

Token type Description/Purpose Examples


Keywords Words with special meaning to int, double, for, auto
the compiler
Identifiers Names of things that are not cout, std, x, myFunction
built into the language
Literals Basic constant values whose "Hello, world!", 24.3,
value is specified directly in 0, ’c’
the source code
Operators Mathematical or logical oper +, -, &&, %, <<
ations
Punctuation/Separators Punctuation defining the { } ( ) , ;
structure of a program
Whitespace Spaces of various sorts; ig Spaces, tabs, newlines, com
nored by the compiler ments
C++ 4

2.2 Line-By-Line Explanation

1. // indicates that everything following it until the end of the line is a comment: it is
ignored by the compiler. Another way to write a comment is to put it between /*
and
*/ (e.g. x = 1 + /*sneaky comment here*/ 1;). A comment of this form may
span multiple lines. Comments exist to explain non-obvious things going on in the
code. Use them: document your code well!
2. Lines beginning with # are preprocessor commands, which usually change what
code is actually being compiled. #include tells the preprocessor to dump in the
contents of another file, here the iostream file, which defines the procedures for
input/output.
4. int main() {...} defines the code that should execute when the program starts
up. The curly braces represent grouping of multiple commands into a block. More
about this syntax in the next few lectures.

5. • cout << : This is the syntax for outputting some piece of text to the screen.
We’ll discuss how it works in Lecture 9.
• Namespaces: In C++, identifiers can be defined within a context – sort of a
directory of names – called a namespace. When we want to access an
identifier defined in a namespace, we tell the compiler to look for it in that
namespace using the scope resolution operator (::). Here, we’re telling the
compiler to look for cout in the std namespace, in which many standard C++
identifiers are defined.
A cleaner alternative is to add the following line below line 2:
us ing na m e s pa ce std ;

This line tells the compiler that it should look in the std namespace for any
identifier we haven’t defined. If we do this, we can omit the std:: prefix when
writing cout. This is the recommended practice.
• Strings: A sequence of characters such as Hello, world is known as a string.
A string that is specified explicitly in a program is a string literal.
• Escape sequences: The \n indicates a newline character. It is an example of an
escape sequence – a symbol used to represent a special character in a text
literal. Here are all the C++ escape sequences which you can include in
strings:

Escape Sequence Represented Character


\a System bell (beep sound)
\b Backspace
\f Formfeed (page break)
\n Newline (line break)
\r “Carriage return” (returns cursor to start of line)
C++ 5

\t Tab
\\ Backslash
\’ Single quote character
\" Double quote character
\some integer x The character represented by x
7. return 0 indicates that the program should tell the operating system it has
completed successfully. This syntax will be explained in the context of functions; for
now, just include it as the last line in the main block.
Note that every statement ends with a semicolon (except preprocessor commands and blocks
using {}). Forgetting these semicolons is a common mistake among new C++
programmers.

3 Basic Language Features


So far our program doesn’t do very much. Let’s tweak it in various ways to demonstrate
some more interesting constructs.

3.1 Values and Statements

First, a few definitions:


• A statement is a unit of code that does something – a basic building block of a program.
• An expression is a statement that has a value – for instance, a number, a string,
thesum of two numbers, etc. 4 + 2, x - 1, and "Hello, world!\n" are all
expressions.
Not every statement is an expression. It makes no sense to talk about the value of an
#include statement, for instance.

3.2 Operators

We can perform arithmetic calculations with operators. Operators act on expressions to


form a new expression. For example, we could replace "Hello, world!\n" with (4 +
2) / 3, which would cause the program to print the number 2. In this case, the +
operator acts on the expressions 4 and 2 (its operands).
Operator types:
• Mathematical: +, -, *, /, and parentheses have their usual mathematical
meanings, including using - for negation. % (the modulus operator) takes the
remainder of two numbers: 6 % 5 evaluates to 1.
• Logical: used for “and,” “or,” and so on. More on those in the next lecture.
• Bitwise: used to manipulate the binary representations of numbers. We will not
C++ 6

focuson these.

3.3 Data Types

Every expression has a type – a formal description of what kind of data its value is. For
instance, 0 is an integer, 3.142 is a floating-point (decimal) number, and "Hello,
world!\n"
is a string value (a sequence of characters). Data of different types take a different
amountsof memory to store. Here are the built-in datatypes we will use most often:

Type Names Description Size Range


char Single text character or small 1 byte signed: -128 to 127
integer. Indicated with single unsigned: 0 to 255
quotes (’a’, ’3’).
int Larger integer. 4 bytes signed: -2147483648 to
2147483647
unsigned: 0 to 4294967295
bool Boolean (true/false). Indi 1 byte Just true (1) or false (0).
cated with the keywords true
and false.
double “Doubly” precise floating 8 bytes +/- 1.7e +/- 308 ( 15 digits)
point number.
Notes on this table:
• A signed integer is one that can represent a negative number; an unsigned integer will
never be interpreted as negative, so it can represent a wider range of positive numbers.
Most compilers assume signed if unspecified.
• There are actually 3 integer types: short, int, and long, in non-decreasing order
of size (int is usually a synonym for one of the other two). You generally don’t
need to worry about which kind to use unless you’re worried about memory usage
or you’re using really huge numbers. The same goes for the 3 floating point types,
float, double, and long double, which are in non-decreasing order of precision
(there is usually some imprecision in representing real numbers on a computer).
• The sizes/ranges for each type are not fully standardized; those shown above are
the ones used on most 32-bit computers.
An operation can only be performed on compatible types. You can add 34 and 3, but you
can’t take the remainder of an integer and a floating-point number.
An operator also normally produces a value of the same type as its operands; thus, 1 / 4
evaluates to 0 because with two integer operands, / truncates the result to an integer. To
get 0.25, you’d need to write something like 1 / 4.0.
A text string, for reasons we will learn in Lecture 5, has the type char *.
4 Variables
C++ 7

We might want to give a value a name so we can refer to it later. We do this using
variables.A variable is a named location in memory.
For example, say we wanted to use the value 4 + 2 multiple times. We might call it x and
use it as follows:
1 # include < iostrea m >
2 us ing na m e s pa ce s td ;
3
4 int m ain () {
5 int x ;
6 x = 4 + 2;
7 cout << x / 3 << ’ ’ << x * 2;
8
9 return 0;
10 }

(Note how we can print a sequence of values by “chaining” the << symbol.)
The name of a variable is an identifier token. Identifiers may contain numbers, letters,
and underscores (_), and may not start with a number.
Line 5 is the declaration of the variable x. We must tell the compiler what type x will be
so that it knows how much memory to reserve for it and what kinds of operations may be
performed on it.
Line 6 is the initialization of x, where we specify an initial value for it. This introduces a
new operator: =, the assignment operator. We can also change the value of x later on in
thecode using this operator.
We could replace lines 5 and 6 with a single statement that does both declaration and
initialization:
int x = 4 + 2;

This form of declaration/initialization is cleaner, so it is to be preferred.

5 Input
Now that we know how to give names to values, we can have the user of the program input
values. This is demonstrated in line 6 below:
1 # include < iostrea m >
2 us ing na m e s pa ce s td ;
3
4 int m ain () {
5 int x ;
6 cin > > x ;
7
8 cout << x / 3 << ’ ’ << x * 2;
9
C++ 8

10 return 0;
11 }

Just as cout << is the syntax for outputting values, cin >> (line 6) is the syntax for
inputting values.
Memory trick: if you have trouble remembering which way the angle brackets go for cout
and cin, think of them as arrows pointing in the direction of data flow. cin represents
the terminal, with data flowing from it to your variables; cout likewise represents the
terminal, and your data flows to it.

6 Debugging
There are two kinds of errors you’ll run into when writing C++ programs: compilation
errors and runtime errors. Compilation errors are problems raised by the compiler,
generally resulting from violations of the syntax rules or misuse of types. These are often
caused by typos and the like. Runtime errors are problems that you only spot when you
run the program: you did specify a legal program, but it doesn’t do what you wanted it to.
These are usually more tricky to catch, since the compiler won’t tell you about them.
1 using namespace std ;
2 int main () {
3 int x ;
4 cin >> x ;
5 cout << x / 3 << ’ ’ << x * 2;
6 return 0;
7 }
Just as cout << is the syntax for outputting values, cin >> (line 6) is the syntax for inputting

values.

Memory trick: if you have trouble remembering which way the angle brackets go for cout

and cin, think of them as arrows pointing in the direction of data flow. cin represents the

terminal, with data flowing from it to your variables; cout likewise represents the terminal,

and your data flows to it.

6 Debugging

There are two kinds of errors you’ll run into when writing C++ programs: compilation

errors and runtime errors. Compilation errors are problems raised by the compiler, generally

resulting from violations of the syntax rules or misuse of types. These are often caused by

typos and the like. Runtime errors are problems that you only spot when you run the

program: you did specify a legal program, but it doesn’t do what you wanted it to. These
C++ 9

are usually more tricky to catch, since the compiler won’t tell you about them.

Flow of Control

Normally, a program executes statements from first to last. The first statement is
executed, then the second, then the third, and so on, until the program reaches its end and
terminates. A computer program likely wouldn't be very useful if it ran the same sequence of
statements every time it was run. It would be nice to be able to change which statements ran and
when, depending on the circumstances. For example, if a program checks a file for the number of
times a certain word appears, it should be able to give the correct count no matter what file and
word are given to it. Or, a computer game should move the player's character around when the
player wants. We need to be able to alter the order in which a program's statementsare executed,
the control flow.

1 Control Structures
Control structures are portions of program code that contain statements within them and,
depending on the circumstances, execute these statements in a certain way. There are typically
two kinds: conditionals and loops.

1.1 Conditionals
In order for a program to change its behavior depending on the input, there must a way to testthat
input. Conditionals allow the program to check the values of variables and to execute (or not execute)
certain statements. C++ has if and switch-case conditional structures.

1.1.1 Operators
Conditionals use two kinds of special operators: relational and logical. These are used todetermine
whether some condition is true or false.

The relational operators are used to test a relation between two expressions:
C++ 10

Operator Meaning
> Greater than
>= Greater than or equal to
< Less than
<= Less than or equal to
== Equal to
!= Not equal to

They work the same as the arithmetic operators (e.g., a > b) but return a Boolean value of either
true or false, indicating whether the relation tested for holds. (An expression that returns this
kind of value is called a Boolean expression.) For example, if the variables x and yhave been set to 6
and 2, respectively, then x > y returns true. Similarly, x < 5 returns false.

The logical operators are often used to combine relational expressions into more complicatedBoolean
expressions:
Operator Meaning
&& and
|| or
! not

The operators return true or false, according to the rules of logic:

a b a && b
true true true
true false false
false true false
false false false

a b a || b
true true true
true false true
false true true
false false false

The ! operator is a unary operator, taking only one argument and negating its value:

a !a
true false
false true

Examples using logical operators (assume x = 6 and y = 2):


C++ 11

!(x > 2) → false


(x > y) && (y > 0) →
true (x < y) && (y > 0)
→ false (x < y) || (y >
0) → true

Of course, Boolean variables can be used directly in these expressions, since they hold true and
false values. In fact, any kind of value can be used in a Boolean expression due to a quirk C++ has:
false is represented by a value of 0 and anything that is not 0 is true. So, “Hello,
world!” is true, 2 is true, and any int variable holding a non-zero value is true. Thismeans !x
returns false and x && y returns true!

1.1.2 if, if-else and else if

The if conditional has the form:

if(condition)
{
Stmt1
stmt2

}
The condition is some expression whose value is being tested. If the condition resolves to a value of
true, then the statements are executed before the program continues on. Otherwise,the statements
are ignored. If there is only one statement, the curly braces may be omitted, giving the form:

if(condition)
statement

The if-else form is used to decide between two sequences of statements referred to as blocks:

if(condition)
{
statement
A1
statement
}
else A2
{ …

} statement
B1
statement
B2

If the condition is met, the block corresponding to the if is executed. Otherwise, the block
corresponding to the else is executed. Because the condition is either satisfied or not, one ofthe
blocks in an if-else must execute. If there is only one statement for any of the blocks, thecurly braces
C++ 12

for that block may be omitted:

if(condition)
statementA1
else
statementB1

The else if is used to decide between two or more blocks based on multiple conditions:

if(condition1)
{
statement
A1
statement
A2

}
else if(condition2)
{
statement
B1
statement
B2

}

If condition1 is met, the block corresponding to the if is executed. If not, then only if
condition2 is met is the block corresponding to the else if executed. There may be more
than one else if, each with its own condition. Once a block whose condition was met is executed,
any else ifs after it are ignored. Therefore, in an if-else-if structure, either one orno block is
executed.

An else may be added to the end of an if-else-if. If none of the previous conditions are met, the
else block is executed. In this structure, one of the blocks must execute, as in a normal if-else.

Here is an example using these control structures:

1 #include <iostream>
2 using namespace std;
3
4 int main() {
5 int x = 6;
6 int y = 2;
7
8 if(x > y)
9 cout << “x is greater than y\n”;
10 else if(y > x)
11 cout << “y is greater than x\n”;
12 else
13 cout << “x and y are equal\n”;
14
15 return 0;
16 }
C++ 13

The output of this program is x is greater than y. If we replace lines 5 and 6 with

int x = 2;
int y = 6;

then the output is y is greater than x. If we replace the lines with

int x = 2;
int y = 2;

then the output is x and y are equal.

1.1.3 switch-case
The switch-case is another conditional structure that may or may not execute certainstatements.
However, the switch-case has peculiar syntax and behavior:

switch(expression)
{
case constant1:
statement
A1
statement
A2
...
break;
case
constant2:
statement
B1
statement
B2
...
break;
...
default:
statement
Z1
statement
Z2
...
}

The switch evaluates expression and, if expression is equal to constant1, then the
statements beneath case constant 1: are executed until a break is encountered. If
expression is not equal to constant1, then it is compared to constant2. If these are
equal, then the statements beneath case constant 2: are executed until a break is
C++ 14

encountered. Ifnot, then the same process repeats for each of the constants, in turn. If none of the
constantsmatch, then the statements beneath default: are executed.

Due to the peculiar behavior of switch-cases, curly braces are not necessary for cases where
there is more than one statement (but they are necessary to enclose the entire switch-case).
switch-cases generally have if-else equivalents but can often be a cleaner way of
expressing the same behavior.

Here is an example using switch-case:

1 #include <iostream>
2 using namespace std;3
4 int main() {
5 int x = 6;
6
7 switch(x) {
8 case 1:
9 cout << “x is 1\n”;break;
10 case 2:
11
12 case 3:
13 cout << "x is 2 or 3";break;
14 default:
15
16 cout << "x is not 1, 2, or 3";
17 }
18
19 return 0;
20 }

This program will print x is not 1, 2, or 3. If we replace line 5 with int x = 2; then
theprogram will print x is 2 or 3.

1.2 Loops
Conditionals execute certain statements if certain conditions are met; loops execute certain
statements while certain conditions are met. C++ has three kinds of loops: while, do-while,and for.
1.2.1 while and do-while
The while loop has a form similar to the if conditional:

while(condition)
{
statemen
t1
statemen
t2

}
C++ 15

As long as condition holds, the block of statements will be repeatedly executed. If there is onlyone
statement, the curly braces may be omitted. Here is an example:

1 #include <iostream>
2 using namespace std;
3 int main() {
4 int x = 0;
5 while(x
<10)
6 x = x + 1;
7 cout<<”x
is
“<<x<<”\n”;
8 return 0;
9 }

This program will print x is 10.

The do-while loop is a variation that guarantees the block of statements will be executed atleast once:

do
{
statemen
t1
statemen
t2

}
while(condition);

The block of statements is executed and then, if the condition holds, the program returns to the
top of the block. Curly braces are always required. Also note the semicolon after the while
condition.

1.2.2 for

The for loop works like the while loop but with some change in syntax:

for(initialization; condition; incrementation)


{
statemen
t1
statemen
t2

}
C++ 16

The for loop is designed to allow a counter variable that is initialized at the beginning of theloop and
incremented (or decremented) on each iteration of the loop. Curly braces may be omitted if there is
only one statement. Here is an example:

1 #include <iostream>
2 using namespace std;3
4 int main() {
5
6 for(int x = 0; x < 10; x =
x + 1) 7 cout << x << “\n”;
8
9 return
0; 10 }

This program will print out the values 0 through 9, each on its own line.

If the counter variable is already defined, there is no need to define a new one in theinitialization
portion of the for loop. Therefore, it is valid to have the following:
1 #include <iostream>
2 using namespace std;3
4 int main() {
5
6 int x = 0;
7 for(; x < 10; x = x +
1) 8 cout << x <<
“\n”; 9
10 return 0; 11
}

Note that the first semicolon inside the for loop's parentheses is still required.

A for loop can be expressed as a while loop and vice-versa. Recalling that a for loop has theform

for(initialization; condition; incrementation)


{
statemen
t1
statemen
t2

}

we can write an equivalent while loop as

initialization
while(condition)
{
statemen
C++ 17

t1
statemen
t2

incrementati
on
}

Using our example above,

1 #include <iostream>
2 using namespace std;3
4 int main() {
5
6 for(int x = 0; x < 10; x =
x + 1) 7 cout << x << “\n”;
8
9 return
0; 10 }

is converted to

1 #include <iostream>
2 using namespace std;
3
4 int main() {
5
6 int x = 0;
7 while(x < 10) {
8 cout << x << “\n”;
9 x = x + 1;
10 }
11
12 return 0;
13 }
The incrementation step can technically be anywhere inside the statement block, but it is good
practice to place it as the last step, particularly if the previous statements use the current value of the
counter variable.

1.3 Nested Control Structures


It is possible to place ifs inside of ifs and loops inside of loops by simply placing these structures inside
the statement blocks. This allows for more complicated program behavior.

Here is an example using nesting if conditionals:

1 #include <iostream>
2 using namespace std;3
C++ 18

4 int main() {
5 int x = 6;
6 int y = 0;7
8 if(x > y) {
9 cout << “x is greater than y\n”;
10 if(x == 6)
11 cout << “x is equal to 6\n”;
12 else
13 cout << “x is not equalt to 6\n”;
14 } else
15 cout << “x is not greater than y\n”;16
17 return
0; 18 }

This program will print x is greater than y on one line and then x is equal to 6 on
thenext line.

Here is an example using nested loops:

1 #include <iostream>
2 using namespace std;3
4 int main() {
5 for(int x = 0; x < 4; x = x + 1) {
6 for(int y = 0; y < 4; y = y + 1)
7 cout << y;
8 cout <<
“\n”; 9 }
10
11 return
0; 12 }

This program will print four lines of 0123.


C++ 19

Functions
A function is a group of statements that together perform a task. Every C++ program has at
least one function, which is main(), and all the most trivial programs can define additional
functions.
You can divide up your code into separate functions. How you divide up your code among
different functions is up to you, but logically the division usually is such that each function
performs a specific task.
A function declaration tells the compiler about a function's name, return type, and parameters.
A function definition provides the actual body of the function.
The C++ standard library provides numerous built-in functions that your program can call. For
example, function strcat() to concatenate two strings, function memcpy() to copy one memory
location to another location and many more functions.
A function is known with various names like a method or a sub-routine or a procedure etc.

Defining a Function
The general form of a C++ function definition is as follows −
return_type function_name( parameter list ) {
body of the function
}
A C++ function definition consists of a function header and a function body. Here are all the
parts of a function −
 Return Type − A function may return a value. The return_type is the data type of the
value the function returns. Some functions perform the desired operations without
returning a value. In this case, the return_type is the keyword void.
 Function Name − This is the actual name of the function. The function name and the
parameter list together constitute the function signature.
 Parameters − A parameter is like a placeholder. When a function is invoked, you pass a
value to the parameter. This value is referred to as actual parameter or argument. The
parameter list refers to the type, order, and number of the parameters of a function.
Parameters are optional; that is, a function may contain no parameters.
 Function Body − The function body contains a collection of statements that define what
the function does.
Example
Following is the source code for a function called max(). This function takes two parameters
num1 and num2 and return the biggest of both −
// function returning the max between two numbers

int max(int num1, int num2) {


C++ 20

// local variable declaration


int result;

if (num1 > num2)


result = num1;
else
result = num2;

return result;
}
Function Declarations
A function declaration tells the compiler about a function name and how to call the function.
The actual body of the function can be defined separately.
A function declaration has the following parts −
return_type function_name( parameter list );
For the above defined function max(), following is the function declaration −
int max(int num1, int num2);
Parameter names are not important in function declaration only their type is required, so
following is also valid declaration −
int max(int, int);
Function declaration is required when you define a function in one source file and you call that
function in another file. In such case, you should declare the function at the top of the file
calling the function.

Calling a Function
While creating a C++ function, you give a definition of what the function has to do. To use a
function, you will have to call or invoke that function.
When a program calls a function, program control is transferred to the called function. A called
function performs defined task and when it’s return statement is executed or when its function-
ending closing brace is reached, it returns program control back to the main program.
To call a function, you simply need to pass the required parameters along with function name,
and if function returns a value, then you can store returned value. For example −
Live Demo

#include <iostream>
using namespace std;

// function declaration
int max(int num1, int num2);

int main () {
C++ 21

// local variable declaration:


int a = 100;
int b = 200;
int ret;

// calling a function to get max value.


ret = max(a, b);
cout << "Max value is : " << ret << endl;

return 0;
}

// function returning the max between two numbers


int max(int num1, int num2) {
// local variable declaration
int result;

if (num1 > num2)


result = num1;
else
result = num2;

return result;
}
I kept max() function along with main() function and compiled the source code. While running
final executable, it would produce the following result −
Max value is : 200
Function Arguments
If a function is to use arguments, it must declare variables that accept the values of the
arguments. These variables are called the formal parameters of the function.
The formal parameters behave like other local variables inside the function and are created
upon entry into the function and destroyed upon exit.
While calling a function, there are two ways that arguments can be passed to a function −

Sl.No Call Type & Description

1 Call by Value

This method copies the actual value of an argument into the formal
parameter of the function. In this case, changes made to the parameter
inside the function have no effect on the argument.
C++ 22

2 Call by Pointer

This method copies the address of an argument into the formal


parameter. Inside the function, the address is used to access the actual
argument used in the call. This means that changes made to the
parameter affect the argument.

3 Call by Reference

This method copies the reference of an argument into the formal


parameter. Inside the function, the reference is used to access the actual
argument used in the call. This means that changes made to the
parameter affect the argument.

By default, C++ uses call by value to pass arguments. In general, this means that code within
a function cannot alter the arguments used to call the function and above mentioned example
while calling max() function used the same method.

Default Values for Parameters


When you define a function, you can specify a default value for each of the last parameters.
This value will be used if the corresponding argument is left blank when calling to the function.
This is done by using the assignment operator and assigning values for the arguments in the
function definition. If a value for that parameter is not passed when the function is called, the
default given value is used, but if a value is specified, this default value is ignored and the
passed value is used instead. Consider the following example −
Live Demo

#include <iostream>
using namespace std;

int sum(int a, int b = 20) {


int result;
result = a + b;

return (result);
}
int main () {
// local variable declaration:
int a = 100;
int b = 200;
int result;

// calling a function to add the values.


result = sum(a, b);
cout << "Total value is :" << result << endl;
C++ 23

// calling a function again as follows.


result = sum(a);
cout << "Total value is :" << result << endl;

return 0;
}
When the above code is compiled and executed, it produces the following result −
Total value is :300
Total value is :120

Constructor

Characteristics of constructor functions

 Constructors are invoked automatically when we create objects.


 Constructors should be declared in the public section of the Class.
 Constructors cannot return values to the calling program because they do not
have return types.
 Constructors should always be non-virtual. They are static functions and in
C++ so they cannot be virtual.
 Constructors cannot be inherited because they are called when objects of the
class are created. It is therefore not realistic to create a base class object using
the derived class constructor function.
 We cannot refer to the addresses of constructors since we only require the
address of a function to call it and they can never be called directly. Also, the
language does not permit it.
C++ 24

NOTE: Whenever a Constructor is declared, initialization of the class objects


becomes imperative.

Types of constructors
1. Default constructors

These are constructors that do not pass or accept any parameters. The default
constructor for a class C is C::C(). The compiler supplies a default constructor for
instances where it is not defined.

Therefore a statement such as integer v1 invokes the default constructor of the


compiler to create the object v1.

Example of default constructor


// c++ program to illustrate the concept of constructors

#include <iostream>
using namespace std;

class integer
{
public:
int x, y;

// Default Constructor declared


integer()
{
x = 45;
y = 10;
}
};

int main()
{
// Default constructor called automatically when the object is
created
integer a;
cout << "x: " << a.x << endl << "y: " << a.y;
return 0;
C++ 25

In the program above, the compiler will automatically provide a default constructor
implicitly.

Our program output will be:


x: 45
y: 10

2. Parameterized constructors

In practice, we may be required to initialize the data elements of different objects


with different values. C++ enables us to accomplish this by the use of
parameterized constructors that can take parameters when the objects are created

In the program below we are going to illustrate how our constructor integer() will
be used.
// C++ program to illustrate parameterized constructors

#include <iostream>
using namespace std;

class integer
{
private:
int a, b;
public:
// Parameterized Constructor
integer(int x, int y)
{
a = x;
b = y;
};

int getX()
{
return a;
};

int getY()
C++ 26

{
return b;
};
};
int main()
{
integer v(10, 15); // Constructor called

cout << "a = " << v.getX() << endl; // values assigned by
constructor accessed
cout<< "b = " << v.getY() << endl;

return 0;
}

The output is: a = 10 b = 15

Initial values have to be passed to the object through parameterized constructors


and the normal declaration of a statement will not work. We can pass the initial
values as arguments by either calling the constructor implicitly or explicitly.

For example our declaration above, can be declared implicitly as:


integer v(10,15); // implicit call

This statement passes the values 10 and 15 to our integer object v.

We can also pass our values explicitly as follows:


integer v=integer(10,15); // Explicit call

However, the first method is preferred to the second because it’s shorter and easier
to apply.

NOTE: The arguments of a constructor function cannot be the type of the class to
which it belongs to.

For instance:
C++ 27

class v {
public:
v(v);
}; //is illegal.

3. Copy constructors

When we discussed parameterized constructors, we mentioned that the parameters


of a constructor function cannot be the type of the class to which it belongs.

However, constructors can accept a reference to its class as a parameter. Copy


constructors initialize an object using another object that is of the same class.

In C++, copy constructors are called using the cases below:

1. Whenever objects of the class are returned by value.


2. Whenever objects are constructed based on another object that is of the same
class.
3. Whenever objects are passed as parameters.

We are required to define our copy constructor functions particularly if an object


has runtime allocation of resources or pointers.

Example of a copy constructor


// C++ program to illustrate copy constructor

class integer
{
int a ,b;
public:
integer (integer &v) // copy constructor declared
{
a=v.a;
b=v.b;
};
};
C++ 28

4. Multiple constructors

C++ allows us to use the three constructor functions we have discussed in the same
class.

For example:
class complex
{
int a, b;
public:
complex() // default constructor
{
a= 10;
b=45;
};
complex( int x, int y) // parameterized constructor
{
a=x;
b=y;
};
complex( complex & v) // copy constructor
{
a=v.a;
b=v.b;
};
};

 The first constructor function has no values passed by the calling program
therefore the constructor assigns itself the data values.
 The second constructor function has parameters in which the function call
passes the appropriate values from the main function.
 The third constructor function receives objects as arguments. Copy
constructors set the values of the first data element to the value of the
corresponding.

Constructor overloading
C++ 29

This is where more than one constructor function is defined in a class. Overloaded
constructors have the same name as the class but with a different number of
arguments.

They are based on the number and type of parameters passed to the calling function.
The compiler will know which constructor requires to be called depending on the
arguments passed when the object is created.
// C++ program to illustrate Constructor overloading

#include <iostream>
using namespace std;

class shape
{
int a, b;
public:
// Constructor with no argument
shape()
{
a= 2;
b= 3;
}; // constructor with one argument
shape(int x)
{
a=b=x;
}; // Constructor with two arguments
shape(int x, int y)
{
a= x;
b= y;
};
int area(void)
{
return(a*b);
};
void display()
{
cout<<"area="<< area() <<endl;
};
};
int main()
{// ConstructorOverloading two different constructors of class name
shape s;
C++ 30

shape s2(6);
shape s3( 3, 2);

s.display();
s.display();
s.display();
return 0;
}

The output is: area=6 area=6 area=6

Object-Oriented Programming (OOP) and Inheritance


1 The Basic Ideas of OOP
Classic “procedural” programming languages before C++ (such as C) often focused on the
question “What should the program do next?” The way you structure a program in these
languages is:
1. Split it up into a set of tasks and subtasks
2. Make functions for the tasks
3. Instruct the computer to perform them in sequence
With large amounts of data and/or large numbers of tasks, this makes for complex and
unmaintainable programs.
Consider the task of modeling the operation of a car. Such a program would have lots of
separate variables storing information on various car parts, and there’d be no way to group
together all the code that relates to, say, the wheels. It’s hard to keep all these variables
and the connections between all the functions in mind.
To manage this complexity, it’s nicer to package up self-sufficient, modular pieces of code.
People think of the world in terms of interacting objects: we’d talk about interactions between
the steering wheel, the pedals, the wheels, etc. OOP allows programmers to pack away details
into neat, self-contained boxes (objects) so that they can think of the objects more abstractly
and focus on the interactions between them.
There are lots of definitions for OOP, but 3 primary features of it are:
• Encapsulation: grouping related data and functions together as objects and defining
an interface to those objects
C++ 31

• Inheritance: allowing code to be reused between related types


• Polymorphism: allowing a value to be one of several types, and determining at
runtime which functions to call on it based on its type
C++ 32

2 Encapsulation
Encapsulation just refers to packaging related stuff together. We’ve already seen how to
package up data and the operations it supports in C++: with classes.
If someone hands us a class, we do not need to know how it actually works to use it; all we
need to know about is its public methods/data – its interface. This is often compared to
operating a car: when you drive, you don’t care how the steering wheel makes the wheels
turn; you just care that the interface the car presents (the steering wheel) allows you to
accomplish your goal. If you remember the analogy from Lecture 6 about objects being
boxes with buttons you can push, you can also think of the interface of a class as the set
of buttons each instance of that class makes available. Interfaces abstract away the details
of how all the operations are actually performed, allowing the programmer to focus on how
objects will use each other’s interfaces – how they interact.
This is why C++ makes you specify public and private access specifiers: by default, it
assumes that the things you define in a class are internal details which someone using your
code should not have to worry about. The practice of hiding away these details from client
code is called “data hiding,” or making your class a “black box.”
One way to think about what happens in an object-oriented program is that we define what
objects exist and what each one knows, and then the objects send messages to each other
(by calling each other’s methods) to exchange information and tell each other what to do.

3 Inheritance
Inheritance allows us to define hierarchies of related classes.
Imagine we’re writing an inventory program for vehicles, including cars and trucks. We could
write one class for representing cars and an unrelated one for representing trucks, but we’d
have to duplicate the functionality that all vehicles have in common. Instead, C++ allows
us to specify the common code in a Vehicle class, and then specify that the Car and Truck
classes share this code.
The Vehicle class will be much the same as what we’ve seen before:
1 cla ss Ve hicle {
2 protected :
3 s tr ing lice ns e ;
4 int ye ar ;

2
C++ 33

5
6 public :
7 Vehicle ( cons t s tr ing & m yLicense , const int m yYe ar )
8 : lice ns e ( m yL ice ns e ) , yea r ( m yYe ar ) {}
9 const s tr ing ge tD es c () const
10 { r e tur n lice nse + " fr om " + s tr i ngify ( year ) ;}
11 const s tr ing & ge tL ice ns e () cons t { r e tur n lice nse ;}
12 const int ge tYea r () const { r e tur n ye ar ;}
13 };

A few notes on this code, by line:


2. The standard string class is described in Section 1 of PS3; see there for details. Recall
that strings can be appended to each other with the + operator.
3. protected is largely equivalent to private. We’ll discuss the differences shortly.
8. This line demonstrates member initializer syntax. When defining a constructor, you
sometimes want to initialize certain members, particularly const members, even before
the constructor body. You simply put a colon before the function body, followed by a
comma-separated list of items of the form dataMember(initialValue).
10. This line assumes the existence of some function stringify for converting numbers to
strings.
Now we want to specify that Car will inherit the Vehicle code, but with some additions.
This is accomplished in line 1 below:
1 cla ss Ca r : public Ve hicle { // M akes Ca r inhe r it fr om Ve hicle
2 s tr ing style ;
3
4 public :
5 Car ( const str ing & m yLice nse , cons t int myYe ar , const s tr ing
& m yS tyle )
6 : Ve hicle ( m yL icense , m yYe ar ) , s tyle ( m yS tyle ) {}
7 const s tr ing & ge tS ty le () { re turn style ;}
8 };

Now class Car has all the data members and methods of Vehicle, as well as a style data
member and a getStyle method.
Class Car inherits from class Vehicle. This is equivalent to saying that Car is a derived
class, while Vehicle is its base class. You may also hear the terms subclass and superclass
instead.

Notes on the code:


C++ 34

1. Don’t worry for now about why we stuck the public keyword in there.
Note how we use member initializer syntax to call the base-class constructor. We need to
have a complete Vehicle object constructed before we construct the components
added in the Car. If you do not explicitly call a base-class constructor using this syntax,
the default base-class constructor will be called.
Similarly, we could make a Truck class that inherits from Vehicle and shares its code. This
would give a class hierarchy like the following:

Vehicle

Truck Car

Class hierarchies are generally drawn with arrows pointing from derived classes to base
classes.

3.1 Is-a vs. Has-a

There are two ways we could describe some class A as depending on some other class B:
1. Every A object has a B object. For instance, every Vehicle has a string object (called
license).
2. Every instance of A is a B instance. For instance, every Car is a Vehicle, as well.
Inheritance allows us to define “is-a” relationships, but it should not be used to implement
“has-a” relationships. It would be a design error to make Vehicle inherit from string
because every Vehicle has a license; a Vehicle is not a string. “Has-a” relationships
should be implemented by declaring data members, not by inheritance.
3.2 Overriding Methods
We might want to generate the description for Cars in a different way from generic Vehicles.
To accomplish this, we can simply redefine the getDesc method in Car, as below. Then,
when we call getDesc on a Car object, it will use the redefined function. Redefining in this
manner is called overriding the function.
1 cla ss Ca r : Vehicle { // Ma kes Car inhe r it from Vehicle
2 public s tr ing
3 style ;
C++ 35

4 public :
5 Car ( const str ing & m yLice nse , cons t int myYe ar , const s tr ing
& m yS tyle )
6 : Ve hicle ( m yL icense , m yYe ar ) , s tyle ( m yS tyle ) {}
7 const s tr ing ge tD es c () // Ove r r i d ing this me m ber functi on
8 { r e tur n s tr ingify ( ye ar ) + ’ ’ + s tyle + ": " + lice ns e
;}
9 const s tr ing & ge tS ty le () { re turn style ;}
10 };

3.2.1 Programming by Difference

In defining derived classes, we only need to specify what’s different about them from their
base classes. This powerful technique is called programming by difference.
Inheritance allows only overriding methods and adding new members and methods. We
cannot remove functionality that was present in the base class.

3.3 Access Modifiers and Inheritance

If we’d declared year and license as private in Vehicle, we wouldn’t be able to access
them even from a derived class like Car. To allow derived classes but not outside code to
access data members and member functions, we must declare them as protected.
The public keyword used in specifying a base class (e.g., class Car : public Vehicle
{...}) gives a limit for the visibility of the inherited methods in the derived class. Normally
you should just use public here, which means that inherited methods declared as public
are still public in the derived class. Specifying protected would make inherited methods,
even those declared public, have at most protected visibility. For a full table of the effects
of different inheritance access specifiers, see
http://en.wikibooks.org/wiki/C++ Programming/Classes/Inheritance.

4 Polymorphism
Polymorphism means “many shapes.” It refers to the ability of one object to have many
types. If we have a function that expects a Vehicle object, we can safely pass it a Car
object, because every Car is also a Vehicle. Likewise for references and pointers: anywhere
you can use a Vehicle *, you can use a Car *.

4.1 virtual Functions


C++ 36

There is still a problem. Take the following example:


1 Car c(" VAN ITY " , 2003) ;
2 Vehicle * vPtr = & c;
3 cout << vPtr - > getDesc () ;

(The -> notation on line 3 just dereferences and gets a member. ptr->member is equivalent
to (*ptr).member.)
Because vPtr is declared as a Vehicle *, this will call the Vehicle version of getDesc, even
though the object pointed to is actually a Car. Usually we’d want the program to select the
correct function at runtime based on which kind of object is pointed to. We can get this
behavior by adding the keyword virtual before the method definition:
1 cla ss Ve hicle {
2 ...
3 virtua l const s tr ing ge tD es c () {... }
4 };

With this definition, the code above would correctly select the Car version of getDesc.
Selecting the correct function at runtime is called dynamic dispatch. This matches the whole
OOP idea – we’re sending a message to the object and letting it figure out for itself what
actions that message actually means it should take.
Because references are implicitly using pointers, the same issues apply to references:
1 Car c(" VAN ITY " , 2003) ;
2 Vehicle & v = c;
3 cout << v. getDesc () ;

This will only call the Car version of getDesc if getDesc is declared as virtual.
Once a method is declared virtual in some class C, it is virtual in every derived class of C,
even if not explicitly declared as such. However, it is a good idea to declare it as virtual
in the derived classes anyway for clarity.

4.2 Pure virtual Functions

Arguably, there is no reasonable way to define getDesc for a generic Vehicle – only derived
classes really need a definition of it, since there is no such thing as a generic vehicle that
isn’t also a car, truck, or the like. Still, we do want to require every derived class of Vehicle
to have this function.
37
C++

We can omit the definition of getDesc from Vehicle by making the function pure virtual
via the following odd syntax:
1 cla ss Ve hicle {
2 ...
3 virtua l const s tr ing ge tD es c () = 0; // Pure vir tua l
4 };

The = 0 indicates that no definition will be given. This implies that one can no longer create an
instance of Vehicle; one can only create instances of Cars, Trucks, and other derived classes
which do implement the getDesc method. Vehicle is then an abstract class – one which
defines only an interface, but doesn’t actually implement it, and therefore cannot be
instantiated.

5 Multiple Inheritance
Unlike many object-oriented languages, C++ allows a class to have multiple base classes:
1 cla ss Ca r : public Vehicle , public Ins ur e d Ite m {
2 ...
3 };

This specifies that Car should have all the members of both the Vehicle and the InsuredItem
classes.
Multiple inheritance is tricky and potentially dangerous:
• If both Vehicle and InsuredItem define a member x, you must remember to disam-
biguate which one you’re referring to by saying Vehicle::x or InsuredItem::x.
• If both Vehicle and InsuredItem inherited from the same base class, you’d end up
with two instances of the base class within each Car (a “dreaded diamond” class hier­
archy). There are ways to solve this problem, but it can get messy.
In general, avoid multiple inheritance unless you know exactly what you’re doing.
38
C++

Arrays
In this tutorial, we will learn to work with arrays. We will learn to declare, initialize, and
access array elements in C++ programming with the help of examples.

In C++, an array is a variable that can store multiple values of the same type. For
example,

Suppose a class has 27 students, and we need to store the grades of all of them.
Instead of creating 27 separate variables, we can simply create an array:

double grade[27];

Here, grade is an array that can hold a maximum of 27 elements of double type.
In C++, the size and type of arrays cannot be changed after its declaration.

C++ Array Declaration

dataType arrayName[arraySize];

For example,

int x[6];

Here,

 int - type of element to be stored


 x - name of the array
 6 - size of the array
39
C++

Access Elements in C++ Array

In C++, each element in an array is associated with a number. The number is known as
an array index. We can access elements of an array by using those indices.

// syntax to access array elements


array[index];

Consider the array x we have seen above.

Elements of an array in
C++

Few Things to Remember:

 The array indices start with 0 . Meaning x[0] is the first element stored at index 0 .
 If the size of an array is n , the last element is stored at index (n-1) . In this
example, x[5] is the last element.
 Elements of an array have consecutive addresses. For example, suppose the starting
address of x[0] is 2120.

Then, the address of the next element x[1] will be 2124, the address of x[2] will
be 2128, and so on.

Here, the size of each element is increased by 4. This is because the size of int is 4
bytes.

C++ Array Initialization


40
C++

In C++, it's possible to initialize an array during declaration. For example,

// declare and initialize and array


int x[6] = {19, 10, 8, 17, 9, 15};

C++ Array elements and


their data

Another method to initialize array during declaration:

// declare and initialize an array


int x[] = {19, 10, 8, 17, 9, 15};

Here, we have not mentioned the size of the array. In such cases, the compiler
automatically computes the size.

C++ Array With Empty Members

In C++, if an array has a size n , we can store upto n number of elements in the array.
However, what will happen if we store less than n number of elements.
For example,

// store only 3 elements in the array


int x[6] = {19, 10, 8};

Here, the array x has a size of 6 . However, we have initialized it with only 3 elements.
In such cases, the compiler assigns random values to the remaining places.
Oftentimes, this random value is simply 0 .
41
C++

Empty array members are


automatically assigned the value 0

How to insert and print array elements?

int mark[5] = {19, 10, 8, 17, 9}

// change 4th element to 9


mark[3] = 9;

// take input from the user


// store the value at third position
cin >> mark[2];

// take input from the user


// insert at ith position
cin >> mark[i-1];

// print first element of the array


cout << mark[0];

// print ith element of the array


cout >> mark[i-1];

Example 1: Displaying Array Elements


#include <iostream>
42
C++

using namespace std;

int main() {

int numbers[5] = {7, 5, 6, 12, 35};

cout << "The numbers are: ";

// Printing array elements


// using range based for loop
for (const int &n : numbers) {
cout << n << " ";
}

cout << "\nThe numbers are: ";

// Printing array elements


// using traditional for loop
for (int i = 0; i < 5; ++i) {
cout << numbers[i] << " ";
}

return 0;
}
Run Code

Output

The numbers are: 7 5 6 12 35


The numbers are: 7 5 6 12 35

Here, we have used a for loop to iterate from i = 0 to i = 4. In each iteration, we have
printed numbers[i] .

We again used a range-based for loop to print out the elements of the array. To learn
more about this loop, check C++ Ranged for Loop.
Note: In our range-based loop, we have used the code const int &n instead of int n as
the range declaration. However, the const int &n is more preferred because:
1. Using int n simply copies the array elements to the variable n during each iteration.
This is not memory-efficient.

&n , however, uses the memory address of the array elements to access their data
without copying them to a new variable. This is memory-efficient.
43
C++

2. We are simply printing the array elements, not modifying them. Therefore, we
use const so as not to accidentally change the values of the array.

Example 2: Take Inputs from User and Store Them in an Array


#include <iostream>
using namespace std;

int main() {

int numbers[5];

cout << "Enter 5 numbers: " << endl;

// store input from user to array


for (int i = 0; i < 5; ++i) {
cin >> numbers[i];
}

cout << "The numbers are: ";

// print array elements


for (int n = 0; n < 5; ++n) {
cout << numbers[n] << " ";
}

return 0;
}
Run Code

Output

Enter 5 numbers:
11
12
13
14
15
The numbers are: 11 12 13 14 15
44
C++

Once again, we have used a for loop to iterate from i = 0 to i = 4. In each iteration, we
took an input from the user and stored it in numbers[i] .

Then, we used another for loop to print all the array elements.

Example 3: Display Sum and Average of Array Elements Using for Loop
#include <iostream>
using namespace std;

int main() {

// initialize an array without specifying size


double numbers[] = {7, 5, 6, 12, 35, 27};

double sum = 0;
double count = 0;
double average;

cout << "The numbers are: ";

// print array elements


// use of range-based for loop
for (const double &n : numbers) {
cout << n << " ";

// calculate the sum


sum += n;

// count the no. of array elements


++count;
}

// print the sum


cout << "\nTheir Sum = " << sum << endl;

// find the average


average = sum / count;
cout << "Their Average = " << average << endl;

return 0;
}
45
C++
Run Code

Output

The numbers are: 7 5 6 12 35 27


Their Sum = 92
Their Average = 15.3333

In this program:

1. We have initialized a double array named numbers but without specifying its size. We also
declared three double variables sum , count , and average .

Here, sum =0 and count = 0 .

2. Then we used a range-based for loop to print the array elements. In each iteration of
the loop, we add the current array element to sum .

3. We also increase the value of count by 1 in each iteration, so that we can get the size of
the array by the end of the for loop.
4. After printing all the elements, we print the sum and the average of all the numbers.
The average of the numbers is given by average = sum / count;

Note: We used a ranged for loop instead of a normal for loop.


A normal for loop requires us to specify the number of iterations, which is given by the
size of the array.
But a ranged for loop does not require such specifications.

C++ Array Out of Bounds

If we declare an array of size 10, then the array will contain elements from index 0 to 9.
However, if we try to access the element at index 10 or more than 10, it will result in
Undefined Behaviour.
46
C++

Pointers
In this tutorial, we will learn about pointers in C++ and their working with the help of
examples.

In C++, pointers are variables that store the memory addresses of other variables.

Address in C++

If we have a variable var in our program, &var will give us its address in the memory.
For example,
Example 1: Printing Variable Addresses in C++
#include <iostream>
using namespace std;

int main()
{
// declare variables
int var1 = 3;
int var2 = 24;
int var3 = 17;

// print address of var1


cout << "Address of var1: "<< &var1 << endl;

// print address of var2


cout << "Address of var2: " << &var2 << endl;

// print address of var3


cout << "Address of var3: " << &var3 << endl;
}
Run Code

Output

Address of var1: 0x7fff5fbff8ac


Address of var2: 0x7fff5fbff8a8
Address of var3: 0x7fff5fbff8a4
47
C++

Here, 0x at the beginning represents the address is in the hexadecimal form.


Notice that the first address differs from the second by 4 bytes and the second address
differs from the third by 4 bytes.

This is because the size of an int variable is 4 bytes in a 64-bit system.

Note: You may not get the same results when you run the program.

C++ Pointers

As mentioned above, pointers are used to store addresses rather than values.

Here is how we can declare pointers.

int *pointVar;

Here, we have declared a pointer pointVar of the int type.


We can also declare pointers in the following way.

int* pointVar; // preferred syntax

Let's take another example of declaring pointers.

int* pointVar, p;

Here, we have declared a pointer pointVar and a normal variable p .

Note: The * operator is used after the data type to declare pointers.
48
C++

Assigning Addresses to Pointers

Here is how we can assign addresses to pointers:

int* pointVar, var;


var = 5;

// assign address of var to pointVar pointer


pointVar = &var;

Here, 5 is assigned to the variable var . And, the address of var is assigned to
the pointVar pointer with the code pointVar = &var .

Get the Value from the Address Using Pointers

To get the value pointed by a pointer, we use the * operator. For example:

int* pointVar, var;


var = 5;

// assign address of var to pointVar


pointVar = &var;

// access value pointed by pointVar


cout << *pointVar << endl; // Output: 5

In the above code, the address of var is assigned to pointVar . We have used
the *pointVar to get the value stored in that address.
When * is used with pointers, it's called the dereference operator. It operates on a
pointer and gives the value pointed by the address stored in the pointer. That
is, *pointVar = var .

Note: In C++, pointVar and *pointVar is completely different. We cannot do something


like *pointVar = &var;
49
C++

Example 2: Working of C++ Pointers


#include <iostream>
using namespace std;
int main() {
int var = 5;

// declare pointer variable


int* pointVar;

// store address of var


pointVar = &var;

// print value of var


cout << "var = " << var << endl;

// print address of var


cout << "Address of var (&var) = " << &var << endl
<< endl;

// print pointer pointVar


cout << "pointVar = " << pointVar << endl;

// print the content of the address pointVar points to


cout << "Content of the address pointed to by pointVar (*pointVar) = " << *pointVar <<
endl;

return 0;
}
Run Code

Output

var = 5
Address of var (&var) = 0x61ff08

pointVar = 0x61ff08
Content of the address pointed to by pointVar (*pointVar) = 5
50
C++

Working of C++ pointers

Changing Value Pointed by Pointers

If pointVar points to the address of var , we can change the value of var by
using *pointVar .

For example,

int var = 5;
int* pointVar;

// assign address of var


pointVar = &var;

// change value at address pointVar


*pointVar = 1;

cout << var << endl; // Output: 1

Here, pointVar and &var have the same address, the value of var will also be changed
when *pointVar is changed.
51
C++

Example 3: Changing Value Pointed by Pointers


#include <iostream>
using namespace std;
int main() {
int var = 5;
int* pointVar;

// store address of var


pointVar = &var;

// print var
cout << "var = " << var << endl;

// print *pointVar
cout << "*pointVar = " << *pointVar << endl
<< endl;

cout << "Changing value of var to 7:" << endl;

// change value of var to 7


var = 7;

// print var
cout << "var = " << var << endl;

// print *pointVar
cout << "*pointVar = " << *pointVar << endl
<< endl;

cout << "Changing value of *pointVar to 16:" << endl;

// change value of var to 16


*pointVar = 16;

// print var
cout << "var = " << var << endl;

// print *pointVar
cout << "*pointVar = " << *pointVar << endl;
return 0;
}
Run Code

Output

var = 5
52
C++

*pointVar = 5

Changing value of var to 7:


var = 7
*pointVar = 7

Changing value of *pointVar to 16:


var = 16
*pointVar = 16

Common mistakes when working with pointers

Suppose, we want a pointer varPoint to point to the address of var . Then,

int var, *varPoint;

// Wrong!
// varPoint is an address but var is not
varPoint = var;

// Wrong!
// &var is an address
// *varPoint is the value stored in &var
*varPoint = &var;

// Correct!
// varPoint is an address and so is &var
varPoint = &var;

// Correct!
// both *varPoint and var are values
*varPoint = var;

You might also like