When a function is called by value, the values of the actual arguments are copied into the formal arguments and the function works with these copied values. As a result, any changes made to the copied value in the called function do not affect the value of the actual argument in the calling function.
By default, functions are called by value in C++. The call by value method is useful when an argument is to be used only for passing information to a function and does not need to modify the original values. Thus, this method provides security by preventing any accidental alterations in the value of the actual argument.
To understand the concept of call by value, consider this example.
Example: A program to demonstrate the call by value mechanism
#include<iostream>
using namespace std;
void inc(int, int); //prototype of inc()
int main ( )
{
int x=-2,y=7;
cout<< “Values before function call in main (): “<<endl;
cout<<“x= “<<X<<” and y= “<<y<<endl;
inc (x,y); // function call
cout<<“Values after function call in main(): “<<endl;
cout<<“x= “<<X<<” and y= “<<y<<endl;
return 0;
}
void inc(int a,int b)
{
a++;
b++;
cout<<“Values within function inc(): “<<endl;
cout<<”a= “<<a<<” and b= “<<b<<endl;
}
The output of the program is
Values before function call in main()
x = -2 and y = 7
Values within function inc() :
a = -1 and b = 8
Values after function call in main()
x = -2 and y = 7
In this example, since x and y are passed by value, their values are copied into the formal arguments a and b. The function inc ()works with a and b, and not with x and y. Hence, the values of x and y remains same in main ().
Default Arguments: Whenever a function is called, the calling function must provide all the arguments specified in the function’s declaration. If the calling function does not provide the required arguments, the compiler raises an error. However, C++ allows a function to be called without specifying all of its arguments. This can be achieved by assigning a default value to the argument. Default value is specified in the function declaration and is used when the value of that argument is not passed while calling the function.
The syntax for providing a default value to an argument is
return_type function_name (type param1 =value1, type paramN = valueN) ;
Default arguments are used in situations where the value of an argument is same in most of the function calls. Default arguments provide a lot of flexibility during function calls. If a function call does not specify an argument, the default value is passed as an argument to the function. In case a function call specifies an argument, the default value is overridden and the specified value is passed to the function.
To understand the concept of default arguments, consider this example.
Example : A program to demonstrate the concept of default arguments
#include<iostream>
using namespace std;
float calc(float tax, float originalval, float disc=25.50);
int main ()
{
int price;
price=calc(4.25,1250.50); //default argument missing
cout<<“Calculated price with default discount value: “;
cout<<price<<endl;
price=calc(4.25,1250.50,15.25);//default argument overridden
cout<<“Calculated price with assigned value : “<<price;
return 0;
}
float calc(float tax, float originalval, float disc)
{
float discvalue = originalval*disc/100;
float taxvalue=tax/100;
float price=originalval – discvalue + taxvalue;
return price;
}
The output of the program is
Calculated price with default discount value: 931.665
Calculated price with assigned value: 1059.84
In this example, the function declaration of calc ()specifies a default value for the third argument disc. In the first call to calc (), only two arguments (4.25,1250.50) are passed. As a result, the third argument disc is assigned the default value 25.50.In the second call to calc (),the third argument is passed explicitly and hence, it overrides the default value.
Note that all the default arguments must be specified at the end of the parameter list. If any default value of an argument is to be omitted, it should be omitted from the end and not in between the argument list. For example, consider the declaration of the function average ();
average (int, int, int = 5,int = 10,int = 15,int = 20);
Some of the invalid function calls to average()are given here.
=> average (1,2, ,4, ,6);
=> average (1,2,3,4, ,6) ;
Since default arguments are missing from in-between the list, an error is raised during the compilation process.
Some of the valid function calls to average()are given here.
=>average(1,2,3,4,5) ;
=>average(1,2,3,4) ;
=>average(1,2);
Since default arguments are missing from the end of the list, no error is raised during the compilation process.
Constant Arguments: When an argument is passed to a function, its value can be modified within the function body. If the user wants the value of an argument to be intact throughout the function then such arguments must be declared as constant. As the value of constant arguments cannot be changed in the called function, an attempt to modify such arguments results in compile-time error. An argument to a function can be made constant by prefixing const keyword to the data type of the argument.
To understand the concept of constant arguments, consider this example.
Example : A program to demonstrate the concept of constant arguments
#include<iostream>
using namespace std;
int sq_area(const int);
int main()
{
int side, area;
cout<<”Enter the side of a square “;
cin>>side;
area=sq_area(side) ;
cout<<”The area of square is “<<area;
return 0;
}
int sq_area(const int s)
{
s++; // invalid as const cannot be modified
return s*s;
}
In this example, the declaration of sq_area()specifies one argument with the const keyword and hence, the value of s cannot be altered within the function body.
Structure as Arguments: Like ordinary variables, structure variables can also be passed by value to a function. To understand the concept of structure arguments, consider this example.
Example : A program to demonstrate the concept of structure variables as arguments
#include<iostream>
using namespace std;
struct details
{
int pcode;
float qty;
float amt;
float total;
} ;
void calc (details) ;
int main ()
{
details d1={1, 15,100,0}; // initializing structure
calc(d1);
cout<<”Total amount in main(): “<<d1.total;
return 0;
}
void calc(details dd)
{
dd.total = dd.amt*dd.qty;
cout<<”Total amount in called function “<<dd.total<<endl;
}
The output of the program is
Total amount in called function : 1500
Total amount in main(): 0
In this example, the structure variable d1 of structure details is passed by value to function calc ().The function calc () calculates the total amount and displays it. Since the structure variable is passed by value, the new value of the data member total of structure details is not reflected in main ().