All these predefined functions have parameters passed by
value.
- double pow(double base, double exp)
- double sqrt(double x)
- void srand(unsigned int seed)
If we call one of these functions, no change occurs to the
argment:
int main()
{
double x = 5.0;
double y = sqrt(x);
// x is still 5.0!!
- Pasing arguments by reference means that the
parameter is an alias for the same location as the
argument.
- Consequeces:
- Any change to the parameter value is a change in the
argument.
- When the function returns, the arguments will
may have also changed.
The default calling method is call by value.
void swap(int x, int y);
Here arguments will be passed to x and y by value.
To specify call by reference place an & (an ampersand) after the parameter
type in the function declaration (and definition).
void swap(int& x, int& y);
There is NO difference in the syntax of calling a function if
its parameters are call by value or call by reference.
The compiler has to see the declaration of the function being
called to determine how to pass the arguments.
The programmer writes the same sytnax for the call in either
case.
Are arguments a and b passed by value or
reference by the following code? You can't tell unless you see the
declaration of the swap function.
int main()
{
int a = 5, b = 10;
swap(a,b);
cout << a << b << endl;
return 0;
}
Which calling method should be used for the function in these
function calls:
int main()
{
int a, b, c;
int max;
double avg;
cin >> a >> b >> c;
sort(a,b,c);
max = findmax(a,b,c);
avg = average(a,b,c);
cout << a << " "
<< b << " "
<< c << endl;
cout << "Max = " << max << endl;
cout << "Average = " << avg << endl;
return 0;
}
What should the declarations be for each of these functions?
void sort(int&, int&, int&);
int findmax(int, int, int);
double average(int, int, int);
In the previous example there was no prompt to the user to
enter the input.
Suppose we decide we want to modify the code like by adding a
function getInput to read in the three value like this:
int main()
{
int a, b, c;
int max;
double avg;
getInput(a,b,c);
sort(a,b,c);
max = findmax(a,b,c);
avg = average(a,b,c);
cout << a << " "
<< b << " "
<< c << endl;
cout << "Max = " << max << endl;
cout << "Average = " << avg << endl;
return 0;
}
What should the declaration for getInput be? (Should it use
call by value or call by reference?)
Declaration
void getInput(int&, int&, int&);
Definition
void getInput(int& x, int& y, int& z)
{
cout << "First number: ";
cin >> x;
cout << "Second number: ";
cin >> y;
cout << "Third number: ";
cin >> z;
}
What would happen in the main program if getInput used call by
value?
Call by constant reference isn't really a different argument
passing method.
It is just call by reference
It combines the const qualifier with the parameter
type declaration and has the usual meaning.
A parameter that is declared to have values passed by constant
reference
- do get initialized at the call
- are passed by reference (so the parameter is an alias for
the argument)
- but the function is not allowed to assign to or otherwise
change the parameter's value.
Syntax Example
Call by constant reference:
int findMax(const int& a, const int& b, const int& c);
We could instead declare findMax to use call by value:
int findMax(int a, int b, int c);
What is the difference between call by value and call by
constant reference?
A function that has a return type of void must have some
effect such as input, output, or modification of the
arguments.
A function that has a non void return type should
typically not have side effects. It is like an operator
that produces some new result but doesn't change its operands.
Argument passing method can be different for each argument in a
function that has multiple parameters.
The function setBoth below sets a = x and b =
y and guarantees that x and y are not changed!
What should its declaration be? That is, how should the 4
arguments be passed?
int main()
{
int a = 5, b = 3;
int x, y;
x = a + b;
y = a;
setBoth(a, b, x, y);
}
The first two arguments must be passed by reference.
The second two could be passed by value or constant reference
to guarantee that the third and fourth arguments are not changed
void setBoth(int& aval, int& bval, int xval, int yval);
or
void setBoth(int& aval, int& bval, const int& xval, const int& yval);
Here is the getInput function again, but it changed to
explicitly ask for an integer:
void getInput(int& x, int& y, int& z)
{
cout << "First integer: ";
cin >> x;
cout << "Second integer: ";
cin >> y;
cout << "Third integer: ";
cin >> z;
}
Suppose we also wanted a function to read 3 values of type
double.
Just modify getInput like this:
void getInput(double& x, double& y, double& z)
{
cout << "First double: ";
cin >> x;
cout << "Second double: ";
cin >> y;
cout << "Third double: ";
cin >> z;
}
Can you have both functions (with the same name!!) in
the same program?
In C++, yes. (In C the answer was no.)
If there are two functions named the same (e.g. getInpt), the
function is said to be overloaded.
If an overloaded function is called, the compiler must
determine which version is being called.
This is called overload resolution.
Here are the declarations for the two versions of
getInput
- void get(int&, int&, int&);
- void get(double&, double&, double&);
Which version should be called (1 or 2) for each of the
following calls:
int a, b, c;
double x, y, z;
float p, q, r;
getInput(a,b,c); // A.
getInput(x,y,z); // B.
getInput(p,q,r); // C
Here is the same example, except that suppose the double
version of getInput is changed to float:
Here are the declarations for the two versions of
getInput
- void get(int&, int&, int&);
- void get(float&, float&, float&);
Which version should be called (1 or 2) for each of the
following calls:
int a, b, c;
double x, y, z;
float p, q, r;
getInput(a,b,c); // A.
getInput(x,y,z); // B.
getInput(p,q,r); // C
Functions can specify default argument values in the function
declaration.
If a default argument value is given in a function declaration,
the caller can override the default value by passing an
argument.
But if the caller omits the argument altogether, the default
argument value is used.
double area(double radius = 1.0 );
int main()
{
double a1, a2;
double r;
cin >> r;
a1 = area(r); // radius = r
a2 = area(); // radius = 1.0
}
double area(double radius)
{
return radius * radius * PI;
}