Common Techniques of Using Parameters

Function Overloading

We know 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 also saw that a function could be declared as follows:

float Area(float, float);

The name of a function, its return type, and its list of arguments, if any, constitute 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 (called a virtual table) 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) (this allows the compiler to perform name mangling).

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. This is the foundation of Function Overloading: 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:

using namespace System;

// Area of a square
float Area(float Side)
{
    return (Side * Side);
}

// Area of a rectangle
float Area(float Length, float Width)
{
    return (Length * Width);
}

int main()
{
    float s, l, w;

    s = 15.25f;
    l = 28.12f;
    w = 10.35f;

    Console::WriteLine("The area of the square is {0}", Area(s));
    Console::WriteLine("\nThe area of the rectangle is {0}", Area(l, w));
    
    return 0;
}

Here is the result of running the program:

The rea of the square is 232.562
The area of the rectangle is 291.042

Press any key to continue...

You can also declare overloaded functions as inline and/or.

Default Arguments

Whenever a function takes an argument, that argument is required. If the calling function doesn't 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:

double CalculateNetPrice(double DiscountRate)
{
    double OrigPrice;

    Console::Write("Please enter the original price: ");
    OrigPrice = double::Parse(Console::ReadLine());

    return OrigPrice - (OrigPrice * DiscountRate / 100);
}

Since this function expects an argument, if you do not supply it, the following program would not compile:

using namespace System;

double CalculateNetPrice(double DiscountRate)
{
    double OrigPrice;

    Console::Write("Please enter the original price: ");
    OrigPrice = double::Parse(Console::ReadLine());

    return OrigPrice - (OrigPrice * DiscountRate / 100);
}

int main()
{
    double FinalPrice;
    double Discount = 15; // That is 25% = 25

    FinalPrice = CalculateNetPrice(Discount);

    Console::WriteLine("\nAfter applying the discount");
    Console::WriteLine("Final Price = {0}", FinalPrice);
    
    return 0;
}

Here is an example of running the program:

Please enter the original price: 250.50

After applying the discount
Final Price = 212.925
Press any key to continue . . .

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:

using namespace System;

double CalculateNetPrice(double DiscountRate = 20);

int main()
{
    double FinalPrice;

    FinalPrice = CalculateNetPrice();

    Console::WriteLine("\nAfter applying the discount");
    Console::WriteLine("Final Price = {0}", FinalPrice);
    
    return 0;
}

double   CalculateNetPrice(double DiscountRate)
{
    double OrigPrice;

    Console::Write("Please enter the original price: ");
    OrigPrice = double::Parse(Console::ReadLine());

    return OrigPrice - (OrigPrice * DiscountRate / 100);
}

Here is an example of running the program:

Please enter the original price: 120.15

After applying the discount
Final Price = 90.1125

Press any key to continue...

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:

using namespace System;

double CalculateNetPrice(double Tax = 5.75, double Discount = 25,
                         double OrigPrice = 245.55);

int main()
{
    double FinalPrice;

    FinalPrice = CalculateNetPrice();

    Console::WriteLine("\nAfter applying the discount");
    Console::WriteLine("Final Price = {0}", FinalPrice);
    
    return 0;
}

double CalculateNetPrice(double Tax, double Discount, double OrigPrice)
{
    double DiscountValue = OrigPrice * Discount / 100;
    double TaxValue = Tax / 100;
    double NetPrice = OrigPrice - DiscountValue + TaxValue;

    Console::WriteLine("Original Price: {0:C}", OrigPrice);
    Console::WriteLine("Discount Rate:  {0:P}", Discount/100);
    Console::WriteLine("Tax Amount:     {0:C}", Tax);

    return NetPrice;
}

Here is the result produced:

Original Price: $245.55
Discount Rate:  25.00 %
Tax Amount:     $5.75

After applying the discount
Final Price = 184.22
Press any key to continue . . .

If a function takes more than one parameter and you would like to provide default values for those parameters, the order of appearance of the arguments is very important.

  1. If a function takes two parameters, you can declare it with default values. We already know how to do that. If you want to provide a default value for only one of the arguments, the argument that would have a default value must be the second in the list. Here is an example:
    double CalculatePrice(double Tax, double Discount = 25);

    When calling such a function, if you supply only one argument, the compiler would assign its value to the first parameter in the list and ignore assigning a value to the second:

    using namespace System;
    
    double CalculateNetPrice(double Tax, double Discount = 25);
    
    int main()
    {
        double FinalPrice;
        double TaxRate = 5.50; // = 5.50%
    
        FinalPrice = CalculateNetPrice(TaxRate);
    
        Console::WriteLine("\nAfter applying a 25% discount and a 5.50% tax rate");
        Console::WriteLine("Final Price = {0:C}\n", FinalPrice);
        
        return 0;
    }
    
    double CalculateNetPrice(double Tax, double Discount)
    {
        double OrigPrice, DiscountValue, TaxValue, NetPrice;
    
        Console::Write("Enter the original price of the item: ");
        OrigPrice = double::Parse(Console::ReadLine());
    
        DiscountValue = OrigPrice * Discount / 100;
        TaxValue = Tax / 100;
        NetPrice = OrigPrice - DiscountValue + TaxValue;
    
        return NetPrice;
    }

    Here is an example of running the program:

    Enter the original price of the item: 250.50
    
    After applying a 25% discount and a 5.50% tax rate
    Final Price = 187.93
    
    Press any key to continue...

    If you define the function and assign a default value to the first argument, if you provide only one argument when calling the function, you would receive an error.

  2. If the function receives more than two arguments and you would like only some of those arguments to have default values, the arguments that would have default values must be at the end of the list. Regardless of how many arguments would or would not have default values, start the list of arguments without those that would not use default values. Here is an example:

    using namespace System;
    
    double RequestOriginalPrice();
    double CalculateNetPrice(double Price, double Tax = 5.75,
                                        double Discount = 25);
    
    int main()
    {
        double OriginalPrice, FinalPrice;
    
        OriginalPrice = RequestOriginalPrice();
        FinalPrice    = CalculateNetPrice(OriginalPrice);
    
        Console::WriteLine("\nAfter applying a 25% discount and a 5.75% tax rate");
        Console::WriteLine("Final Price = {0:C}\n", FinalPrice);
        
        return 0;
    }
    
    double RequestOriginalPrice()
    {
        double OrigPrice;
    
        Console::Write("Enter the original price of the item: ");
        OrigPrice = double::Parse(Console::ReadLine());
        return OrigPrice;
    }
    
    double CalculateNetPrice(double Price, double Tax,
                                         double Discount)
    {
        double DiscountValue, TaxValue, NetPrice;
    
        DiscountValue = Price * Discount / 100;
        TaxValue = Tax / 100;
        NetPrice = Price - DiscountValue + TaxValue;
    
        return NetPrice;
    }

    Here is an example of running the program:

    Enter the original price of the item: 250.50
    
    After applying a 25% discount and a 5.75% tax rate
    Final Price = 187.933
    
    Press any key to continue...

    As you can see, the argument(s) that has(have) default value(s) must be last in the list of arguments.

Constant Arguments

When a function receives an argument, it behaves in one of two manners with regards to the value of the argument; it might 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. 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. Also, 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:

double CalculateNetPrice(const double Price, double Tax = 5.75,
                                    double Discount = 25);

If you declare a function before implementing it, make sure you specify the argument as constant in both cases:

using namespace System;

double RequestOriginalPrice();
double CalculateNetPrice(const double Price, double Tax = 5.75,
                                    double Discount = 25);

int main()
{
    double OriginalPrice, FinalPrice;

    OriginalPrice = RequestOriginalPrice();
    FinalPrice = CalculateNetPrice(OriginalPrice);

    Console::WriteLine("\nAfter applying a 25% discount and a 5.75% tax rate");
    Console::WriteLine("Final Price = {0:C}\n", FinalPrice);
    
    return 0;
}

double RequestOriginalPrice()
{
    double OrigPrice;

    Console::Write("Enter the original price of the item: ");
    OrigPrice = double::Parse(Console::ReadLine());
    return OrigPrice;
}

double CalculateNetPrice(const double Price, double Tax,
                                     double Discount)
{
    double DiscountValue, TaxValue, NetPrice;

    DiscountValue = Price * Discount / 100;
    TaxValue = Tax / 100;
    NetPrice = Price - DiscountValue + TaxValue;

    return NetPrice;
}

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 CalculateNetPrice(const double, double = 5.75,
                                    double = 25);

You can pass just one argument as constant. You can almost pass a few or all arguments as constants. It depends on the role of the arguments in the implementation of the function.

Passing Arguments by Reference

 

Passing by Native Reference

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:

void Area(double &Side); // The argument is passed by reference
bool Decision(char &Answer, int Age); // One argument is passed by reference
// All arguments are passed by reference
float Purchase(float &DiscountPrice, float &NewDiscount, char &Commission);

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:

void Area(double &); 
bool Decision(char &, int );
float Purchase(float &, float &, char &);

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.

Passing by Constant Reference

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:

double CalculateDiscount(const double &Original, double Rate)
{
    return Original * Rate / 100;
}

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:

using namespace System;

double CalculateDiscount(const double &MarkedPrice, double = 20);
double PriceAfterDiscount(const double, const double);
double CalculateTaxAmount(const double &, double);
double CalculateNetPrice(const double &, const double &);
void DisplayResult(double, double, double, double, double);

void RequestOriginalPrice(double &Price)
{
    Console::Write("Enter the original price: $");
    Price = double::Parse(Console::ReadLine());
}

void RequestDiscountRate(double &Discount)
{
    Console::Write("Enter discount rate(0.00 to 100.00): ");
    Discount = double::Parse(Console::ReadLine());
}

void RequestTaxRate(double& Tax)
{
    Console::Write("Enter the tax rate(0.00 to 100.00): ");
    Tax = double::Parse(Console::ReadLine());
}

int main()
{
    double OriginalPrice, DiscountRate, AfterDiscount, TaxRate;
    double DiscountAmount, TaxAmount, NetPrice;

    RequestOriginalPrice(OriginalPrice);
    RequestDiscountRate(DiscountRate);
    RequestTaxRate(TaxRate);

    DiscountAmount = CalculateDiscount(OriginalPrice, DiscountRate);
    AfterDiscount  = PriceAfterDiscount(OriginalPrice, DiscountAmount);
    TaxAmount      = CalculateTaxAmount(AfterDiscount, TaxRate);
    NetPrice       = CalculateNetPrice(AfterDiscount, TaxAmount);

    DisplayResult(OriginalPrice, DiscountAmount,
                  AfterDiscount, TaxAmount, NetPrice);
    
    return 0;
}

double CalculateDiscount(const double &Original, double Rate)
{
    return Original * Rate / 100;
}

double PriceAfterDiscount(const double Original, const double Discount)
{
    return Original - Discount;
}

double CalculateTaxAmount(const double &Discount, double Rate)
{
    return Discount * Rate / 100;
}

double CalculateNetPrice(const double &Discount, const double &TaxAmt)
{
    return Discount + TaxAmt;
}

void DisplayResult(const double OrigPrice, const double DiscAmt,
                   const double Discount, const double TaxAmt,
                   const double FinalPrice)
{
    Console::WriteLine("\nReceipt");
    Console::WriteLine("Original Price:  {0:C}", OrigPrice);
    Console::WriteLine("Discount Amount: {0:C}", DiscAmt);
    Console::WriteLine("After Discount:  {0:C}", Discount);
    Console::WriteLine("Tax Amount:      {0:C}", TaxAmt);
    Console::WriteLine("Net Price:       {0:C}", FinalPrice);
}

Here is an example of running the program:

Enter the original price: $885.95
Enter discount rate(0.00 to 100.00): 40
Enter the tax rate(0.00 to 100.00): 5.75

Receipt
Original Price:  $885.95
Discount Amount: $354.38
After Discount:  $531.57
Tax Amount:      $30.57
Net Price:       $562.14
Press any key to continue . . .

Passing by Tracking Reference

When programming in C++/CLI rather than C++, a tracking reference may be your most regular choice if you want to pass an argument by reference. This is because, as we will learn with classes, a managed object cannot directly use a C++ regular reference. Fortunately, as done for a native reference, you can pass an argument using a tracking reference. To do this, precede the name of the argument with the % operator.

Everything considered, you pass an argument by tracking reference exactly as you would a native reference: the rules are the same. Here are example:

using namespace System;

void GetHourlySalary(double % salary)
{
	Console::Write(L"Hourly Salary: ");
	salary = double::Parse(Console::ReadLine());
}

void GetWeeklyHours(double %);
void CalculateWeeklySalary(double %, double, double);
void ShowPaycheck(double hourly, double hours, double weekly);

int main()
{
        double HourlySalary, WeeklyHours, WeeklySalary;

	Console::WriteLine(L"Payroll Preparation");
	Console::WriteLine(L"Enter the following information");
        GetHourlySalary(HourlySalary);
	GetWeeklyHours(WeeklyHours);
	CalculateWeeklySalary(WeeklySalary, HourlySalary, WeeklyHours);
    
	Console::WriteLine();

	ShowPaycheck(HourlySalary, WeeklyHours, WeeklySalary);
        return 0;
}

void GetWeeklyHours(double % hours)
{
	Console::Write(L"Weekly Hours:  ");
	hours = double::Parse(Console::ReadLine());
}

void CalculateWeeklySalary(double % weekly, double hourly, double hours)
{
	weekly = hourly * hours;
}

void ShowPaycheck(double hourly, double hours, double weekly)
{
	Console::WriteLine(L"Employee Paycheck");
	Console::WriteLine(L"Hourly Salary: {0:C}", hourly);
	Console::WriteLine(L"Weekly Hours:  {0:F}", hours);
	Console::WriteLine(L"Weekly Salary: {0:C}", weekly);
}

This would produce:

Payroll Preparation
Enter the following information
Hourly Salary: 18.42
Weekly Hours:  42.50

Employee Paycheck
Hourly Salary: $18.42
Weekly Hours:  42.50
Weekly Salary: $782.85
Press any key to continue . . .

As mentioned for native references, when an argument is passed by tracking reference, the argument is modified by the function. That is, when the function closes, the parameter passed by tracking reference holds the value as it was changed in the function, if it was changed.

Also, as mentioned for the native references, the ability to pass various parameters by tracking references allows a single function to return more than one value. Here is an example:

using namespace System;

void PreparePayroll(double %, double %);

void CalculateWeeklySalary(double %, double, double);
void ShowPaycheck(double hourly, double hours, double weekly);

int main()
{
        double HourlySalary, WeeklyHours, WeeklySalary;

	Console::WriteLine(L"Payroll Preparation");
	Console::WriteLine(L"Enter the following information");
        PreparePayroll(HourlySalary, WeeklyHours);
	CalculateWeeklySalary(WeeklySalary, HourlySalary, WeeklyHours);
    
	Console::WriteLine();

	ShowPaycheck(HourlySalary, WeeklyHours, WeeklySalary);
        return 0;
}

void PreparePayroll(double % salary, double % hours)
{
	Console::Write(L"Hourly Salary: ");
	salary = double::Parse(Console::ReadLine());

	Console::Write(L"Weekly Hours:  ");
	hours = double::Parse(Console::ReadLine());
}

void CalculateWeeklySalary(double % weekly,
			   const double hourly,
			   const double hours)
{
	weekly = hourly * hours;
}

void ShowPaycheck(double hourly, double hours, double weekly)
{
	Console::WriteLine(L"Employee Paycheck");
	Console::WriteLine(L"Hourly Salary: {0:C}", hourly);
	Console::WriteLine(L"Weekly Hours:  {0:F}", hours);
	Console::WriteLine(L"Weekly Salary: {0:C}", weekly);
}

Just as done for a native reference, you can pass a tracking reference by constant. The main rule is to remember, then, is that the called function cannot modify the value of the argument. Here are examples:

using namespace System;

void PreparePayroll(double %, double %);

void CalculateWeeklySalary(double %, double, double);
void ShowPaycheck(const double %, const double %, const double %);

int main()
{
        double HourlySalary, WeeklyHours, WeeklySalary;

	Console::WriteLine(L"Payroll Preparation");
	Console::WriteLine(L"Enter the following information");
        PreparePayroll(HourlySalary, WeeklyHours);
	CalculateWeeklySalary(WeeklySalary, HourlySalary, WeeklyHours);
    
	Console::WriteLine();

	ShowPaycheck(HourlySalary, WeeklyHours, WeeklySalary);
        return 0;
}

void PreparePayroll(double % salary, double % hours)
{
	Console::Write(L"Hourly Salary: ");
	salary = double::Parse(Console::ReadLine());

	Console::Write(L"Weekly Hours:  ");
	hours = double::Parse(Console::ReadLine());
}

void CalculateWeeklySalary(double % weekly,
			   const double hourly, const double hours)
{
	weekly = hourly * hours;
}

void ShowPaycheck(const double % hourly,
		  const double % hours,
		  const double % weekly)
{
	Console::WriteLine(L"Employee Paycheck");
	Console::WriteLine(L"Hourly Salary: {0:C}", hourly);
	Console::WriteLine(L"Weekly Hours:  {0:F}", hours);
	Console::WriteLine(L"Weekly Salary: {0:C}", weekly);
}

Passing a Pointer as Argument

 

Introduction

As we have seen so far, a function can use one or more arguments in order to carry its assignment. When necessary, a function also declares its own variable(s) to get the desired return value. Here is an example:

using namespace System;

double CalculateNetPrice(double Disc);

int main()
{
    double FinalPrice;
    double Discount = 20;

    FinalPrice = CalculateNetPrice(Discount);

    Console::WriteLine("After applying a 20% discount");
    Console::WriteLine("Final Price = {0:C}\n", FinalPrice);
    
    return 0;
}

double CalculateNetPrice(double Discount)
{
    double OrigPrice;

    Console::Write("Enter the original price: ");
    OrigPrice = double::Parse(Console::ReadLine());

    return OrigPrice - (OrigPrice * Discount / 100);
}

Here is an example of running the program:

Enter the original price: 125.95
After applying a 20% discount
Final Price = $100.76

Press any key to continue . . .

Like other variables, a pointer can be passed to a function. When declaring  and when implementing a function that takes a pointer as an argument, use the asterisk for the argument. Here is an example:

using namespace System;

double CalculateNetPrice(double *);

int main()
{  
    return 0;
}

double CalculateNetPrice(double *Discount)
{
    double OrigPrice;

    Console::Write("Enter the original price: ");
    OrigPrice = double::Parse(Console::ReadLine());

    return OrigPrice - (OrigPrice * *Discount / 100);
}

When calling the function, use the reference(s) to the variable(s). The function will perform its assignment on the referenced variable(s). After the function has performed its assignment, the changed value(s) of the argument(s) will be preserved and given to the calling function. Here is an example:

int main()
{
    double FinalPrice;
    double Discount = 20.00;

    FinalPrice = CalculateNetPrice(&Discount);

    Console::WriteLine("After applying a 20% discount");
    Console::WriteLine("Final Price = {0:C}\n", FinalPrice);
    
    return 0;
}

Here is an example of running the program:

Enter the original price: 250.50
After applying a 20% discount
Final Price = $200.40

Press any key to continue . . .  

Like a reference (native or tracking), when passing a pointer as argument to a function, the function that is receiving the argument is in fact accessing the argument's address. Therefore, like a reference, the called function has the ability to alter the value held by the pointer. The effect is the same as for the reference: if the called function modifies the value of the pointer, that value is permanently changed. This is a feature you can use to have one (even void) function returning more than one value.

Constant Pointers as Arguments

The previous section demonstrates to us that, when passing a pointer as argument, the effect is the same as passing an argument as reference. This shows that, passing a pointer as argument gives the called function direct access to the address of the variable. Besides permanently changing the value of the argument, this process also speeds up code execution. Although there are various good reasons to pass pointers as arguments, sometimes you may not want the called function to modify the value held by the variable. In fact, you can prevent this.

If a function that receives a pointer as argument is not supposed to modify the value of the argument, you can pass the argument as a constant pointer. To do this, type the const keyword on the left side of the data type of the pointer argument. Here is an example:

using namespace System;

double CalculateNetPrice(const double *Disc);

int main()
{
    double FinalPrice;
    double Discount = 20.00;

    FinalPrice = CalculateNetPrice(&Discount);

    Console::WriteLine("After applying a 20% discount");
    Console::WriteLine("Final Price = {0:C}\n", FinalPrice);
    
    return 0;
}

double CalculateNetPrice(const double *Discount)
{
    double OrigPrice;

    Console::Write("Enter the original price: ");
    OrigPrice = double::Parse(Console::ReadLine());

    return OrigPrice - (OrigPrice * *Discount / 100);
}

Passing a Pointer to a Pointer

A regular use of the double pointer is to pass it as argument. This can easily be done as follows:

void ShowValue(int **value)
{
}

A double-pointer is primarily a pointer. It is just a pointer that points to another pointer. If it's passed as argument, you can display its value using Write() or WriteLine() as done above. Here is an example:

void ShowValue(int **value)
{
	Console::WriteLine("Value = {0}", **value);
}

When calling a function that takes a double-pointer, if the variable passed was declared as a (single) pointer, type an ampersand to the left of the argument. Here is an example:

using namespace System;

void ShowValue(int **value)
{
    Console::WriteLine("Value = {0}", **value);
}

int main()
{
    int *vl = new int(428);

    ShowValue(&vl);
    
    return 0;
}

This would produce:

Value = 428
Press any key to continue...

Passing an Argument as a Reference to a Pointer

Another technique you can use it to pass an argument as a reference to a pointer. You start by passing the argument as a pointer but, to indicate that it in fact is a reference, you precede the name of the parameter with the & operator. Here is an example:

double CalculateNetPrice(double *&dicount);

When defining the function, use the parameter as a pointer. Here is an example:

double CalculateNetPrice(double *&Discount)
{
    double OrigPrice;

    Console::Write("Enter the original price: ");
    OrigPrice = double::Parse(Console::ReadLine());

    return OrigPrice - (OrigPrice * *Discount / 100);
}

When calling the function, the argument must be passed as a pointer and not as a regular variable. Here is an example:

using namespace System;

double CalculateNetPrice(double *&);

int main()
{  
    double FinalPrice = 0.00;
    double *Discount  = new double(20.00);

    FinalPrice = CalculateNetPrice(Discount);

    Console::WriteLine("After applying a 20% discount");
    Console::WriteLine("Final Price = {0:C}\n", FinalPrice);
    return 0;
}

double CalculateNetPrice(double *&Discount)
{
    double OrigPrice;

    Console::Write("Enter the original price: ");
    OrigPrice = double::Parse(Console::ReadLine());

    return OrigPrice - (OrigPrice * *Discount / 100);
}

Once again, keep in mind that, when a function receives a either pointer, a reference (native or tracking), or a reference to a pointer as argument, if that function modifies the value of the argument, when the function exits, the argument would be returned with the new value. You can use this characteristic to return many values from a single function.

Passing an Argument as a Handle

Instead of passing an argument as pointer, you can pass it as a handle. To do this, in the parentheses of the function, precede the argument's name with a cap operator. Here is an example:

double CalculateNetPrice(double ^Discount)
{
}

In the body of the function, process the argument as if it were a pointer. For example, to access its value, precede it with an asterisk. Here is an example:

double CalculateNetPrice(double ^Discount)
{
    double OrigPrice;

    Console::Write("Enter the original price: ");
    OrigPrice = double::Parse(Console::ReadLine());

    return OrigPrice - (OrigPrice * *Discount / 100);
}

As mentioned for the other arguments, if you are only declaring the function without defining it, in its parentheses, only the data type and the ^ operator are necessary. The name of the argument is important only when implementing the function. Here is an example:

using namespace System;

double CalculateNetPrice(double ^);

int main()
{  
    double FinalPrice;
    double Discount = 20.00;

    FinalPrice = CalculateNetPrice(Discount);

    Console::WriteLine("After applying a 20% discount");
    Console::WriteLine("Final Price = {0:C}\n", FinalPrice);
    return 0;
}

double CalculateNetPrice(double ^Discount)
{
    double OrigPrice;

    Console::Write("Enter the original price: ");
    OrigPrice = double::Parse(Console::ReadLine());

    return OrigPrice - (OrigPrice * Discount / 100);
}

Previous Copyright © 2006-2025, FunctionX Monday 14 October 2024, 10:12 Next