Call by Value and Call by Address / Call by Reference in C
Call by Value and Call by Address Introduction:
We have looked at the Introduction to C Functions and Types of C functions in our earlier posts. In today’s article, We are going to look at Call by Value and Call by Address in C language. The call by address is also referred as the call by reference.
This program is as part of the C-Function series, Please check out all C functions programs Here
Before looking at the call by value and call by reference, We need to understand what is meant by Actual arguments and formal arguments.
Actual Arguments in C:
The parameters which are specified in the function call are called Actual Arguments in C programming language.
For example,
result = sum(10, 20);
In the above function call example, The parameters 10 and 20 are called the Actual Arguments.
Here is another example.
factorial = fact(number);
Here the variable number is called an Actual argument.
We can use the constants, variables, and any expression as the actual arguments. We can even use a function call( function should return appropriate value) as an actual argument.
Formal Arguments in C:
The arguments which are specified in the function definition are called as the formal arguments in C language.
For example,
1 2 3 4 |
int sum ( int num1, int num2) { // function body } |
Here are the arguments num1 and num2 are called formal arguments. As these arguments simply hold/copy the actual arguments which are passed by the function call.
The formal arguments are like the local variables of the function. They are only accessible inside the function and will be freed once the function is completed.
But the formal arguments are by default initialized with the actual parameters, unlike the local variables.
Now that, We know about the actual arguments and formal arguments in C language. Let’s go ahead and look at different types of parameter passing techniques, They are the Call by value and call by reference, or call by address in C.
Call by Value in C Language:
In the Call by value method, We pass the actual arguments in the form of values and the formal arguments get a copy of the actual arguments. ( Actual arguments are copied to formal arguments )
As we are copying the data from actual arguments to formal arguments, They are both stored at different places in the memory. We can check the memory address of the actual argument and formal argument, They will have different memory addresses.
As actual arguments and formal arguments are technically different variables, So any changes we made to the formal arguments inside the function won’t affect the actual arguments. As we are working on the copy of the data (inside the function).
Here is an example to understand how function call by value works in C language.
Example 1: Program to understand the Call by Value in C Language:
Write a C Program to add the number 50 to the given number
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
/* Program: Call by value demonstration. */ #include<stdio.h> int add50(int); int main() { int number, result; printf("Enter a positive number : "); scanf("%d", &number); printf("In main: before function call - Number : %d \n", number); // function call result = add50(number); printf("In main: After function call - Number : %d \n", number); return 0; } int add50(int number) { number = number + 50; printf("In add50: Number is : %d\n", number); return number; } |
Program Output:
Compile and Run the program using the GCC compiler.
1 2 3 4 5 6 7 |
$ gcc call-by-value-1.c $ ./a.out Enter a positive number : 30 In main: before function call - Number : 30 In add50: Number is : 80 In main: After function call - Number : 30 $ |
If you look at the above program, We have defined a function called add50, which accepts a variable called the number and adds 50 to it, and returns the result.
We have called the add50 function by passing the number as a value.
result = add50(number);
So the value of the number is copied to the formal argument number
1 2 3 4 5 6 |
int add50(int number) { number = number + 50; printf("In add50: Number is : %d\n", number); return number; } |
So when we changed the value of the number by adding 50 to it. The formal argument value inside the add50 function is changed.
Code:
number = number + 50;
Output:
In add50: Number is : 80
But the actual arguments value, The value in the main() function is not changed. As we are working on a copy of the actual argument inside the add80 function.
So when we printed the value of the number inside the main() function, We got the number value as 30.
Code:
printf("In main: After function call - Number : %d \\n", number);
Output:
In main: After function call - Number : 30
With this example, We can say if you use the call-by-value method, The changes made for the formal arguments won’t affect the original or actual argument
Example 2: Call by value – Swap two Numbers in C:
Let’s look at one more example to make our understanding concrete.
Here is a program, which tries to swap the two numbers using the function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
/* Program: Swap two numbers : Call by value demonistration. */ #include<stdio.h> void swapNumbers(int, int); int main() { int num1, num2; printf("Enter two positive numbers : "); scanf("%d%d", &num1, &num2); printf("Main: before function call, Num1:%d and Num2:%d \n", num1, num2); swapNumbers(num1, num2); printf("Main: after function call, Num1:%d and Num2:%d \n", num1, num2); return 0; } void swapNumbers(int num1, int num2) { int temp = num1; num1 = num2; num2 = temp; printf("In swapNumbers function, Num1:%d and Num2:%d \n", num1, num2); } |
Related Program – Different Methods to Swap two Numbers in C Language
Program Output:
Compile and run the above program.
1 2 3 4 5 6 7 |
$ gcc call-by-value-2.c $ ./a.out Enter two positive numbers : 44 77 Main: before function call, Num1:44 and Num2:77 In swapNumbers function, Num1:77 and Num2:44 Main: after function call, Num1:44 and Num2:77 $ |
From the program output, We can see that the values of actual arguments num1 and num2 in main() functions are not changed even though we changed the formal arguments inside the swapNumbers functions.
When we called the swapNumbers function( using swapNumbers(num1, num2); ). As we called the swapNumbers function by value, The values of num1 and num2 are copied to the formal arguments ( num1 and num2 of swapNumbers function), So changes made inside the swapNumbers won’t affect the actual arguments.
Call by Reference or Call by Address in C Language:
In the call by reference or call by address method, The actual arguments are passed to the function by address. So while calling the function, We use the address of the actual arguments instead of values.
As we are passing the actual arguments by address, The formal arguments don’t need to copy the value of actual arguments, Instead, they can directly use the actual arguments via the address.
If you pass the actual arguments by address (or reference), Then both formal arguments and actual arguments will share the same memory address. If we make any changes to formal arguments they will be reflected in the actual arguments as well, as both formal arguments and actual arguments are pointing to the same variable(s) in the memory. So we need to be careful while working with the data which is passed through the call by reference.
ℹ️ It is recommended to know the basics of the Pointers in C language to better understand the Call by reference in C.
Let’s look at a couple of examples to understand the call by reference in C:
Example 1: Swap two numbers using Call by Address or Call by Reference in C Language:
Let’s look at the swapNumbers program, Now instead of calling by value, We use the call by reference.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
/* Program: Swap two numbers : Call by value demonistration. */ #include<stdio.h> void swapNumbers(int *, int *); int main() { int num1, num2; printf("Enter two positive numbers : "); scanf("%d%d", &num1, &num2); printf("Main: before function call, Num1:%d and Num2:%d \n", num1, num2); // calling by reference or calling by address // so specifying the '&' swapNumbers(&num1, &num2); printf("Main: after function call, Num1:%d and Num2:%d \n", num1, num2); return 0; } /* SwapNumbers function takes two integer pointers and swaps the numbers. */ void swapNumbers(int *num1, int *num2) { // To access num1 and num2 values // We need to use the de-reference oprator '*' int temp = *num1; *num1 = *num2; *num2 = temp; printf("In swapNumbers function, Num1:%d and Num2:%d \n", *num1, *num2); } |
Program Output:
1 2 3 4 5 6 7 |
$ gcc call-by-reference-1.c $ ./a.out Enter two positive numbers : 500 1000 Main: before function call, Num1:500 and Num2:1000 In swapNumbers function, Num1:1000 and Num2:500 Main: after function call, Num1:1000 and Num2:500 $ |
From the above output, We can see that the changes made in the swapNumbers function are reflected in the main() function.
If we look at the function call, We passed the addresses of actual arguments.
1 |
swapNumbers(&num1, &num2); |
Note that we added the ampersand(&) before our actual arguments, The ampersand is used to pass the address of the variable.
At the receiving side i.e at function definition, We need to use the pointer to store the address of the actual arguments. So we used two pointers to integer as our formal arguments.
void swapNumbers(int *num1, int *num2)
Here the int *num1 and int *num2 are two integer pointers.
ℹ️ We can store the address of a variable in the pointer. So If you use the call by reference, our formal arguments should be a pointer type. We are going to discuss more about the pointers in the Pointers section.
Now the address of actual arguments is stored in the formal arguments. we can access the actual arguments by simply de-referencing ( *) the formal arguments.
So when we changed the values of formal arguments num1 and num2 using the de-reference operator ( *), The original or actual arguments will also change.
1 2 3 |
int temp = *num1; *num1 = *num2; *num2 = temp; |
📢When call by reference or call by address is used, both formal arguments and actual arguments point to the same memory address. Thus making any change to the formal argument will also change the actual argument as well.
Let’s look at another program for call by reference or address.
Example 2: Call by Reference in C Langauge Program:
Write a C Program to subtract 10 from the given number.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
/* Program: Subtract 10 from given number : Call by value demonistration. */ #include<stdio.h> void subtract10(int *); int main() { int num; printf("Enter a positive numbers : "); scanf("%d", &num); printf("Main: before function call, Num:%d \n", num); // calling by reference or calling by address // so specifying the '&' subtract10(&num); printf("Main: after function call, Num:%d \n", num); return 0; } /* subtract10 - subtracts 10 from given number 'num' subtract10 - accepts a integer pointer */ void subtract10(int *num) { *num = *num - 10; printf("In subtract10 function, Num:%d \n", *num); } |
Program Output:
1 2 3 4 5 6 7 8 9 10 11 12 |
$ gcc call-by-reference-2.c $ ./a.out Enter a positive numbers : 50 Main: before function call, Num:50 In subtract10 function, Num:40 Main: after function call, Num:40 $ ./a.out Enter a positive numbers : 100 Main: before function call, Num:100 In subtract10 function, Num:90 Main: after function call, Num:90 $ |
As we can see from the above output When we passed the actual argument by address, The changes made in the subtract10 function is reflected in the main() function.
At the Function call,
1 |
subtract10(&num); |
We used the call by reference or call-by-address for the actual arguments.
At Function definition and declaration,
void subtract10(int *num)
We used the integer pointer to store the address of the actual argument. So our formal argument num1 will get the address of the actual argument num1.
Any changes made to formal arguments via address will reflect in the actual arguments.
num = *num - 10;
Output:
1 2 3 |
Main: before function call, Num:100 In subtract10 function, Num:90 Main: after function call, Num:90 |
📢Make sure to use the appropriate syntaxes for the Pointers and don’t forget to de-reference (*) the pointer variable to access and modify the data.
Call by Value and Call by Address Conclusion:
In this article, We discussed the Call by value and call by Address or call by reference in C language with Example Programs. We also learned about formal arguments and actual arguments in C. We are going to look at the Recursion in C in the next tutorial.
Related Functions Practice Programs:
- Arithmetic Operations using functions
- Fibonacci Series using function
- Factorial of a Number using functions
- Armstrong Number using Function in C language
- Prime number program using Function
- Program to Caclulate Area of Circle using Function
- Program to Check Even or Odd number using Function
- Binary to Decimal Conversion using function in C
- Arithmetic Operations using Functions
- Add Two Numbers using Function
- 100+ C Practice Programs
- C Tutorials Index
10 Responses
[…] have looked at the call by value and call by reference in our earlier posts, In today’s article, We are going to look at the recursion in c language […]
[…] Call by Value and Call by Address / Call by Reference in C Langauge […]
[…] have discussed the Recursion and Call by value and Call by Reference in our Earlier articles, In today’s article, we are going to look at the Functions with […]
[…] readMatrix() function takes three formal arguments, which are rows size, columns size, and A[][] 2D […]
[…] Call by Value and Call by Address / Call by Reference in C Langauge […]
[…] stringReverse function takes a string(i.e character pointer) as a formal argument and reverses the given string and returns it back to the […]
[…] removeWSpacesBWWords function takes two formal arguments. They are input string( inputStr) and Output String( outputStr). This function removes extra white […]
[…] prototype of all functions is the same, They accept three integer pointer variables as formal arguments and perform the respective […]
[…] malloc() function is used to dynamically allocate memory in C Language. It takes size as an argument and allocates the specified number of bytes in the […]
[…] have looked at the Call by value and call by reference in our earlier posts, In today’s article, We are going to look at the Storage Classes in the C […]