C Tutorial (31) : Passing arguments/variables to functions (by value and by address)

If multiple functions are good (they are), and if local variables are good (they are), then you must have a way to share local variables between functions that need to share them (there is a way). You don’t want all functions to have access to all variables because not every function needs access to every variable. If full variable access between functions is needed, you might as well use global variables.

To share data from function to function, you must pass variables from function to function. When one function passes a variable to another function, only those two functions have access to the variable (assuming that the variable is local).

Passing Arguments

When you pass a variable from one function to another, you are passing an argument from the first function to the next. You can pass more than one variable at a time. The receiving function receives the parameters from the function that sent the variables.

Note : The words variable, argument, and parameter are sometimes used interchangeably when passing and receiving values.

c_func_arg

Methods of Passing Arguments

You pass arguments from a function to another function in two ways: by value and by address. Both of these methods pass arguments to a receiving function from a calling function. There is also a way to return a value from a function back to the calling function (see the next tutorial).

Passing by Value

Sometimes passing by value is called passing by copy. Passing by value means that the value of the variable is passed to the receiving function, not the variable itself. Here is a program that passes a value from main() to half():

/* The program demonstrates passing a variable to a function by value. */

#include 

main()
{
int i;

printf("Please enter an integer... "); 
scanf(" %d", &i);

// Now call the half function, passing the value of i
half(i);

// Shows that the function did not alter i's value 
printf("In main(), i is still %d.\n", i);

return(0); // Ends the program
}

/******************************************************************/
/* Sometimes putting dividers like the one above is a nice break between your different functions. */

half (int i)  // Recieves the value of i
{
i = i / 2;

printf("Your value halved is %d.\n", i); 
return; // Returns to main
}

Here is a sample of the program’s output:

Please enter an integer... 28
Your value halved is 14.
In main(), i is still 28.

Study this first line of the half() function:

half(int i)                    /* Receives value of i */

Notice that you must put the data type (int) inside the receiving function’s parameter list. As Figure shows, the contents of i are passed to half(). The i in main() is never changed because only a copy of its value is passed.

c_func_arg_val

The value of i is passed, not the variable i.

If you passed more than one variable separated by commas, all would have to have their data types listed as well, even if they were all the same type. Here is a function that receives three variables: a floating point, a character array, and an integer:

aFun(float x, char name[15], int age)      /* Receives three arguments */

Note : Passing by value protects a variable. If the receiving function changes a passed-by-value variable, the calling function’s variable is left unchanged. Therefore, passing by value is always safe because the receiving function can’t change the passing function’s variables—it can only use them.

If the previous program’s receiving function called its parameter i2, the program would still work the way it does now. The i2 would be local to half(), whereas the i in main() would be local to main().

Passing by Address

When you pass an array to another function, the array is passed by address. Instead of a copy of the array being passed, the memory address of the array is passed. The receiving function then places its receiving parameter array over the address passed. The bottom line is that the receiving function works with the same address as the calling function. If the receiving function changes one of the variables in the parameter list, the calling function’s argument changes as well.

The following program passes an array to a function.

/* The program demonstrates passing an array to a function. */

#include  
#include 

main()
{
char name[15] = "Anukul Verma"; 
change(name);

printf("Back in main(), the name is now %s.\n", name);

return(0); // Ends the program
}

/******************************************************************/
change(char name[15])    // Recieves the value of i
{
// Change the string stored at the address pointed to by name
strcpy(name, "XXXXXXXXXXXXXX"); 
return; // Returns to main
}

This program produces the following output:

Back in main(), the name is now XXXXXXXXXXXXXX.

If you want to override the passing of non-arrays by value, you can force C to pass regular non-array variables by address.

/* The program demonstrates passing a variable to a function by address. */

#include 

main()
{
int i;
printf("Please enter an integer... "); 
scanf(" %d", &i);

// Now call the half function, passing the address of i
half(&i);

// Shows that the function did alter i's value 
printf("In main(), i is now %d.\n", i);

return(0); // Ends the program
}

/******************************************************************/
half (int *i)       // Receives the address of i
{
*i = *i / 2;
printf("Your value halved is %d.\n", *i); 
return; // Returns to main
}

Here is the output from the program:

Please enter an integer... 28
Your value halved is 14.
In main(), i is now 14.

It looks strange, but if you want to pass a non-array by address, precede it in the passing function with an & (address-of) symbol and then put a * (dereferencing) symbol in front of the variable everywhere it appears in the receiving function. If you think you’re now passing a pointer to a function, you’re exactly right.

Note : You put an & before non-array variables but not before array variables that you pass to scanf(). When you call scanf(), you must pass it the address of variables so that scanf() can change the variables. Because strings are arrays, when you get a string from the keyboard, you don’t put an address-of operator before the array name.

Here is a program that passes an integer i by value, a floating-point x by address, and an integer array by address:

/* The program demonstrates passing multiple variables to a function. */

#include 

changeSome(int i, float *newX, int iAry[5]);

main()
{
int i = 10; 
int ctr;
float x = 20.5;
int iAry[] = {10, 20, 30, 40, 50};

puts("Here are main()'s variables before the function:"); 
printf("i is %d\n", i);

printf("x is %.1f\n", x); 
for (ctr = 0; ctr < 5; ctr++)
{
  printf("iAry[%d] is %d\n", ctr, iAry[ctr]);
}

// Now call the changeSome function, passing the value of i
// and the address of x (hence, the &)
changeSome(i, &x, iAry);

puts("\n\nHere are main()'s variables after the function:"); 
printf("i is %d\n", i);

printf("x is %.1f\n", x); 
for (ctr = 0; ctr < 5; ctr++)
{
  printf("iAry[%d] is %d\n", ctr, iAry[ctr]);
}
return(0); // Ends the program
}

/******************************************************************/
changeSome (int i, float *newX, int iAry[5])
{
// All variables are changes, but only the float and array
// remain changed when the program returns to main()
// changed when the program returns to main()

int j;
i = 47;
*newX = 97.6; // Same location as x in main

for (j = 0; j < 5; j++)
{
  iAry[j] = 100 + 100*j;
}
return; // Returns to main
}

Here is the output from the program:

Here are main()'s variables before the function: 
i is 10
x is 20.5 
iAry[0] is 10 
iAry[1] is 20 
iAry[2] is 30 
iAry[3] is 40 
iAry[4] is 50

Here are main()'s variables after the function: 
i is 10
x is 97.6 
iAry[0] is 100 
iAry[1] is 200 
iAry[2] is 300 
iAry[3] is 400
iAry[4] is 500

Don’t pass an array variable by value; C has no way to do that.

 

Function and local-global variables < Prev     Next > Returning values & prototype

Advertisements

2 comments

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s