Showing posts with label Parameters. Show all posts
Showing posts with label Parameters. Show all posts

Function Overloading: Different Parameters and Arguments

In this tutorial from our C++ e-book, we will learn what function overloading is, what it is for, and how to use this important programming technique.

Parameter and Arguments Sizes in C++ Functions

In the Default Arguments tutorial, we saw that you can send a variety of arguments to a function as long as it is using reference parameters.

For example, the code below is from a function that calculates an arithmetic average:
#include <iostream>
using namespace std;

float average(float a, float b, float c, float d = 0.0)
{
    return (a+b+c+d)/4;
}

int main()
{
    cout<<"Average of 3 numbers: "<<average(10, 9, 7)<<endl;
    cout<<"Average of 4 numbers: "<<average(10, 9, 7, 6)<<endl;

    return 0;
}
It can take 3 or 4 arguments. If you submit only 3, the 4 argument is the default, with a value of 0.
However, note an error.

Even if we only send 3 arguments, the arithmetic average is calculated as if there were 4 notes.

It would be interesting if, if I submitted 3 arguments, it would return:
(a + b + c) / 3

And if I sent 4 arguments, it would return:
(a + b + c + d) / 4

And this is possible with overloading functions.

C++ Function Overloading

Overloading is the technique that allows us to have functions with the same name as long as their parameters are different, in some way.

Here's what the 3 and for grade average program looks like:
#include <iostream>
using namespace std;

float average(float a, float b, float c)
{
    return (a+b+c)/3;
}

float average(float a, float b, float c, float d)
{
    return (a+b+c+d)/4;
}

int main()
{
    cout<<"Average of 3 numbers: "<<average(10, 9, 7)<<endl;
    cout<<"Average of 4 numbers: "<<average(10, 9, 7, 6)<<endl;

    return 0;
}
Note that we invoke the average() function, the only difference is that in the first call we pass 3 arguments, and in the second call of the function we pass 4 arguments.

Because C++ is naughty and smart, it knows which function to run correctly.

It is so clever that even if there are the same number of parameters / arguments, it can differentiate through the type of data we are using.

Look:
#include <iostream>
using namespace std;

double average(double a, double b, double c)
{
    cout<<"Average of 3 doubles   : ";
    return (a+b+c)/3;
}

int average(int a, int b, int c)
{
    cout<<"Average of 3 integers  : ";
    return (a+b+c)/3;
}

int main()
{
    cout<<average(10.0, 9.0, 7.0)<<endl;
    cout<<average(10, 9, 7)<<endl;

    return 0;
}
When we pass double type variables, it calls average(double, double, double)
When we pass int variables, it calls average(int, int, int)

C++ can differentiate because the signatures of each function are different (either in the number of parameters or the type that will work).

In fact, even if the functions have the same name, the same number of parameters, and the same data types, we can overload functions as long as the order of the parameters is different:
#include <iostream>
using namespace std;

void func(int a, double b)
{
    cout<<"First is int    : "<<a<<endl;
    cout<<"Second is double: "<<b<<endl;
}

void func(double b, int a)
{
    cout<<"First is double : "<<b<<endl;
    cout<<"Second is int   : "<<a<<endl;
}

int main()
{
    func(1, 2.5);
    cout<<endl;
    func(2.5, 1);

    return 0;
}
In the example we have: func (int, double)
Also: func (double, int)

Simply signature from one function to another is different so we can use overload where signature is a set: function name, data type, data number and order of information.

For good programming practices, you should use function overloading whenever you need to use functions with the same purpose and logic, but for different number and / or types and / or order of data.

Reference Parameters and Variables

In this tutorial of our C++ course, we will learn how to pass arguments by reference into functions.

Pass by Value

We have already learned how to send information to functions through arguments and parameters.
And we saw that this pass is called pass by value, because we only pass the value to the function.

If we send a variable to a function, and within that function that variable is changed, it is not changed outside the function. Test the following code, which squares a number:
#include <iostream>
using namespace std;

void square(int num);

int main()
{
    int number = 6;

    cout<<"Before  : num = "<<number<<endl;
    square(number);
    cout<<"After   : num = "<<number<<endl;

    return 0;
}

void square(int num)
{
    num = num*num;
    cout<<"During  : num = "<<num<<endl;
}
When we invoke the function: square (number), we are actually passing a copy of the value of the variable number.

Within the function, the num variable will receive a copy of the value of number. That is, it will not have access to the original variable number, only its value! Therefore, passing by value.

Reference Parameter: &

Be the variable declaration:
  • int num = 6;

What we are doing is allocating, reserving, a space in the memory of your computer.

So when we use num, C++ understands that we must go to the address this variable points to and get the number inside that memory location.

As we have seen, when we pass this normal variable to a function that expects a normal variable, it takes only a copy of its value, and does not mess with the original content.

However, there is another special type of variable, the reference variable.

It is special because if we pass a variable to a function and the function wants to get the reference variable through a reference parameter, it will have access to the memory address (the reference) where this variable is originally stored.

That is: we will actually have access to the variable, not just its copy.

To get the reference of a variable, just use the & operator before the variable name, in the function parameter! It is the reference parameter. Both in the prototype and in the function declaration.

So the previous code example looks like this:
#include <iostream>
using namespace std;

void square(int &);

int main()
{
    int number = 6;

    cout<<"Before  : num = "<<number<<endl;
    square(number);
    cout<<"After   : num = "<<number<<endl;

    return 0;
}

void square(int &num)
{
    num = num*num;
    cout<<"During  : num = "<<num<<endl;
}
See now the result:
Parameter reference

In fact, the function was able to change the value of the variable because this argument pass to the parameter was by reference parameter.

What happens here is that the parameter will not capture the value of the argument but its reference to where it is pointing in memory. Speaking of pointing to an address, we will study more about it in the pointers and arrays (vectors) sections in C++, where we will study about passing by reference using pointers.

More about C++ Reference Parameters

Some programmers also prefer to declare the prototype like this:
  • square (int&);

You can also use it like this in the prototype:
  • square(int &num);
  • square(int& num);

Also, the important thing is that & is in both the prototype and function declaration, ok?

Remember that if your parameter is reference, it can only work with reference variable.
It would be a mistake if you use an argument that is not a variable, such as a literal, an expression, or a constant, for example:
  • square(10); // must use square (number);
  • square(number+1); // it's an expression, avoid
When we do: square (int &num)

Read: "num is a reference to an integer", that is, it is referencing, pointing, indicating a memory location where an integer is stored. Since you have the location of the original variable, you can change this value.

Value passing and reference exercise

Create a program that prompts the user for an integer. Then it must turn this value into its cube. Do this by using a function that receives pass by value and another that uses parameter and reference variable. Make it clear that one changes the value only within the function (value) and the other changes the original value of the variable (reference).

Paste in the comments, your solution.

Default arguments and omission of arguments

In this C ++ tutorial, we will learn what a default argument is, what it is for, and how to use it, as well as omitting an argument in a function call.

Default Argument

We have already learned how to send information to functions by using parameters and arguments.
Suppose we want to add two numbers, a and b, the function would be:
float sum2(float a, float b)
{
    return a+b;
}
Now suppose we want to calculate the sum of three variables, we would have to do a function like this:
float sum3(float a, float b, float c)
{
    return a+b+c;
}
Note that we would have to use another function, with another name, for the same purpose: adding the arguments. Not very smart, do you agree?
It would be nice if the same function added 2 or 3 arguments as much as the user wants.

To add two numbers, it would be interesting to do: sum (1,2);
To add three numbers, we would do: sum (1,2,3);

This is where the concept of standard argument comes in.
Simply declare the prototype of the function above:
  • float sum(float a, float b, float c = 0.0);

And its scope:
float sum(float a, float b, float c = 0.0)
{
    return a+b+c;
}
What happens is as follows:
The default value of c is 0.0

If you do: sum (1,2,3), the value of c will be 3.

If you do: sum (1,2), you will not be setting value for c, so it will default to 0, got it? Argument with default value if you do not provide this value.

Test:
#include <iostream>
using namespace std;

float sum(float a, float b, float c = 0.0)
{
    return a+b+c;
}

int main()
{
    cout<<sum(1,2)<<endl;
    cout<<sum(1,2,3)<<endl;

    return 0;
}
It works for 2 or 3 variables, just like the way you want it!

Arguments omission

The previous code works to add 2 or 3 numbers.
To add 2, 3 or 4 numbers, we could do:
float sum(float a, float b, float c = 0.0, float d = 0.0)
{
    return a+b+c+d;
}
Now you can do:

sum (1,2);
sum (1,2,3);
sum (1,2,3,4);

In the first case, we omitted argument c and d.
In the second example, we omitted the argument d.
In the last example, we did not omit any arguments.

That is, default arguments are automatically replaced when we enter the arguments.

Rules in Using Default Arguments

When we enter and pass arguments to a function, they are copied from left to right.

For example: sum (1,2,3)
1 goes to 'a', 2 goes to 'b' and value 3 goes to parameter 'c'. The value of the argument 'd', then, is the default argument, which we set to 0.

Another rule is that once we use a default argument in one parameter, all other subsequent parameters must also have default arguments as well. For example, the following function prototype is valid:

  • float volume (base float, float height = 1, float width = 1);

'height' is a default argument, and the following as well.

The following function prototype is invalid:

  • float volume (float height = 1, base float, float width = 1);

Since the first argument is default, all others must be, and 'base' is a normal parameter without default argument, which must necessarily be provided by the function call.

Another point is that parameters with default arguments must be declared on the first occurrence of the function declaration. That is, if you use a prototype of a function and then elsewhere you will define the scope of your function, the default arguments must already be defined in the prototype, which will come before. For example, you might even abbreviate it like this:

  • Prototype: double area (double = 1.0, float 2.0);
  • Function definition: double area (double length, float witdh) {return length * width; }

So, to recap, be the function:
double area (double length = 1.0, float witdh = 2.0) 
{ 
   return length*width; 
} 
If we make the following function calls:

  • area() - values 1.0 and 2.0 will be used to calculate the area respectively, ie we are using the two default arguments, no one is overwritten.
  • area(3) - values 3 and 2.0 will be used to calculate the area, ie the first default argument has been overwritten with 3
  • area(3,6) - values 3 and 6 will be used to calculate the area, ie the two default arguments have been overwritten.

Let's see this in practice? Test the following code:
#include <iostream>
using namespace std;

void area(float = 1.0, float = 1.0);

int main()
{
    cout << "No argument passed:"<<endl;
    area();

    cout << "\nFirst argument passed:"<<endl;
    area(2.0);

    cout << "\nBoth argument passed:"<<endl;
    area(2.0, 3.0);

    return 0;
}

void area(float length, float width)
{
    cout << "Area: " << length * width << endl;
}



Everything worked? Yes? So let's follow in our C++ tutorials about functions.

Parameters and Arguments - Sending Data to C++ Functions

In this tutorial, we will learn how to send data to functions in C++ programming language.

Sending data to functions

In the last tutorial of our C++ course, we learned how functions return information to those who invoked it through the return command.

Functions can receive information through the use of parameters, which is a special variable, declared in the function header, which will be responsible for storing the values ​​that will be passed to these functions. These values ​​are the arguments.

To use the arguments (ie, pass some value for functions to work), we must enter the parameter list within the parentheses of the function declaration.

For example, a function that returns an integer, receives an integer and is called func, states:

  • int func (int var) {...}


To invoke by passing the number 2112, for example, we do:

  • func (2112);


var is the parameter, 2112 is an argument.

Now a function that returns nothing is called func2 and receives an integer, a float, and a boolean:

  • void func2 (int var, float num, bool status) {...}


If we want to pass integer 1, float 21.12 and boolean true, into this function, we do:

  • func2 (1, 21.12, true);


Parameter list: var, num and status
Arguments (values): 1, 21.12 and true

See the order: an integer, a float and a boolean! Respect the order of the function header parameter list!

C++ Parameters and Arguments Example

Let's create a function that takes any number, and returns it squared:
#include <iostream>
using namespace std;

float square(float num)
{
    return num*num;
}

int main()
{
    float var;

    cout<<"Number to square: ";
    cin >> var;

    cout<<var<<"*"<<var<<" = " << sqaure(var)<<endl;
}
Note that we pass the var variable, which is a float, to the square() function, which takes a float as its argument.

Although we passed the var variable, what actually happens behind the scenes is that we pass a number, a value, that was entered by the user.

If we pass var = 5, what goes to the function is 5.
It is as if we had done: square(5);

Within the function, this value is stored in the num parameter, ok?
The function does not 'see' the var variable, nor does it know of its existence, it just takes its value and copies it to the float num variable.

C++ Parameters and Arguments

Let's now create a function that takes a number, raises it to the cube, and returns that value.
#include <iostream>
using namespace std;

float cube(float num)
{
    num = num*num*num;

    return num;
}

int main()
{
    float num;

    cout<<"Number to cube: ";
    cin >> num;

    cout<<"Number typed: "<<num<<endl;
    cout<<"Cube: "<< cube(num)<<endl;
    cout<<"num value: "<<num<<endl;
}
We tested this example.
The parameter is num within the function.

When calling the function, also pass a name variable num.
Within the function, we change the value of num.
It used to be num, then it becomes (num * num * num), and we return this new num value.

In main(), we will display the number that the user types (num), the cube (by invoking the cube() function), and then display the value of num again.

For num = 4, the result is:
C++ free tutorial


Note that the value of num has been changed ONLY inside the function!

When we pass an argument to a function, the function makes a copy of it and assigns it to the specific parameter. Inside the function, you changed the parameter value, but the variable original is not changed!

Ah ... now you can understand a little more about main ():
int main () {
...
    return 0;
}


That is, it is a function that takes no argument (since it has no parameter) and returns an integer, in which case it returns 0.

Two things

  1. Universally, when a function returns 0, it's all right, all ok. When your code works ok, it should return 0
  2. In this specific case, main() has no parameters, but yes, there are versions of it getting arguments, we will see later in our course