Wednesday, 4 April 2012

Passing Data to Functions in C & C++


C and C++ are built on functions. All programs in C/C++ start with a main() function and branch out from there to other functions. Generally, since it's considered poor coding practice to use global variables, you will need a way to pass local variables from one function to another. This blog looks at the different way of passing data to a function.

1. Pass By Value.

The default in C/C++ is to pass the value of a variable to a function. This means the function cannot change the value of the variable in the caller function. Here is some test code to show this point.

int i = 10;
printf("Pass Argument by Value.\n");
printf("Value before function call: %d.\n", i);
ByVal(i);
printf("Value after function call: %d.\n", i);

void ByVal(int Parameter)
{
     // Change won't happen.
     Parameter = 100;
     printf("Value in function: %d.\n", Parameter);
}

>Pass Argument by Value.
>Value before function call: 10.
>Value in function: 100.
>Value after function call: 10.
 
When a variable is passed to a function by value, the language copies the value to the heap—the dynamic runtime memory. The variable in the caller function is thus duplicated—one copy in the caller function and one copy for the called function. This is not an efficient use of resources. It uses up memory and it takes time to copy the data. A better way is to pass a memory address of the variable to the called function.

2. Pass By Reference.

If I declare MyVar as integer type, I can find out its memory address with the & operator. The first method of passing a memory address to a variable uses this operator. I define the function with a parameter of DataType &VariableName.

i = 20;
printf("\nPass Argument by Reference.\n");
printf("Value before function call: %d.\n", i);
printf("Address of i in main: %#X.\n", &i);
ByRef(i);
printf("Value after function call: %d.\n", i);


void ByRef(int &Parameter)
{
     // Value changes.
     Parameter = 200;
     printf("Value in function: %d.\n", Parameter);
     printf("Address of Parameter in function: %#X.\n", &Parameter);
}


>Pass Argument by Reference.
>Value before function call: 20.
>Address of i in main: 0X36EB8C.
>Value in fn: 200.
>Address of Parameter in function: 0X36EB8C.
>Value after function call: 200.

Because the function ByRef function has direct reference to the i variable, it can change the value. You will note the memory address is the same inside the function as it is in the caller function.

3. Pass By Pointer.

The previous example indirectly passed the memory address for the parameter with ByRef(i) instead of ByRef(&i). The function used the & operator. In this example, the caller must pass a pointer—a direct reference to the memory location. The end result is the same.

int* pi = &i;
i = 30;
printf("\nPass Argument by Pointer.\n");
printf("Value before function call: %d.\n", i);
printf("Address of i in main: %#X.\n", pi);
ByPointer(pi);
printf("Value after function call: %d.\n", *pi);

void ByPointer(int* Parameter)
{
     // Value changes.
     *Parameter = 300;
     printf("Value in function: %d.\n", *Parameter);
     printf("Address of Parameter in function: %#X.\n", Parameter);
}

>Pass Argument by Pointer.
>Value before function call: 30.
>Address of i in main: 0X36EB8C.
>Value in fn: 300.
>Address of Parameter in function: 0X36EB8C.
>Value after function call: 300.
 
Calling the function with a pointer, ByPointer(pi), is equivalent to this: ByPointer(&i).

These examples used the integer data type. The code could be modified to use the other built-in data types: char, bool, double, float. For passing an array, especially a character array, to a function, see the next blog entry.

No comments:

Post a Comment