Loading

Bits & Bytes

Archive for the ‘C++’ Category

Arguments and Parameters

The terms argument and parameter are frequently used interchangeably, and there is often confusion about what these two terms mean. Arguments and parameters are two different things, but they are closely related. By definition, an argument is a value or variable that is passed into a function, and a parameter is value or variable that is used inside of a function. For illustration, look at the program below.

#include <iostream>

int Sum(int iP1, int iP2) {
    return iP1 + iP2;
}

int main () {
    int iA1 = 48;
    int iA2 = 24;

    std::cout << Sum(iA1, iA2) << std::endl;

    return 0;
}

The program contains takes in two int values and returns an int that is the sum of them. The two int values that the function takes in are called arguments, while the two values that are used inside the function are called parameters. To clarify this, we have named the variables that we used for the arguments, iA1 and iA2, and the two variables that we used for the parameters, iP1 and iP2. Correspondingly, "iA1, iA2" inside the function call is called the argument list and "int iP1, int iP2" inside the function definition is called the parameter list.

In the example above, the difference between the arguments and paramters is clear. The arguments and parameters refer to totally different memory locations because the arguments are both passed by value. In the program below, we have replaced the variables with the constant literals 48 and 24. In this program, these literals are the arguments.

#include <iostream>

int Sum(int iP1, int iP2) {
	return iP1 + iP2;
}

int main () {

    std::cout << Sum(48, 24) << std::endl;

    return 0;
}

In our last example below, we changed the function a bit; we pass the first argument by reference and use a default argument for the second. So, the arguments are iA and 45. The parameters are still iP1 and iP2. However, the first parameter is only a reference so changing its value changes the value of iA, as we would expect. Passing values by reference is probably one of the sources of confusion between arguments and parameters, but it is easy to understand if we remember that the parameter is only a reference; in fact, we could use any valid C++ data type as a parameter, including pointers, constants, etc.

#include <iostream>

void AddTo(int& iP1, int iP2 = 45) {
    iP1 += iP2;
}

int main () {
	int iA = 16;
	AddTo(iA);
	std::cout << iA << std::endl;

    return 0;
}

Keeping the C++ Console Window Open

One of the first problems that new C++ programmers have is keeping the console window open when writing C++ programs. The easiest solution to this problem is to use the Start Without Debugging option under the Debug the when executing programs. Unfortunately, Microsoft took this option and many others out of the default menus in Visual C++ 2010. To get this option back, select Tools->Settings->Expert Settings. Otherwise, you can use press (Ctrl + F5) to select Start Without Debugging without the menu.

That’s the simplest option for keeping the console window open. However, if you want to keep the window open when running an executable that you create, you will need to add some code to suspend execution and keep the window open. Below, we show one example of how to keep the window open by adding this line of code before the return statement:

system("pause");

The one objection I have to this method is that the system() function is not part of the C++ standard and may not be valid with some C++ compilers.

#include <iostream>

int main()
{
    using namespace std;

    cout << "Hello World!" << endl;

    system("pause");
    return 0;
}

Alternatively, we could use cin.get(); to keep the window open like this:

#include <iostream>

int main()
{
    using namespace std;

    cout << "Hello World!" << endl;

    cin.get();
    return 0;
}

However, using cin.get() can have problems if input is taken directly before it. The problem is that the input in the stream carries over to the cin.get() and causes the program to exit. To prevent this, we can add a call to clear() and ignore(), as we do below.

#include <iostream>

int main()
{
    using namespace std;

    int iInt;
    cin >> iInt;
    cout << "Input = " << iInt << endl;

    cin.clear();
    cin.ignore(0xFFFFFFFF, '\n');
    cin.get();
    return 0;
}

Operator Overloading in C++ – part 2

Continued . . .

Operator overloading offers advantages not only over C, but also over newer object-oriented languages as well. In these languages, we face the same problem. How do we make a sort that works on fundamental types and programmer-defined types? With an object-oriented structure, we can create an interface with a comparison function that all sortable types inherit. Then we can wrap native types, like double, with a class that inherits our interface, say Double. The technique of wrapping fundamental types in objects is often refered to as boxing. Converting from the wrapped type back to the fundamental type is called unboxing.

Boxing

double dTwo = 2.0;
Double qWrappedTwo = new Double(dTwo);

Unboxing

double dTwo = qWrappedTwo.GetValue();

With this technique, a single sort can work on all of our types. However, our data types suffer the memory inefficiency of the wrapping object and speed inefficiency of conversion from boxing and unboxing. Additionally, the conversions back and forth between fundamental and wrapped types is cumbersome. So, we see that templates and operator overloading offer advantages over other languages, particular in terms of speed and memory usage.

For programmers who work with numerical algorithms, operator overloading offers still more benefits. We can overload arithmetical operators to make object conform to the mathematical structures from abstract algebra like fields, rings, etc. For example, if we create a class for complex numbers or matrices, we might want to overload “+”, “*”, etc. It is important to use these operators properly. In this context, operator overloading can be very powerful.

One of the most common uses, and abuses, of operator overloading is the use of “+” to concatenate strings. Unfortunately, this usage is common in many languages and has even been used in the C++ STL string class. The STL has an elegant architecture to it, but this usage only seems to add confusion and further the idea of operator overloading as “syntactic sugar.” My problem with using “+” in string classes is that the usage does not conform to the intended mathematical meaning of the symbol.

Overloading a mathematical operator, like “+”, has many legitimate purposes in programming classes like quaternions, Taylor series, matrices, finite fields, complex numbers, vectors, polynomials, etc. If you are not working with mathematical types, overloading mathematical operators is probably a mistake.