Sei sulla pagina 1di 14

ENGR 1200U Introduction to Programming Lecture 18 Modular Programming with Functions (Chapter 6) (contd)

Dr. Eyhab Al-Masri

1992-2012 by Pearson Education, Inc. & John Wiley & Sons Some portions are adopted from C++ for Everyone by Horstmann

What are the two kinds of functions in C++?

valuereturningfunctions voidfunctions

ENGR 1200U Winter 2013 - UOIT

Given void format_string(stringstr) Is the following code statement correct?

int result=format_string("Hello");

ENGR 1200U Winter 2013 - UOIT

What is the difference between an argument and a parameter?

Anargumentalwaysappearsinafunctioncallwithinthe callingblock Aparameteralwaysappearsinthefunctionheadingor functionprototype

ENGR 1200U Winter 2013 - UOIT

You can have only one main function in a program Can you have the same variable name in different functions?

But you can have as many variables and parameters

It is possible to have the same variable name more than once in a program When the variable name is used, you need to know to which definition it belongs

ENGR 1200U Winter 2013 - UOIT

A variable or parameter that is defined within a function is visible from the point at which it is defined until the end of the block named by the function
This area is called the scope of the variable

ENGR 1200U Winter 2013 - UOIT

The scope of a variable is the part of the program in which it is visible.

Because scopes do not overlap, a name in one scope cannot conflict with any name in another scope A name in one scope is invisible in another scope

ENGR 1200U Winter 2013 - UOIT

double cube_volume(double side_length) { double volume=side_length *side_length *side_length; return volume; } Each volume variable is defined in a separate function, and their scope do not int main() overlap { double volume=cube_volume(2); cout <<volume<<endl; return 0; }

ENGR 1200U Winter 2013 - UOIT

A local variable is defined inside a function. A global variable is defined outside a function

A global variable is visible to every function defined after them. Generally, global variables are not a good idea.

ENGR 1200U Winter 2013 - UOIT

int balance=10000;//Aglobalvariable void withdraw(double amount) { if (balance>=amount) { balance=balance amount; } } int main() { withdraw(1000); cout <<balance<<endl; return 0; }

The scope of the variable balance extends over both the withdraw and the main functions When multiple functions update global variables, result can be difficult to predict Avoid global variables as much as you can

ENGR 1200U Winter 2013 - UOIT

int balance=10000;//Aglobalvariable void withdraw(double amount) { if (balance>=amount) { balance=balance amount; } } int main() { withdraw(1000); cout <<balance<<endl; return 0; }

There is only one function that updates the balance variable

There could be many, many, many functions that might need to update balance

ENGR 1200U Winter 2013 - UOIT

When a function reference is made, the value of the argument is passed to the function and assigned as the value of the corresponding formal parameter
double cube_volume(double side_length) { double volume=side_length *side_length *side_length; return volume; pass by value (value of }

argument does not change


int main() { double volume=cube_volume(2); cout <<volume<<endl; return 0; }

main()
side_length

Pass by value cube_volume() 2


side_length

ENGR 1200U Winter 2013 - UOIT

If you want to write a function that changes the value of an argument, you must use a reference parameter in order to allow the change Example Consider a function that simulates withdrawing a given amount of money from a bank account, provided that sufficient funds are available

If the amount of money is insufficient, a $10 penalty is deducted instead

ENGR 1200U Winter 2013 - UOIT

The function would be as follows:


double johndoe_account =1000; withdraw(johndoe_account,100); //Nowjohndoe_account is900 withdraw(johndoe_account,1000); //Insufficientfunds. //Nowjohndoe_account is890

ENGR 1200U Winter 2013 - UOIT

Here is a first attempt


void withdraw(double balance,double amount) { const double PENALTY=10; if (balance>=amount) { balance=balance amount; } else { balance=balance PENALTY; } }

But this does not work!

ENGR 1200U Winter 2013 - UOIT

Lets look at what is actually happening:

Example: lets call the function passing in 100 to be taken from johndoe_account

double johndoe_account =1000; withdraw(johndoe_account,100);

ENGR 1200U Winter 2013 - UOIT

The local variables consts, and the value parameters are initialized

double johndoe_account =1000; withdraw(johndoe_account,100); void withdraw(double balance,double amount) {const int PENALTY=10;

ENGR 1200U Winter 2013 - UOIT

The test is false, the LOCAL variable balance is updated


else { balance=balance PENALTY; }

double johndoe_account =1000;...

NOTHING happens to johndoe_account because it is a separate variable (in a different scope)

ENGR 1200U Winter 2013 - UOIT

The function call has ended. Local names in the function are gone and
NOTHING happened to johndoe_account. withdraw(johndoe_account,100);

ENGR 1200U Winter 2013 - UOIT

A reference parameter refers to a variable that is supplied in a function call


To indicate a reference parameter, you place an & after the type name.

void withdraw(double balance,double amount)

To indicate a value parameter, you do not place an & after the type name.

ENGR 1200U Winter 2013 - UOIT

10

Here is the correct code, using reference parameters


void withdraw(double& balance,double amount) { const double PENALTY=10; if (balance>=amount) { balance=balance amount; } else { balance=balance PENALTY; Lets see } this in action }

ENGR 1200U Winter 2013 - UOIT

Now, using the function with pass by reference (or reference parameters), lets call the function passing in 100 to be taken from johndoe_account

double johndoe_account =1000; withdraw(johndoe_account,100);

ENGR 1200U Winter 2013 - UOIT

11

Notice that balance now refers to johndoe_account

double johndoe_account =1000; ... withdraw(johndoe_account,100); ... void withdraw(double& balance,double amount) {const int PENALTY=10;

ENGR 1200U Winter 2013 - UOIT

johndoe_account and balance are both names for this memory

The test is false, the variable johndoe_account is updated when the reference parameter balance is assigned to
recall that johndoe_account and balance are both names for this memory

double johndoe_account =1000; ... else { balance=balance amount; }

ENGR 1200U Winter 2013 - UOIT

12

The function call has ended. Local names in the function are gone and
johndoe_account was correctly changed! withdraw(johndoe_account,100);

ENGR 1200U Winter 2013 - UOIT

The type double& is pronounced:


reference to double double ref
or

A reference parameter must always be called with a variable


It would be an error to supply a number
withdraw(1000, 500); // Error: reference parameter must be a variable

ENGR 1200U Winter 2013 - UOIT

13

For the same reason, you cannot supply an expression:


withdraw(johndoe_account + 150, 500); // Error: reference parameter must be a variable

ENGR 1200U Winter 2013 - UOIT

Returning smallest & average of numbers in an argument list

Write the following functions program to test them.

and

provide

a. double(smallest(doublex,doubley,doublez), returningthesmallestofthearguments b. double(smallest(doublex,doubley,doublez), returningtheaverageofthearguments

ENGR 1200U Winter 2013 - UOIT

14

Potrebbero piacerti anche