You are on page 1of 27

Page 1 of 27

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, !! pro"ides control structures that ser"e to specify #hat has to be done by our program, #hen and under #hich circumstances. $ith the introduction of control structures #e are going to ha"e to introduce a ne# concept% the compound-statement or block. A block is a group of statements #hich are separated by semicolons &'( like all !! statements, but grouped together in a block enclosed in braces% { }% { statement1; statement2; statement3; } )ost of the control structures that #e #ill see in this section require a generic statement as part of its synta*. A statement can be either a simple statement &a simple instruction ending #ith a semicolon( or a compound statement &se"eral instructions grouped in a block(, like the one +ust described. ,n the case that #e #ant the statement to be a simple statement, #e do not need to enclose it in braces &{}(. -ut in the case that #e #ant the statement to be a compound statement it must be enclosed bet#een braces &{}(, forming a block. Conditional structure: if and else .he if key#ord is used to e*ecute a statement or block only if a condition is fulfilled. ,ts form is% if (condition) statement $here condition is the e*pression that is being e"aluated. ,f this condition is true, statement is e*ecuted. ,f it is false, statement is ignored &not e*ecuted( and the program continues right after this conditional structure. For e*ample, the follo#ing code fragment prints x is 100 only if the "alue stored in the x "ariable is indeed 100% if (x == 100) cout << "x is 100"; ,f #e #ant more than a single statement to be e*ecuted in case that the condition is true #e can specify a block using braces { }% if (x == 100) { cout << "x is "; cout << x; } $e can additionally specify #hat #e #ant to happen if the condition is not fulfilled by using the key#ord else. ,ts form used in con+unction #ith if is% if (condition) statement1 else statement2 For e*ample% if (x == 100) cout << "x is 100"; else cout << "x is not 100"; prints on the screen x is 100 if indeed x has a "alue of 100, but if it has not /and only if not/ it prints out x is not

Page 2 of 27

100. .he if + else structures can be concatenated #ith the intention of "erifying a range of "alues. .he follo#ing e*ample sho#s its use telling if the "alue currently stored in x is positi"e, negati"e or none of them &i.e. 0ero(% if (x > 0) cout << "x else if (x < cout << "x else cout << "x is positive"; 0) is ne ative"; is 0";

1emember that in case that #e #ant more than a single statement to be e*ecuted, #e must group them in a block by enclosing them in braces { }. Iteration structures (loops)

2oops ha"e as purpose to repeat a statement a certain number of times or #hile a condition is fulfilled. The while loop ,ts format is% !"ile (exp#ession) statement and its functionality is simply to repeat statement #hile the condition set in e*pression is true. For e*ample, #e are going to make a program to countdo#n using a #hile/loop% $$ custom countdo!n usin %include <iost#eam> usin namespace std; int main () { int n; cout << "&nte# t"e sta#tin cin >> n; !"ile (n>0) { cout << n << "( "; ))n; } cout << "*+,&-.n"; #etu#n 0; !"ile

num'e# > ";

&nte# t"e sta#tin num'e# > / /( 0( 1( 2( 3( 3( 2( 1( *+,&-

$hen the program starts the user is prompted to insert a starting number for the countdo#n. .hen the !"ile loop begins, if the "alue entered by the user fulfills the condition n>0 &that n is greater than 0ero( the block that follo#s the condition #ill be e*ecuted and repeated #hile the condition &n>0( remains being true. .he #hole process of the pre"ious program can be interpreted according to the follo#ing script &beginning in main(%

1. 3ser assigns a "alue to n

Page 4 of 27

2. .he #hile condition is checked &n>0(. At this point there are t#o posibilities% 4.
5 condition is true% statement is e*ecuted &to step 4( 5 condition is false% ignore statement and continue after it &to step 6( 7*ecute statement% cout << n << "( "; ))n; &prints the "alue of n on the screen and decreases n by 1( 7nd of block. 1eturn automatically to step 2 ontinue the program right after the block% print F,179 and end program.

8. 6.

$hen creating a #hile/loop, #e must al#ays consider that it has to end at some point, therefore #e must pro"ide #ithin the block some method to force the condition to become false at some point, other#ise the loop #ill continue looping fore"er. ,n this case #e ha"e included ))n; that decreases the "alue of the "ariable that is being e"aluated in the condition &n( by one / this #ill e"entually make the condition &n>0( to become false after a certain number of loop iterations% to be more specific, #hen n becomes 0, that is #here our #hile/loop and our countdo#n end. :f course this is such a simple action for our computer that the #hole countdo#n is performed instantly #ithout any practical delay bet#een numbers. The do-while loop

,ts format is% do statement !"ile (condition); ,ts functionality is e*actly the same as the #hile loop, e*cept that condition in the do/#hile loop is e"aluated after the e*ecution of statement instead of before, granting at least one e*ecution of statement e"en if condition is ne"er fulfilled. For e*ample, the follo#ing e*ample program echoes any number you enter until you enter 0. $$ num'e# ec"oe# %include <iost#eam> usin namespace std; int main () { unsi ned lon n; do { cout << "&nte# num'e# (0 to end)4 "; cin >> n; cout << "5ou ente#ed4 " << n << ".n"; } !"ile (n -= 0); #etu#n 0; } &nte# num'e# 5ou ente#ed4 &nte# num'e# 5ou ente#ed4 &nte# num'e# 5ou ente#ed4 (0 to end)4 12332 12332 (0 to end)4 110200 110200 (0 to end)4 0 0

.he do/#hile loop is usually used #hen the condition that has to determine the end of the loop is determined #ithin the loop statement itself, like in the pre"ious case, #here the user input #ithin the block is #hat is used to determine if the loop has to end. ,n fact if you ne"er enter the "alue 0 in the pre"ious e*ample you can be prompted for more numbers fore"er. The for loop

,ts format is%

Page 8 of 27

fo# (initiali6ation; condition; inc#ease) statement; and its main function is to repeat statement #hile condition remains true, like the #hile loop. -ut in addition, the fo# loop pro"ides specific locations to contain an initiali6ation statement and an inc#ease statement. ;o this loop is specially designed to perform a repetiti"e action #ith a counter #hich is initiali0ed and increased on each iteration. ,t #orks in the follo#ing #ay%

1. initiali6ation is e*ecuted. <enerally it is an initial "alue setting for a counter "ariable. .his is e*ecuted only 2. 4. 8.
once. condition is checked. ,f it is true the loop continues, other#ise the loop ends and statement is skipped &not e*ecuted(. statement is e*ecuted. As usual, it can be either a single statement or a block enclosed in braces { }. finally, #hate"er is specified in the inc#ease field is e*ecuted and the loop gets back to step 2.

=ere is an e*ample of countdo#n using a for loop% $$ countdo!n usin a fo# loop %include <iost#eam> usin namespace std; int main () { fo# (int n=10; n>0; n))) { 10( 7( /( 0( 1( 2( 3( 3( 2( 1( *+,&cout << n << "( "; } cout << "*+,&-.n"; #etu#n 0; } .he initiali6ation and inc#ease fields are optional. .hey can remain empty, but in all cases the semicolon signs bet#een them must be #ritten. For e*ample #e could #rite% fo# (;n<10;) if #e #anted to specify no initiali0ation and no increase' or fo# (;n<10;n++) if #e #anted to include an increase field but no initiali0ation &maybe because the "ariable #as already initiali0ed before(. :ptionally, using the comma operator &(( #e can specify more than one e*pression in any of the fields included in a fo# loop, like in initiali6ation, for e*ample. .he comma operator &(( is an e*pression separator, it ser"es to separate more than one e*pression #here only one is generally e*pected. For e*ample, suppose that #e #anted to initiali0e more than one "ariable in our loop% fo# ( n=0( i=100 ; n-=i ; n++( i)) ) { $$ !"ateve# "e#e888 } .his loop #ill e*ecute for 6> times if neither n or i are modified #ithin the loop%

n starts #ith a "alue of 0, and i #ith 100, the condition is n-=i &that n is not equal to i(. -ecause n is increased by one and i decreased by one, the loop?s condition #ill become false after the 6>th loop, #hen both n and i #ill be equal to 20.

Page 6 of 27

Jump statements.

The break statement

3sing '#ea9 #e can lea"e a loop e"en if the condition for its end is not fulfilled. ,t can be used to end an infinite loop, or to force it to end before its natural end. For e*ample, #e are going to stop the count do#n before its natural end &maybe because of an engine check failure@(% $$ '#ea9 loop example %include <iost#eam> usin namespace std; int main () { int n; fo# (n=10; n>0; n))) { 10( 7( /( 0( 1( 2( 3( 3( countdo!n a'o#tedcout << n << "( "; if (n==3) { cout << "countdo!n a'o#ted-"; '#ea9; } } #etu#n 0; } The continue statement

.he continue statement causes the program to skip the rest of the loop in the current iteration as if the end of the statement block had been reached, causing it to +ump to the start of the follo#ing iteration. For e*ample, #e are going to skip the number 6 in our countdo#n% $$ continue loop example %include <iost#eam> usin namespace std; int main () { fo# (int n=10; n>0; n))) { 10( 7( /( 0( 1( 3( 3( 2( 1( *+,&if (n==2) continue; cout << n << "( "; } cout << "*+,&-.n"; #etu#n 0; } The goto statement oto allo#s to make an absolute +ump to another point in the program. Aou should use this feature #ith caution since its e*ecution causes an unconditional +ump ignoring any type of nesting limitations. .he destination point is identified by a label, #hich is then used as an argument for the goto statement. A label is made of a "alid identifier follo#ed by a colon &4(.

Page B of 27

<enerally speaking, this instruction has no concrete use in structured or ob+ect oriented programming aside from those that lo#/le"el programming fans may find for it. For e*ample, here is our countdo#n loop using oto% $$ oto loop example

%include <iost#eam> usin namespace std; int main () { int n=10; 10( 7( /( 0( 1( 2( 3( 3( 2( 1( *+,&loop4 cout << n << "( "; n)); if (n>0) oto loop; cout << "*+,&-.n"; #etu#n 0; } The e it function

exit is a function defined in the cstdli' library. .he purpose of exit is to terminate the current program #ith a specific e*it code. ,ts prototype is% void exit (int exitcode); .he exitcode is used by some operating systems and may be used by calling programs. -y con"ention, an e*it code of 0 means that the program finished normally and any other "alue means that some error or une*pected results happened. The selecti!e structure: switch. .he synta* of the s#itch statement is a bit peculiar. ,ts ob+ecti"e is to check se"eral possible constant "alues for an e*pression. ;omething similar to #hat #e did at the beginning of this section #ith the concatenation of se"eral if and else if instructions. ,ts form is the follo#ing% s!itc" (exp#ession) { case constant14 #oup of statements 1; '#ea9; case constant24 #oup of statements 2; '#ea9; 8 8 8 default4 default #oup of statements } ,t #orks in the follo#ing #ay% s#itch e"aluates exp#ession and checks if it is equi"alent to constant1, if it is, it e*ecutes #oup of statements 1 until it finds the '#ea9 statement. $hen it finds this '#ea9 statement the program +umps to the end of the s!itc" selecti"e structure. ,f e*pression #as not equal to constant1 it #ill be checked against constant2. ,f it is equal to this, it #ill e*ecute

Page 7 of 27

#oup of statements 2 until a break key#ord is found, and then #ill +ump to the end of the s!itc" selecti"e structure. Finally, if the "alue of exp#ession did not match any of the pre"iously specified constants &you can include as many case labels as "alues you #ant to check(, the program #ill e*ecute the statements included after the default4 label, if it e*ists &since it is optional(. -oth of the follo#ing code fragments ha"e the same beha"ior% switch e ample if-else e"ui!alent s!itc" (x) { if (x == 1) { case 14 cout << "x is 1"; cout << "x is 1"; } '#ea9; else if (x == 2) { case 24 cout << "x is 2"; cout << "x is 2"; } '#ea9; else { default4 cout << "value of x un9no!n"; cout << "value of x un9no!n"; } } .he s!itc" statement is a bit peculiar #ithin the !! language because it uses labels instead of blocks. .his forces us to put '#ea9 statements after the group of statements that #e #ant to be e*ecuted for a specific condition. :ther#ise the remainder statements /including those corresponding to other labels/ #ill also be e*ecuted until the end of the s!itc" selecti"e block or a '#ea9 statement is reached. For e*ample, if #e did not include a '#ea9 statement after the first group for case one, the program #ill not automatically +ump to the end of the s!itc" selecti"e block and it #ould continue e*ecuting the rest of statements until it reaches either a '#ea9 instruction or the end of the s!itc" selecti"e block. .his makes unnecessary to include braces { } surrounding the statements for each of the cases, and it can also be useful to e*ecute the same block of instructions for different possible "alues for the e*pression being e"aluated. For e*ample% s!itc" (x) { case 14 case 24 case 34 cout << "x is 1( 2 o# 3"; '#ea9; default4 cout << "x is not 1( 2 no# 3"; } Cotice that s#itch can only be used to compare an e*pression against constants. .herefore #e cannot put "ariables as labels &for e*ample case n4 #here n is a "ariable( or ranges &case (1883)4( because they are not "alid !! constants. ,f you need to check ranges or "alues that are not constants, use a concatenation of if and else if statements.

#unctions (I) 3sing functions #e can structure our programs in a more modular #ay, accessing all the potential that structured programming can offer to us in !!. A function is a group of statements that is e*ecuted #hen it is called from some point of the program. .he follo#ing is its format% t:pe name ( pa#amete#1( pa#amete#2( 888) { statements }

Page D of 27

#here% t:pe is the data type specifier of the data returned by the function. name is the identifier by #hich it #ill be possible to call the function. pa#amete#s &as many as needed(% 7ach parameter consists of a data type specifier follo#ed by an identifier, like any regular "ariable declaration &for e*ample% int x( and #hich acts #ithin the function as a regular local "ariable. .hey allo# to pass arguments to the function #hen it is called. .he different parameters are separated by commas. statements is the function?s body. ,t is a block of statements surrounded by braces { }.

=ere you ha"e the first function e*ample% $$ function example %include <iost#eam> usin namespace std; int addition (int a( int ') { int #; #=a+'; #etu#n (#); } int main () { int 6; 6 = addition (2(3); cout << ";"e #esult is " << 6; #etu#n 0; } ,n order to e*amine this code, first of all remember something said at the beginning of this tutorial% a !! program al#ays begins its e*ecution by the main function. ;o #e #ill begin there. $e can see ho# the main function begins by declaring the "ariable 6 of type int. 1ight after that, #e see a call to a function called addition. Paying attention #e #ill be able to see the similarity bet#een the structure of the call to the function and the declaration of the function itself some code lines abo"e%

;"e #esult is /

.he parameters and arguments ha"e a clear correspondence. $ithin the main function #e called to addition passing t#o "alues% 2 and 3, that correspond to the int a and int ' parameters declared for function addition. At the point at #hich the function is called from #ithin main, the control is lost by main and passed to function addition. .he "alue of both arguments passed in the call &2 and 3( are copied to the local "ariables int a and int ' #ithin the function. Function addition declares another local "ariable &int #(, and by means of the e*pression #=a+', it assigns to # the result of a plus '. -ecause the actual parameters passed for a and ' are 2 and 3 respecti"ely, the result is /. .he follo#ing line of code% #etu#n (#);

Page E of 27

finali0es 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 follo#s it regular course from the same point at #hich it #as interrupted by the call to addition. -ut additionally, because the #etu#n statement in function addition specified a "alue% the content of "ariable # &#etu#n (#);(, #hich at that moment had a "alue of /. .his "alue becomes the "alue of e"aluating the function call.

;o being the "alue returned by a function the "alue gi"en to the function call itself #hen it is e"aluated, the "ariable 6 #ill be set to the "alue returned by addition (2( 3), that is /. .o e*plain it another #ay, you can imagine that the call to a function &addition (2(3)( is literally replaced by the "alue it returns &/(. .he follo#ing line of code in main is% cout << ";"e #esult is " << 6; .hat, as you may already e*pect, produces the printing of the result on the screen.

Page 1> of 27

Scope of !ariables

.he scope of "ariables declared #ithin a function or any other inner block is only their o#n function or their o#n block and cannot be used outside of them. For e*ample, in the pre"ious e*ample it #ould ha"e been impossible to use the "ariables a, ' or # directly in function main since they #ere "ariables local to function addition. Also, it #ould ha"e been impossible to use the "ariable 6 directly #ithin function addition, since this #as a "ariable local to the function main.

.herefore, the scope of local "ariables is limited to the same block le"el in #hich they are declared. Ce"ertheless, #e also ha"e the possibility to declare global "ariables' .hese are "isible from any point of the code, inside and outside all functions. ,n order to declare global "ariables you simply ha"e to declare the "ariable outside any function or block' that means, directly in the body of the program. And here is another e*ample about functions% $$ function example %include <iost#eam> usin namespace std; int su't#action (int a( int ') { int #; #=a)'; #etu#n (#); } int main () { int x=2( :=3( 6; 6 = su't#action (0(2); cout << ";"e fi#st #esult is " << 6 << <.n<; cout << ";"e second #esult is " << su't#action (0(2) << <.n<; cout << ";"e t"i#d #esult is " << su't#action (x(:) << <.n<; 6= 3 + su't#action (x(:); cout << ";"e fou#t" #esult is " << 6 << <.n<; #etu#n 0; }

;"e ;"e ;"e ;"e

fi#st #esult is 2 second #esult is 2 t"i#d #esult is 2 fou#t" #esult is 1

Page 11 of 27

,n this case #e ha"e created a function called su't#action. .he only thing that this function does is to subtract both passed parameters and to return the result. Ce"ertheless, if #e e*amine function main #e #ill see that #e ha"e made se"eral calls to function su't#action. $e ha"e used some different calling methods so that you see other #ays or moments #hen a function can be called. ,n order to fully understand these e*amples you must consider once again that a call to a function could be replaced by the "alue that the function call itself is going to return. For e*ample, the first case &that you should already kno# because it is the same pattern that #e ha"e used in pre"ious e*amples(% 6 = su't#action (0(2); cout << ";"e fi#st #esult is " << 6; ,f #e replace the function call by the "alue it returns &i.e., 2(, #e #ould ha"e% 6 = 2; cout << ";"e fi#st #esult is " << 6; As #ell as cout << ";"e second #esult is " << su't#action (0(2); has the same result as the pre"ious call, but in this case #e made the call to su't#action directly as an insertion parameter for cout. ;imply consider that the result is the same as if #e had #ritten% cout << ";"e second #esult is " << 2; since 2 is the "alue returned by su't#action (0(2). ,n the case of% cout << ";"e t"i#d #esult is " << su't#action (x(:); .he only ne# thing that #e introduced is that the parameters of su't#action are "ariables instead of constants. .hat is perfectly "alid. ,n this case the "alues passed to function su't#action are the "alues of x and :, that are 2 and 3 respecti"ely, gi"ing 2 as result. .he fourth case is more of the same. ;imply note that instead of% 6 = 3 + su't#action (x(:); #e could ha"e #ritten% 6 = su't#action (x(:) + 3; #ith e*actly the same result. , ha"e s#itched places so you can see that the semicolon sign &;( goes at the end of the #hole statement. ,t does not necessarily ha"e to go right after the function call. .he e*planation might be once again that you imagine that a function can be replaced by its returned "alue% 6 = 3 + 2;

Page 12 of 27

6 = 2 + 3;

#unctions with no t$pe. The use of !oid.

,f you remember the synta* of a function declaration% t:pe name ( a# ument1( a# ument2 888) statement you #ill see that the declaration begins #ith a t:pe, that is the type of the function itself &i.e., the type of the datum that #ill be returned by the function #ith the return statement(. -ut #hat if #e #ant to return no "alue@ ,magine that #e #ant to make a function +ust to sho# a message on the screen. $e do not need it to return any "alue. ,n this case #e should use the void type specifier for the function. .his is a special specifier that indicates absence of type. $$ void function example %include <iost#eam> usin namespace std; void p#intmessa e () { cout << "+<m a function-"; +<m a function} int main () { p#intmessa e (); #etu#n 0; } void can also be used in the function?s parameter list to e*plicitly specify that #e #ant the function to take no actual parameters #hen it is called. For e*ample, function p#intmessa e could ha"e been declared as% void p#intmessa e (void) { cout << "+<m a function-"; } Although it is optional to specify void in the parameter list. ,n !!, a parameter list can simply be left blank if #e #ant a function #ith no parameters. $hat you must al#ays remember is that the format for calling a function includes specifying its name and enclosing its parameters bet#een parentheses. .he non/e*istence of parameters does not e*empt us from the obligation to #rite the parentheses. For that reason the call to p#intmessa e is% p#intmessa e (); .he parentheses clearly indicate that this is a call to a function and not the name of a "ariable or some other !! statement. .he follo#ing call #ould ha"e been incorrect% p#intmessa e;

Page 14 of 27

#unctions (II)
%rguments passed b$ !alue and b$ reference.

3ntil no#, in all the functions #e ha"e seen, the arguments passed to the functions ha"e been passed by value. .his means that #hen calling a function #ith parameters, #hat #e ha"e passed to the function #ere copies of their "alues but ne"er the "ariables themsel"es. For e*ample, suppose that #e called our first function addition using the follo#ing code%
int x=2( :=3( 6; 6 = addition ( x ( : );

$hat #e did in this case #as to call to function addition passing the "alues of x and :, i.e. 2 and 3 respecti"ely, but not the "ariables x and : themsel"es.

.his #ay, #hen the function addition is called, the "alue of its local "ariables a and ' become 2 and 3 respecti"ely, but any modification to either a or ' #ithin the function addition #ill not ha"e any effect in the "alues of x and : outside it, because "ariables x and : #ere not themsel"es passed to the function, but only copies of their "alues at the moment the function #as called. -ut there might be some cases #here you need to manipulate from inside a function the "alue of an e*ternal "ariable. For that purpose #e can use arguments passed by reference, as in the function duplicate of the follo#ing e*ample%
$$ passin pa#amete#s ': #efe#ence %include <iost#eam> usin namespace std; void duplicate (int= a( int= '( int= c) { a>=2; '>=2; c>=2; } int main () { int x=1( :=3( 6=0; duplicate (x( :( 6); cout << "x=" << x << "( :=" << : << "( 6=" << 6; #etu#n 0; }

x=2( :=1( 6=13

.he first thing that should call your attention is that in the declaration of duplicate the type of each

Page 18 of 27

parameter #as follo#ed by an ampersand sign &=(. .his ampersand is #hat specifies that their corresponding arguments are to be passed by reference instead of by value. $hen a "ariable is passed by reference #e are not passing a copy of its "alue, but #e are someho# passing the "ariable itself to the function and any modification that #e do to the local "ariables #ill ha"e an effect in their counterpart "ariables passed as arguments in the call to the function.

.o e*plain it in another #ay, #e associate a, ' and c #ith the arguments passed on the function call &x, : and 6( and any change that #e do on a #ithin the function #ill affect the "alue of x outside it. Any change that #e do on ' #ill affect :, and the same #ith c and 6. .hat is #hy our program?s output, that sho#s the "alues stored in x, : and 6 after the call to duplicate, sho#s the "alues of all the three "ariables of main doubled. ,f #hen declaring the follo#ing function%
void duplicate (int= a( int= '( int= c)

#e had declared it this #ay%


void duplicate (int a( int '( int c)

i.e., #ithout the ampersand signs &=(, #e #ould ha"e not passed the "ariables by reference, but a copy of their "alues instead, and therefore, the output on screen of our program #ould ha"e been the "alues of x, : and 6 #ithout ha"ing been modified. Passing by reference is also an effecti"e #ay to allo# a function to return more than one "alue. For e*ample, here is a function that returns the pre"ious and ne*t numbers of the first parameter passed.
$$ mo#e t"an one #etu#nin %include <iost#eam> usin namespace std; value

void p#evnext (int x( int= p#ev( int= next) { p#ev = x)1; next = x+1; } int main () { int x=100( :( 6; p#evnext (x( :( 6); cout << "?#evious=" << : << "( @ext=" << 6; #etu#n 0; }

?#evious=77( @ext=101

Page 16 of 27

&efault !alues in parameters.


$hen declaring a function #e can specify a default "alue for each of the last parameters. .his "alue #ill be used if the corresponding argument is left blank #hen calling to the function. .o do that, #e simply ha"e to use the assignment operator and a "alue for the arguments in the function declaration. ,f a "alue for that parameter is not passed #hen the function is called, the default "alue is used, but if a "alue is specified this default "alue is ignored and the passed "alue is used instead. For e*ample%
$$ default values in functions %include <iost#eam> usin namespace std; int divide (int a( int '=2) { int #; #=a$'; #etu#n (#); } int main () { cout << divide (12); cout << endl; cout << divide (20(3); #etu#n 0; }

1 2

As #e can see in the body of the program there are t#o calls to function divide. ,n the first one%
divide (12)

#e ha"e only specified one argument, but the function divide allo#s up to t#o. ;o the function divide has assumed that the second parameter is 2 since that is #hat #e ha"e specified to happen if this parameter #as not passed &notice the function declaration, #hich finishes #ith int '=2, not +ust int '(. .herefore the result of this function call is 1 &12$2(. ,n the second call%
divide (20(3)

there are t#o parameters, so the default "alue for ' &int '=2( is ignored and ' takes the "alue passed as argument, that is 3, making the result returned equal to 2 &20$3(.

'!erloaded functions.
,n !! t#o different functions can ha"e the same name if their parameter types or number are different. .hat means that you can gi"e the same name to more than one function if they ha"e either a different number of parameters or different types in their parameters. For e*ample%
$$ ove#loaded function %include <iost#eam> usin namespace std; 10 282

Page 1B of 27

int ope#ate (int a( int ') { #etu#n (a>'); } float ope#ate (float a( float ') { #etu#n (a$'); } int main () { int x=2(:=2; float n=280(m=280; cout << ope#ate (x(:); cout << ".n"; cout << ope#ate (n(m); cout << ".n"; #etu#n 0; }

,n this case #e ha"e defined t#o functions #ith the same name, ope#ate, but one of them accepts t#o parameters of type int and the other one accepts them of type float. .he compiler kno#s #hich one to call in each case by e*amining the types passed as arguments #hen the function is called. ,f it is called #ith t#o ints as its arguments it calls to the function that has t#o int parameters in its prototype and if it is called #ith t#o floats it #ill call to the one #hich has t#o float parameters in its prototype. ,n the first call to ope#ate the t#o arguments passed are of type int, therefore, the function #ith the first prototype is called' .his function returns the result of multiplying both parameters. $hile the second call passes t#o arguments of type float, so the function #ith the second prototype is called. .his one has a different beha"ior% it di"ides one parameter by the other. ;o the beha"ior of a call to ope#ate depends on the type of the arguments passed because the function has been overloaded. Cotice that a function cannot be o"erloaded only by its return type. At least one of its parameters must ha"e a different type.

inline functions.
.he inline specifier indicates the compiler that inline substitution is preferred to the usual function call mechanism for a specific function. .his does not change the beha"ior of a function itself, but is used to suggest to the compiler that the code generated by the function body is inserted at each point the function is called, instead of being inserted only once and perform a regular call to it, #hich generally in"ol"es some additional o"erhead in running time. .he format for its declaration is%
inline t:pe name ( a# uments 888 ) { inst#uctions 888 }

and the call is +ust like the call to any other function. Aou do not ha"e to include the inline key#ord #hen calling the function, only in its declaration.

Page 17 of 27

)ost compilers already optimi0e code to generate inline functions #hen it is more con"enient. .his specifier only indicates the compiler that inline is preferred for this function.

(ecursi!it$.
1ecursi"ity is the property that functions ha"e to be called by themsel"es. ,t is useful for many tasks, like sorting or calculate the factorial of numbers. For e*ample, to obtain the factorial of a number &n9( the mathematical formula #ould be%
n- = n > (n)1) > (n)2) > (n)3) 888 > 1

more concretely, 69 &factorial of 6( #ould be%


2- = 2 > 3 > 3 > 2 > 1 = 120

and a recursi"e function to calculate this in !! could be%


$$ facto#ial calculato# %include <iost#eam> usin namespace std; lon facto#ial (lon a) { if (a > 1) #etu#n (a > facto#ial (a)1)); else #etu#n (1); } int main () { lon num'e#; cout << "?lease t:pe a num'e#4 "; cin >> num'e#; cout << num'e# << "- = " << facto#ial (num'e#); #etu#n 0; }

?lease t:pe a num'e#4 7 7- = 312//0

Cotice ho# in function facto#ial #e included a call to itself, but only if the argument passed #as greater than 1, since other#ise the function #ould perform an infinite recursi"e loop in #hich once it arri"ed to 0 it #ould continue multiplying by all the negati"e numbers &probably pro"oking a stack o"erflo# error on runtime(. .his function has a limitation because of the data type #e used in its design &lon ( for more simplicity. .he results gi"en #ill not be "alid for "alues much greater than 1>9 or 169, depending on the system you compile it.

&eclaring functions.
3ntil no#, #e ha"e defined all of the functions before the first appearance of calls to them in the source code. .hese calls #ere generally in function main #hich #e ha"e al#ays left at the end of the source code. ,f you try to repeat some of the e*amples of functions described so far, but placing the function

Page 1D of 27

before any of the other functions that #ere called from #ithin it, you #ill most likely obtain compiling errors. .he reason is that to be able to call a function it must ha"e been declared in some earlier point of the code, like #e ha"e done in all our e*amples.
main

-ut there is an alternati"e #ay to a"oid #riting the #hole code of a function before it can be used in main or in some other function. .his can be achie"ed by declaring +ust a prototype of the function before it is used, instead of the entire definition. .his declaration is shorter than the entire definition, but significant enough for the compiler to determine its return type and the types of its parameters. ,ts form is%
t:pe name ( a# umentAt:pe1( a# umentAt:pe2( 888);

,t is identical to a function definition, e*cept that it does not include the body of the function itself &i.e., the function statements that in normal definitions are enclosed in braces { }( and instead of that #e end the prototype declaration #ith a mandatory semicolon &;(. .he parameter enumeration does not need to include the identifiers, but only the type specifiers. .he inclusion of a name for each parameter as in the function definition is optional in the prototype declaration. For e*ample, #e can declare a function called p#otofunction #ith t#o int parameters #ith any of the follo#ing declarations%
int p#otofunction (int fi#st( int second); int p#otofunction (int( int);

Any#ay, including a name for each "ariable makes the prototype more legible.
$$ decla#in functions p#otot:pes %include <iost#eam> usin namespace std; void odd (int a); void even (int a); int main () { int i; do { cout << ";:pe a num'e# (0 to exit)4 "; cin >> i; odd (i); } !"ile (i-=0); #etu#n 0; } void odd (int a) { if ((aB2)-=0) cout << "@um'e# is odd8.n"; else even (a); } void even (int a) { if ((aB2)==0) cout << "@um'e# is even8.n"; ;:pe a @um'e# ;:pe a @um'e# ;:pe a @um'e# ;:pe a @um'e# num'e# (0 is odd8 num'e# (0 is even8 num'e# (0 is even8 num'e# (0 is even8 to exit)4 7 to exit)4 1 to exit)4 1030 to exit)4 0

Page 1E of 27

else odd (a); }

.his e*ample is indeed not an e*ample of efficiency. , am sure that at this point you can already make a program #ith the same result, but using only half of the code lines that ha"e been used in this e*ample. Any#ay this e*ample illustrates ho# prototyping #orks. )oreo"er, in this concrete e*ample the prototyping of at least one of the t#o functions is necessary in order to compile the code #ithout errors. .he first things that #e see are the declaration of functions odd and even%
void odd (int a); void even (int a);

.his allo#s these functions to be used before they are defined, for e*ample, in main, #hich no# is located #here some people find it to be a more logical place for the start of a program% the beginning of the source code. Any#ay, the reason #hy this program needs at least one of the functions to be declared before it is defined is because in odd there is a call to even and in even there is a call to odd. ,f none of the t#o functions had been pre"iously declared, a compilation error #ould happen, since either odd #ould not be "isible from even &because it has still not been declared(, or even #ould not be "isible from odd &for the same reason(. =a"ing the prototype of all functions together in the same place #ithin the source code is found practical by some programmers, and this can be easily achie"ed by declaring all functions prototypes at the beginning of a program.

%rra$s
An array is a series of elements of the same type placed in contiguous memory locations that can be indi"idually referenced by adding an inde* to a unique identifier. .hat means that, for e*ample, #e can store 6 "alues of type int in an array #ithout ha"ing to declare 6 different "ariables, each one #ith a different identifier. ,nstead of that, using an array #e can store 6 different "alues of the same type, int for e*ample, #ith a unique identifier. For e*ample, an array to contain 6 integer "alues of type int called 'ill: could be represented like this%

#here each blank panel represents an element of the array, that in this case are integer "alues of type int. .hese elements are numbered from 0 to 3 since in arrays the first inde* is al#ays 0, independently of its length. 2ike a regular "ariable, an array must be declared before it is used. A typical declaration for an array in

Page 2> of 27

!! is%
t:pe name CelementsD;

#here t:pe is a "alid type &like int, float...(, name is a "alid identifier and the elements field &#hich is al#ays enclosed in square brackets CD(, specifies ho# many of these elements the array has to contain. .herefore, in order to declare an array called 'ill: as the one sho#n in the abo"e diagram it is as simple as%
int 'ill: C2D;

)'T*% .he elements field #ithin brackets CD #hich represents the number of elements the array is going to hold, must be a constant "alue, since arrays are blocks of non/dynamic memory #hose si0e must be determined before e*ecution. ,n order to create arrays #ith a "ariable length dynamic memory is needed, #hich is e*plained later in these tutorials.

Initiali+ing arra$s.
$hen declaring a regular array of local scope &#ithin a function, for e*ample(, if #e do not specify other#ise, its elements #ill not be initiali0ed to any "alue by default, so their content #ill be undetermined until #e store some "alue in them. .he elements of global and static arrays, on the other hand, are automatically initiali0ed #ith their default "alues, #hich for all fundamental types this means they are filled #ith 0eros. ,n both cases, local and global, #hen #e declare an array, #e ha"e the possibility to assign initial "alues to each one of its elements by enclosing the "alues in braces { }. For e*ample%
int 'ill: C2D = { 11( 2( 00( 30( 12001 };

.his declaration #ould ha"e created an array like this%

.he amount of "alues bet#een braces { } must not be larger than the number of elements that #e declare for the array bet#een square brackets C D. For e*ample, in the e*ample of array 'ill: #e ha"e declared that it has 6 elements and in the list of initial "alues #ithin braces { } #e ha"e specified 6 "alues, one for each element. $hen an initiali0ation of "alues is pro"ided for an array, !! allo#s the possibility of lea"ing the square brackets empty C D. ,n this case, the compiler #ill assume a si0e for the array that matches the number of "alues included bet#een braces { }%
int 'ill: CD = { 11( 2( 00( 30( 12001 };

After this declaration, array 'ill: #ould be 6 ints long, since #e ha"e pro"ided 6 initiali0ation "alues.

Page 21 of 27

%ccessing the !alues of an arra$.

,n any point of a program in #hich an array is "isible, #e can access the "alue of any of its elements indi"idually as if it #as a normal "ariable, thus being able to both read and modify its "alue. .he format is as simple as%
nameCindexD

Follo#ing the pre"ious e*amples in #hich 'ill: had 6 elements and each of those elements #as of type int, the name #hich #e can use to refer to each element is the follo#ing%

For e*ample, to store the "alue 02 in the third element of 'ill:, #e could #rite the follo#ing statement%
'ill:C2D = 02;

and, for e*ample, to pass the "alue of the third element of 'ill: to a "ariable called a, #e could #rite%
a = 'ill:C2D;

.herefore, the e*pression 'ill:C2D is for all purposes like a "ariable of type int. Cotice that the third element of 'ill: is specified 'ill:C2D, since the first one is 'ill:C0D, the second one is 'ill:C1D, and therefore, the third one is 'ill:C2D. -y this same reason, its last element is 'ill:C3D. .herefore, if #e #rite billyF6G, #e #ould be accessing the si*th element of 'ill: and therefore e*ceeding the si0e of the array. ,n !! it is syntactically correct to e*ceed the "alid range of indices for an array. .his can create problems, since accessing out/of/range elements do not cause compilation errors but can cause runtime errors. .he reason #hy this is allo#ed #ill be seen further ahead #hen #e begin to use pointers. At this point it is important to be able to clearly distinguish bet#een the t#o uses that brackets C D ha"e related to arrays. .hey perform t#o different tasks% one is to specify the si0e of arrays #hen they are declared' and the second one is to specify indices for concrete array elements. Do not confuse these t#o possible uses of brackets C D #ith arrays.
int 'ill:C2D; 'ill:C2D = 02; $$ decla#ation of a ne! a##a: $$ access to an element of t"e a##a:8

,f you read carefully, you #ill see that a type specifier al#ays precedes a "ariable or array declaration, #hile it ne"er precedes an access. ;ome other "alid operations #ith arrays%
'ill:C0D = a;

Page 22 of 27

'ill:CaD = 02; ' = 'ill: Ca+2D; 'ill:C'ill:CaDD = 'ill:C2D + 2;

$$ a##a:s example %include <iost#eam> usin namespace std; int 'ill: CD = {11( 2( 00( 30( 12001}; int n( #esult=0; int main () { fo# ( n=0 ; n<2 ; n++ ) { #esult += 'ill:CnD; } cout << #esult; #etu#n 0; } 12201

,ultidimensional arra$s

)ultidimensional arrays can be described as Harrays of arraysH. For e*ample, a bidimensional array can be imagined as a bidimensional table made of elements, all of them of a same uniform data type.

Eimm:

represents a bidimensional array of 4 per 6 elements of type int. .he #ay to declare this array in !! #ould be%

int Eimm: C3DC2D;

and, for e*ample, the #ay to reference the second element "ertically and fourth hori0ontally in an e*pression #ould be%
Eimm:C1DC3D

Page 24 of 27

&remember that array indices al#ays begin by 0ero(. )ultidimensional arrays are not limited to t#o indices &i.e., t#o dimensions(. .hey can contain as many indices as needed. -ut be careful9 .he amount of memory needed for an array rapidly increases #ith each dimension. For e*ample%
c"a# centu#: C100DC312DC23DC10DC10D;

declares an array #ith a c"a# element for each second in a century, that is more than 4 billion chars. ;o this declaration #ould consume more than 4 gigabytes of memory9 )ultidimensional arrays are +ust an abstraction for programmers, since #e can obtain the same results #ith a simple array +ust by putting a factor bet#een its indices%
int Eimm: C3DC2D; int Eimm: C12D; $$ is eFuivalent to $$ (3 > 2 = 12)

$ith the only difference that #ith multidimensional arrays the compiler remembers the depth of each imaginary dimension for us. .ake as e*ample these t#o pieces of code, #ith both e*actly the same result. :ne uses a bidimensional array and the other one uses a simple array% multidimensional arra$
%define G+H;I 2 %define I&+JI; 3 int Eimm: CI&+JI;DCG+H;ID; int n(m;

pseudo-multidimensional arra$
%define G+H;I 2 %define I&+JI; 3 int Eimm: CI&+JI; > G+H;ID; int n(m;

int main () int main () { { fo# (n=0;n<I&+JI;;n++) fo# (n=0;n<I&+JI;;n++) fo# (m=0;m<G+H;I;m++) fo# (m=0;m<G+H;I;m++) { { Eimm:CnDCmD=(n+1)>(m+1); Eimm:Cn>G+H;I+mD=(n+1)>(m+1); } } #etu#n 0; #etu#n 0; } }

Cone of the t#o source codes abo"e produce any output on the screen, but both assign "alues to the memory block called +immy in the follo#ing #ay%

$e ha"e used Hdefined constantsH &%define( to simplify possible future modifications of the program. For e*ample, in case that #e decided to enlarge the array to a height of 8 instead of 4 it could be done simply by changing the line%

Page 28 of 27

%define I&+JI; 3

to%
%define I&+JI; 3

#ith no need to make any other modifications to the program.

%rra$s as parameters
At some moment #e may need to pass an array to a function as a parameter. ,n !! it is not possible to pass a complete block of memory by "alue as a parameter to a function, but #e are allo#ed to pass its address. ,n practice this has almost the same effect and it is a much faster and more efficient operation. ,n order to accept arrays as parameters the only thing that #e ha"e to do #hen declaring the function is to specify in its parameters the element type of the array, an identifier and a pair of "oid brackets CD. For e*ample, the follo#ing function%
void p#ocedu#e (int a# CD)

accepts a parameter of type Harray of intH called a# . ,n order to pass to this function an array declared as%
int m:a##a: C30D;

it #ould be enough to #rite a call like this%


p#ocedu#e (m:a##a:);

=ere you ha"e a complete e*ample%


$$ a##a:s as pa#amete#s %include <iost#eam> usin namespace std; void p#inta##a: (int a# CD( int len t") { fo# (int n=0; n<len t"; n++) cout << a# CnD << " "; cout << ".n"; } 2 10 12 2 3 1 / 10 int main () { int fi#sta##a:CD = {2( 10( 12}; int seconda##a:CD = {2( 3( 1( /( 10}; p#inta##a: (fi#sta##a:(3); p#inta##a: (seconda##a:(2); #etu#n 0; }

As you can see, the first parameter &int a# CD( accepts any array #hose elements are of type int, #hate"er its length. For that reason #e ha"e included a second parameter that tells the function the

Page 26 of 27

length of each array that #e pass to it as its first parameter. .his allo#s the fo# loop that prints out the array to kno# the range to iterate in the passed array #ithout going out of range. ,n a function declaration it is also possible to include multidimensional arrays. .he format for a tridimensional array parameter is%
'aseAt:peCDCdept"DCdept"D

for e*ample, a function #ith a multidimensional array as argument could be%


void p#ocedu#e (int m:a##a:CDC3DC3D)

Cotice that the first brackets CD are left blank #hile the follo#ing ones are not. .his is so because the compiler must be able to determine #ithin the function #hich is the depth of each additional dimension. Arrays, both simple or multidimensional, passed as function parameters are a quite common source of errors for no"ice programmers. , recommend the reading of the chapter about Pointers for a better understanding on ho# arrays operate.

Character Se"uences
As you may already kno#, the !! ;tandard 2ibrary implements a po#erful string class, #hich is "ery useful to handle and manipulate strings of characters. =o#e"er, because strings are in fact sequences of characters, #e can represent them also as plain arrays of c"a# elements. For e*ample, the follo#ing array%
c"a# Eenn: C20D;

is an array that can store up to 2> elements of type c"a#. ,t can be represented as%

.herefore, in this array, in theory, #e can store sequences of characters up to 2> characters long. -ut #e can also store shorter sequences. For e*ample, Eenn: could store at some point in a program either the sequence "Iello" or the sequence "Ke##: c"#istmas", since both are shorter than 2> characters. .herefore, since the array of characters can store shorter sequences than its total length, a special character is used to signal the end of the "alid sequence% the null character, #hose literal constant can be #ritten as <.0< &backslash, 0ero(. :ur array of 2> elements of type c"a#, called Eenn:, can be represented storing the characters sequences "Iello" and "Ke##: L"#istmas" as%

Page 2B of 27

Cotice ho# after the "alid content a null character &<.0<( has been included in order to indicate the end of the sequence. .he panels in gray color represent c"a# elements #ith undetermined "alues.

Initiali+ation of null-terminated character se"uences


-ecause arrays of characters are ordinary arrays they follo# all their same rules. For e*ample, if #e #ant to initiali0e an array of characters #ith some predetermined sequence of characters #e can do it +ust like any other array%
c"a# m:!o#dCD = { <I<( <e<( <l<( <l<( <o<( <.0< };

,n this case #e #ould ha"e declared an array of B elements of type c"a# initiali0ed #ith the characters that form the #ord "Iello" plus a null character <.0< at the end. -ut arrays of c"a# elements ha"e an additional method to initiali0e their "alues% using string literals. ,n the e*pressions #e ha"e used in some e*amples in pre"ious chapters, constants that represent entire strings of characters ha"e already sho#ed up se"eral times. .hese are specified enclosing the te*t to become a string literal bet#een double quotes &H(. For e*ample%
"t"e #esult is4 "

is a constant string literal that #e ha"e probably used already. Double quoted strings &"( are literal constants #hose type is in fact a null/terminated array of characters. ;o string literals enclosed bet#een double quotes al#ays ha"e a null character &<.0<( automatically appended at the end. .herefore #e can initiali0e the array of c"a# elements called m:!o#d #ith a null/terminated sequence of characters by either one of these t#o methods%
c"a# m:!o#d CD = { <I<( <e<( <l<( <l<( <o<( <.0< }; c"a# m:!o#d CD = "Iello";

,n both cases the array of characters m:!o#d is declared #ith a si0e of B elements of type c"a#% the 6 characters that compose the #ord "Iello" plus a final null character &<.0<( #hich specifies the end of the sequence and that, in the second case, #hen using double quotes &"( it is appended automatically. Please notice that #e are talking about initiali0ing an array of characters in the moment it is being declared, and not about assigning "alues to them once they ha"e already been declared. ,n fact because this type of null/terminated arrays of characters are regular arrays #e ha"e the same restrictions that #e ha"e #ith any other array, so #e are not able to copy blocks of data #ith an assignment operation. Assuming m:stext is a c"a#CD "ariable, e*pressions #ithin a source code like%

Page 27 of 27

m:stext = "Iello"; m:stextCD = "Iello";

#ould not be "alid, like neither #ould be%


m:stext = { <I<( <e<( <l<( <l<( <o<( <.0< };

.he reason for this may become more comprehensible once you kno# a bit more about pointers, since then it #ill be clarified that an array is in fact a constant pointer pointing to a block of memory.

-sing null-terminated se"uences of characters

Cull/terminated sequences of characters are the natural #ay of treating strings in !!, so they can be used as such in many procedures. ,n fact, regular string literals ha"e this type &c"a#CD( and can also be used in most cases. For e*ample, cin and cout support null/terminated sequences as "alid containers for sequences of characters, so they can be used directly to e*tract strings of characters from cin or to insert them into cout. For e*ample%
$$ null)te#minated seFuences of c"a#acte#s %include <iost#eam> usin namespace std; int main () { c"a# FuestionCD = "?lease( ente# :ou# fi#st name4 ?lease( ente# :ou# fi#st name4 "; Mo"n c"a# #eetin CD = "Iello( "; Iello( Mo"nc"a# :ou#name C/0D; cout << Fuestion; cin >> :ou#name; cout << #eetin << :ou#name << "-"; #etu#n 0; }

As you can see, #e ha"e declared three arrays of c"a# elements. .he first t#o #ere initiali0ed #ith string literal constants, #hile the third one #as left uninitiali0ed. ,n any case, #e ha"e to speficify the si0e of the array% in the first t#o &Fuestion and #eetin ( the si0e #as implicitly defined by the length of the literal constant they #ere initiali0ed to. $hile for :ou#name #e ha"e e*plicitly specified that it has a si0e of D> chars. Finally, sequences of characters stored in c"a# arrays can easily be con"erted into st#in ob+ects +ust by using the assignment operator%
st#in m:st#in ; c"a# m:ntcsCD="some text"; m:st#in = m:ntcs;

You might also like