Functions and their Parameters |
|
When a function is called to take care of a task, it may need external values to carry its assignment. For example, if a function is supposed to calculate the perimeter of a square using the Side * 4 formula, the function should receive the value of the side. An external value that is provided to a function is called an argument. Providing a value to a function is referred to as passing the argument. The argument is provided inside the parentheses of the function. When declaring the function that takes an argument, in its parentheses, enter at least the return type of the argument and an optional name. Here is an example: // This is the main project file for VC++ application project // generated using an Application Wizard. #include "stdafx.h" #using <mscorlib.dll> using namespace System; System::Double SquarePerimeter(double s); int _tmain() { // TODO: Please replace the sample code below with your own. Console::WriteLine(S""); return 0; } To define or implement a function that takes an argument, you can use the argument as if it were a locally declared variable as you see fit. When implementing such a function, you must use exactly the name given to the argument. Here is an example: System::Double SquarePerimeter(double s) { return s * 4; } Alternatively, you can define a function after declaring it. In this case, if you declare a function before calling it, you don't have to provide a name for the argument. When implementing the function, you must provide a name for the argument: // This is the main project file for VC++ application project // generated using an Application Wizard. #include "stdafx.h" #using <mscorlib.dll> using namespace System; System::Double SquarePerimeter(double); int _tmain() { // TODO: Please replace the sample code below with your own. Console::WriteLine(S""); return 0; } System::Double SquarePerimeter(double side) { return side * 4; } You can also provide an optional name for the argument when declaring the function. The name used for an argument when declaring and when defining the function don't have to match. In fact, remember that in C++, you don't have to provide a name for the argument.
To call a function that takes an argument, you must provide a value for the argument. Providing a value to a function is also referred to as passing the argument. To pass an argument to a function, you can just provide a constant value. If the argument is a number, you can pass the appropriate value. If the argument is a character, you can pass a character in single-quotes. If the argument is a string, you can provide a word or sentence in double-quotes. Here is an example: // This is the main project file for VC++ application project // generated using an Application Wizard. #include "stdafx.h" #using <mscorlib.dll> using namespace System; System::Double SquarePerimeter(double); int _tmain() { // TODO: Please replace the sample code below with your own. Console::Write("Square Perimeter: "); Console::WriteLine(SquarePerimeter(42.55)); Console::WriteLine(); return 0; } System::Double SquarePerimeter(double side) { return side * 4; } You can also first declare a variable and then assign a function to it. The variable must be declared with the same or compatible value as the function. Just as done with one function, you can call various functions in another function as you judge this necessary. When you call a function, because it holds a value, it is allocated an amount of space in memory, on the stack. As functions are added to the stack, it is also said that the system "winds" the stack. If you call more than one function, they are incrementally added to the stack, in the order they are called. When the functions are not used anymore, that is, when their values are not necessary anymore, the functions must be removed from the stack. This is also said that the system "unwinds" the stack.
When a function doesn't return a value, it is declared as void, as we have seen. If a function doesn't take an argument, it must still have parentheses although the parentheses can be left empty. An alternative is to type void in the parentheses of the function when declaring or defining it. Here is an example: // This is the main project file for VC++ application project // generated using an Application Wizard. #include "stdafx.h" #using <mscorlib.dll> using namespace System; void Welcome(void); int _tmain() { // TODO: Please replace the sample code below with your own. Console::WriteLine(); return 0; } void Welcome(void) { Console::WriteLine("Welcome to Managed C++"); } The optional void keyword in this case indicates that the function doesn't take any argument at all. When calling such a function, you must leave its parentheses empty. Remember that the void keyword in the parentheses is optional. Therefore, in our lessons, we will use or omit it unpredictably.
The functions we have used so far took either no argument or only one. A function that needs various external values to carry its assignment can take more than one argument. Imagine you want to write a program that calculates an item’s purchase price based on the item’s store price added the tax. The tax rate is a percentage value. This means that a tax rate set at 7.50% in C++ terms is equal to 0.075 (because 7.50/100 = 0.075). The tax amount collected on a purchase is taken from an item’s price; its formula is:
The formula of calculating the final price of an item is: Final Price = Item Price + Tax Amount When creating such a function, since you cannot predict the price of an item or the tax rate applied, you would write a function that expects those values. Such a function would take two arguments. To declare or define a function that takes more than one argument, enter the data type followed by a name for each argument, separating them with a comma. If you are only declaring a function before defining it, the name of each argument is optional. Here are examples of declaring functions that take parameters: double CalculateDiscount(double origPrice, double discRate); double PriceAfterDiscount(double origPrice, double discAmount); When implementing the function, you must provide a name for each argument you intend to use. The name of each argument can then be used in the body of the function as if it were a locally declared variable. Here are examples: // This is the main project file for VC++ application project // generated using an Application Wizard. #include "stdafx.h" #using <mscorlib.dll> using namespace System; double CalculateDiscount(double origPrice, double discRate); double PriceAfterDiscount(double origPrice, double discAmount); int _tmain() { // TODO: Please replace the sample code below with your own. Console::WriteLine(); return 0; } double CalculateDiscount(double price, double rate) { double amount; amount = price * rate / 100; return amount; } double PriceAfterDiscount(double price, double amount) { double afterDiscount; afterDiscount = price - amount; return afterDiscount; } To call a function that takes many arguments, from another function, specify the name of the function and its list of arguments (if any) inside of parentheses. When calling the function, you can pass the arguments by their constant values or you can use values from variables. When declaring a function, we have already mentioned that the compiler does not require that you supply a name for each argument, it only needs to know the type of argument(s) and the number of arguments a function takes. This information is completely provided by the presence of a data type. This means that you can declare your functions as follows: double CalculateDiscount(double, double); double PriceAfterDiscount(double, double); double CalculateTaxAmount(double, double); double CalculateNetPrice(double, double); void DisplayResult(double, double, double, double, double); To call a function that takes more than one argument, you must provide a value for each of its arguments, in the exact order they appear in the parentheses of the function.
Consider the following program:
When executed, this program would produce:
The Starter() function receives one argument passed when it is called. The called function also receives the same argument every time. Looking at the result, the argument passed to the function and the local variables declared inside of the called function keep the same value every time the function is called. That is, when the Starter() function is exited, the values remain the same. We know that, when a function is defined, any variable declared locally belongs to the function and its influence cannot expand beyond the presence of the function. If you want a locally declared variable to keep its changed value when its host function is exited, you can declare such a variable as static. To declare a static variable, type the keyword static on the left of the variable’s data type. For example, if you plan to declare a Radius variable as static in an Area() function, you could write:
You should always initialize a static variable before using it; that is, when declaring it. To make the local variables of our Starter() function static, we can declare them as follows:
This time, when executing the program, it would produce:
Notice that, this time, each local variable keeps its newly changed value when the function exits. Since a function’s argument can receive different values as the function is called different times, we can test our program by passing different values to its argument as follows:
The current version of the program would produce:
We saw earlier that, when declaring a function, the compiler needs to know only the name of the function, its return type and its type(s) of argument(s), if any. We saw that, based on this ability of the C++ language, functions could be declared as follows: double CalculateDiscount(double, double); double PriceAfterDiscount(double, double); double CalculateTaxAmount(double, double); double CalculateNetPrice(double, double); void DisplayResult(double, double, double, double, double); The name of a function, its return type, and its list of arguments, if any, is called the function's signature. This signature gives complete information to the compiler regarding each function. The compiler needs this information about each function because it creates a table (or a list) of all functions used in a particular file (whether it is a header file or a source file). When creating this table, the compiler assigns a unique identification (like somebody's driver's license) to each function, using the function's name, its return type, and its argument(s). When creating this table, the compiler uses each function's name and its argument(s), if any:
The ability for two functions to have the exact same name but differ either by their type(s) of argument(s) or by their number of argument(s) allows the compiler to distinguish them. Function Overloading is the ability to have various functions that have the same name but different arguments, either by the number of arguments of each function or by the types of arguments of each function. Here is an example:
Here is the result of running the program:
Whenever a function takes an argument, that argument is required. If the calling function does not provide the (required) argument, the compiler would throw an error. Imagine you write a function that will be used to calculate the final price of an item after discount. The function would need the discount rate in order to perform the calculation. Such a function could look like this:
Since this function expects an argument, if you do not supply it, the following program would not compile:
Here is an example of running the program:
Most of the time, a function such as this CalculateNetPrice() would use the same discount rate over and over again. Therefore, instead of supplying an argument all the time, C++ allows you to define an argument whose value would be used whenever the function is not provided with a value for the argument. To give a default value to an argument, when declaring the function, type the name of the argument followed by the assignment operator, =, followed by the default value. The CalculateNetPrice() function, with a default value, could be defined as:
Here is an example of running the program:
If a function takes more than one argument, you can provide a default argument for each and select which ones would have default values. If you want all arguments to have default values, when defining the function, type each name followed by = and followed by the desired value. Here is an example:
Here is the result produced:
If a function takes more than one argument and you would like to provide default values for those parameters, the order of appearance of the arguments is very important.
When a function receives an argument, it performs one of two actions with regards to the value of the argument. It may modify the value itself or only use the argument to modify another argument or another of its own variables. If you know that a function should not alter the value of an argument, you should let the compiler know. This is a safeguard that serves at least two purposes. First, the compiler will make sure that the argument supplied stays intact; if the function tries to modify the argument, the compiler would throw an error, letting you know that an undesired operation took place. Second, this speeds up execution. To let the compiler know that the value of an argument must stay constant, use the const keyword before the data type of the argument. The double CalculateDiscount() function above receives two arguments, the marked price of an item and the discount rate applied on it. This function uses the two values to calculate the amount of discount that a customer would receive. Since the marked price is set on the item in the store, the function does not modify its value; it only needs it in order to calculate the new price so the customer can see the difference. The function then returns the discount amount. To reinforce this fact and to prevent the CalculateDiscount() function from changing the value of the marked price, you can declare the argument as constant:
If you declare a function before implementing it, make sure you specify the argument as constant in both cases. Once again, only the signature of the function is important. If you are simply declaring the function, the name of the argument is not important, neither is its presence. Therefore, the above CalculateDiscount() function can as well be declared as follows: double CalculateDiscount(const double, double); You can pass just one argument as constant. You can also pass a few or all arguments as constants. It depends on the role of the arguments in the implementation of the function: // This is the main project file for VC++ application project // generated using an Application Wizard. #include "stdafx.h" #using <mscorlib.dll> using namespace std; using namespace System; double RequestOriginalPrice(); double CalculateNetPrice(const double price, const double tax = 5.75, const double discount = 25); int _tmain() { // TODO: Please replace the sample code below with your own. double originalPrice, finalPrice; originalPrice = RequestOriginalPrice(); finalPrice = CalculateNetPrice(originalPrice); Console::WriteLine("After applying a 25% discount and a 5.75% tax rate"); Console::Write("Final Price = {0:C}", __box(finalPrice)); Console::WriteLine(); return 0; } double RequestOriginalPrice() { double OriginalPrice; Console::Write("Enter the original price of the item: "); String *OrigPrice = Console::ReadLine(); OriginalPrice = OrigPrice->ToDouble(0); return OriginalPrice; } double CalculateNetPrice(const double price, const double tax, const double discount) { double discountValue, taxValue, netPrice; discountValue = price * discount / 100; taxValue = tax / 100; netPrice = price - discountValue + taxValue; return netPrice; }
Consider the following program: // This is the main project file for VC++ application project // generated using an Application Wizard. #include "stdafx.h" #using <mscorlib.dll> using namespace std; using namespace System; void Earnings(double thisWeek, double salary) { thisWeek = 42.50; Console::WriteLine("\nIn the Earnings() function,"); Console::WriteLine("Weekly Hours = {0}", __box(thisWeek)); Console::WriteLine("Salary = {0}", __box(salary)); Console::WriteLine("Weekly Salary = {0}", __box(thisWeek * salary)); } int _tmain() { // TODO: Please replace the sample code below with your own. double hours, rate; rate = 15.58; hours = 26.00; Console::WriteLine("In the Main() function,\n"); Console::WriteLine("Weekly Hours = {0}", __box(hours)); Console::WriteLine("Salary = {0}", __box(rate)); Console::WriteLine("Weekly Salary = {0}", __box(hours * rate)); Console::WriteLine("\nCalling the Earnings() function"); Earnings(hours, rate); Console::WriteLine("\nAfter calling the Earnings() function, "); Console::WriteLine("in the Main() function,"); Console::WriteLine("Weekly Hours = {0}", __box(hours)); Console::WriteLine("Salary = {0}", __box(rate)); Console::WriteLine("Weekly Salary = {0}", __box(hours * rate)); Console::WriteLine("\n"); return 0; } This would produce: In the Main() function, Weekly Hours = 26 Salary = 15.58 Weekly Salary = 405.08 Calling the Earnings() function In the Earnings() function, Weekly Hours = 42.5 Salary = 15.58 Weekly Salary: = 662.15 After calling the Earnings() function, in the Main() function, Weekly Hours = 26 Salary = 15.58 Weekly Salary = 405.08 Press any key to continue Notice that the weekly hours and salary values are the same before and after calling the Earnings() function. When you declare a variable in a program, the compiler reserves an amount of space for that variable. If you need to use that variable somewhere in your program, you call it and make use of its value. There are two major issues related to a variable: its value and its location in the memory: The location of a variable in memory is referred to as its address. If you supply the argument using its name, as we have done so far, the compiler only makes a copy of the argument’s value and gives it to the calling function. Although the calling function receives the argument’s value and can use in any way, it cannot (permanently) alter it. C++ allows a calling function to modify the value of a passed argument if you find it necessary. If you want the calling function to modify the value of a supplied argument and return the modified value, you should pass the argument using its reference. To pass an argument as a reference, when declaring the function, precede the argument name with an ampersand “&”. You can pass one or more arguments as reference in the program or pass all arguments as reference. The decision as to which argument(s) should be passed by value or by reference is based on whether or not you want the called function to modify the argument and permanently change its value. Here are examples of passing some arguments by reference:
Once again, the signature of the function is important when declaring the function. The compiler would not care much about the name of an argument. Therefore, the above functions can be declared as follows:
You add the ampersand when declaring a function and/or when defining it. When calling the function, supply only the name of the referenced argument(s). The above would be called with: Area(Side); Decision(Answer, Age); Purchase(DiscountPrice, NewDiscount, Commission); You will usually need to know what happens to the value passed to a calling function because the rest of the program may depend on it. If you want a calling function to modify the value of an argument, you should supply its reference and not its value. Here is an example: // This is the main project file for VC++ application project // generated using an Application Wizard. #include "stdafx.h" #using <mscorlib.dll> using namespace std; using namespace System; void Earnings(double &thisWeek, double salary) { thisWeek = 42.50; Console::WriteLine("\nIn the Earnings() function,"); Console::WriteLine("Weekly Hours = {0}", __box(thisWeek)); Console::WriteLine("Salary = {0}", __box(salary)); Console::WriteLine("Weekly Salary = {0}", __box(thisWeek * salary)); } int _tmain() { // TODO: Please replace the sample code below with your own. double hours, rate; . . . No Change Console::WriteLine("\n"); return 0; } This would produce: In the Main() function, Weekly Hours = 26 Salary = 15.58 Weekly Salary = 405.08 Calling the Earnings() function In the Earnings() function, Weekly Hours = 42.5 Salary = 15.58 Weekly Salary: = 662.15 After calling the Earnings() function, in the Main() function, Weekly Hours = 42.5 Salary = 15.58 Weekly Salary = 662.15 Press any key to continue Notice that, this time, when the weekly hours and the weekly salary are accessed in the _tmain() function the second time, they have been permanently modified.
We have seen that passing an argument as a reference allows the compiler to retrieve the real value of the argument at its location rather than sending a request for a value of the variable. This speeds up the execution of the program. Also, when passing an argument as a constant, the compiler will make sure that the value of the passed argument is not modified. If you pass an argument as reference, the compiler would access the argument from its location. The called function can modify the value of the argument. The advantage is that code execution is faster because the argument gives access to its address. The disadvantage could be that if the calling function modifies the value of the argument, when the function exits, the value of the argument would have (permanently) changed and the original value would be lost (actually, this can be an advantage as we have learned). If you do not want the value of the passed argument to be modified, you should pass the argument as a constant reference. When doing this, the compiler would access the argument at its location (or address) but it would make sure that the value of the argument stays intact. To pass an argument as a constant reference, when declaring the function and when implementing it, type the const keyword, followed by the argument data type, followed by the ampersand operator "&", followed by a name for the argument. When declaring the function, the name of the argument is optional. Here is a function that receives an argument as a constant reference:
You can mix arguments passed by value, those passed as reference, those passed by constant, and those passed by constant references. You will decide, based on your intentions, to apply whatever technique suits your scenario. The following program illustrates the use of various techniques of passing arguments:
|
|
||
Previous | Copyright © 2004-2010 FunctionX, Inc. | Next |
|