- C Programming Tutorial
- C - Home
- Basics of C
- C - Overview
- C - Features
- C - History
- C - Environment Setup
- C - Program Structure
- C - Hello World
- C - Compilation Process
- C - Comments
- C - Tokens
- C - Keywords
- C - Identifiers
- C - User Input
- C - Basic Syntax
- C - Data Types
- C - Variables
- C - Integer Promotions
- C - Type Conversion
- C - Type Casting
- C - Booleans
- Constants and Literals in C
- C - Constants
- C - Literals
- C - Escape sequences
- C - Format Specifiers
- Operators in C
- C - Operators
- C - Arithmetic Operators
- C - Relational Operators
- C - Logical Operators
- C - Bitwise Operators
- C - Assignment Operators
- C - Unary Operators
- C - Increment and Decrement Operators
- C - Ternary Operator
- C - sizeof Operator
- C - Operator Precedence
- C - Misc Operators
- Decision Making in C
- C - Decision Making
- C - if statement
- C - if...else statement
- C - nested if statements
- C - switch statement
- C - nested switch statements
- Loops in C
- C - Loops
- C - While loop
- C - For loop
- C - Do...while loop
- C - Nested loop
- C - Infinite loop
- C - Break Statement
- C - Continue Statement
- C - goto Statement
- Functions in C
- C - Functions
- C - Main Function
- C - Function call by Value
- C - Function call by reference
- C - Nested Functions
- C - Variadic Functions
- C - User-Defined Functions
- C - Callback Function
- C - Return Statement
- C - Recursion
- Scope Rules in C
- C - Scope Rules
- C - Static Variables
- C - Global Variables
- Arrays in C
- C - Arrays
- C - Properties of Array
- C - Multi-Dimensional Arrays
- C - Passing Arrays to Function
- C - Return Array from Function
- C - Variable Length Arrays
- Pointers in C
- C - Pointers
- C - Pointers and Arrays
- C - Applications of Pointers
- C - Pointer Arithmetics
- C - Array of Pointers
- C - Pointer to Pointer
- C - Passing Pointers to Functions
- C - Return Pointer from Functions
- C - Function Pointers
- C - Pointer to an Array
- C - Pointers to Structures
- C - Chain of Pointers
- C - Pointer vs Array
- C - Character Pointers and Functions
- C - NULL Pointer
- C - void Pointer
- C - Dangling Pointers
- C - Dereference Pointer
- C - Near, Far and Huge Pointers
- C - Initialization of Pointer Arrays
- C - Pointers vs. Multi-dimensional Arrays
- Strings in C
- C - Strings
- C - Array of Strings
- C - Special Characters
- C Structures and Unions
- C - Structures
- C - Structures and Functions
- C - Arrays of Structures
- C - Self-Referential Structures
- C - Lookup Tables
- C - Dot (.) Operator
- C - Enumeration (or enum)
- C - Structure Padding and Packing
- C - Nested Structures
- C - Anonymous Structure and Union
- C - Unions
- C - Bit Fields
- C - Typedef
- File Handling in C
- C - Input & Output
- C - File I/O (File Handling)
- C Preprocessors
- C - Preprocessors
- C - Pragmas
- C - Preprocessor Operators
- C - Macros
- C - Header Files
- Memory Management in C
- C - Memory Management
- C - Memory Address
- C - Storage Classes
- Miscellaneous Topics
- C - Error Handling
- C - Variable Arguments
- C - Command Execution
- C - Math Functions
- C - Static Keyword
- C - Random Number Generation
- C - Command Line Arguments
- C Programming Resources
- C - Questions & Answers
- C - Quick Guide
- C - Cheat Sheet
- C - Useful Resources
- C - Discussion
Function Call by Reference in C
There are two ways in which a function can be called: (a) Call by Value and (b) Call by Reference. In this chapter, we will explain the mechanism of calling a function by reference.
Let us start this chapter with a brief overview on "pointers" and the "address operator (&)". It is important that you learn these two concepts in order to fully understand the mechanism of Call by Reference.
The Address Operator (&) in C
In C language, a variable is a named memory location. When a variable declared, the compiler allocates a random location in the memory and internally identifies the location with the user-defined name.
To fetch the address at which the variable has been created, we use the address (&) operator.
Example
Take a look at the following example −
#include <stdio.h> int main(){ int x = 10; printf("x: %d Address of x: %d", x, &x); }
Output
This will print the value of x and its address −
x: 10 Address of x: -1990957196
What is a Pointer in C?
A pointer is a variable that stores the address of another variable. To declare a pointer variable, its name is prefixed with the * symbol. The type of the pointer variable and its host variable must be same.
The address is assigned with the & operator. The dereference operator (*) is used with the pointer. It fetches the value of a variable whose address is assigned to the pointer.
Example
The following example demonstrates how referening and dereferencing work in C −
#include <stdio.h> int main(){ int x = 10; int *y = &x; printf("x: %d Address of x: %d\n", x, &x); printf("Address of y: %d \n", &y); printf("Value at address in y: %d\n", *y); }
Output
Run the code and check its output −
x: 10 Address of x: -1742755108 Address of y: -1742755104 Value at address in y: 10
How Does Call by Reference Work in C?
When a function is called by reference, the address of the actual argument variables passed, instead of their values.
Let us define the add() function that receives the references of two variables −
int add(int *x, int *y){ int z = *x + *y; return z; }
When such a function is called, we pass the address of the actual argument.
Example
Let us call the add() function by reference from inside the main() function −
#include <stdio.h> /* function declaration */ int add(int *, int *); int main(){ int a = 10, b = 20; int c = add(&a, &b); printf("Addition: %d", c); } int add(int *x, int *y){ int z = *x + *y; return z; }
Output
When you run this code, it will produce the following output −
Addition: 30
Now let's understand how this code actually works. The main() function passes the address of a and b to the add() function. The addresses of a and b are assigned to the pointer variables x and y.
Now focus on the statement "z = *x + *y;" inside the add() function. Remember that x stores the address of a. The dereference operator in *x and *y fetches the values of a and b respectively, hence z is the addition of a and b in the main() function.
Example: Swap Values with Call by Reference
Let us understand in more detail how the Call by Reference mechanism works, with the help of the following example that interchanges value of two variables.
#include <stdio.h> /* Function definition to swap the values */ /* It receives the reference of two variables whose values are to be swapped */ int swap(int *x, int *y){ int z; z = *x; /* save the value at address x */ *x = *y; /* put y into x */ *y = z; /* put z into y */ return 0; } /* The main() function has two variables "a" and "b" */ /* Their addresses are passed as arguments to the swap() function. */ int main(){ /* local variable definition */ int a = 10; int b = 20; printf("Before swap, value of a: %d\n", a ); printf("Before swap, value of b: %d\n", b ); /* calling a function to swap the values */ swap(&a, &b); printf("After swap, value of a: %d\n", a); printf("After swap, value of b: %d\n", b); return 0; }
Output
When you run this code, it will produce the following output −
Before swap, value of a: 10 Before swap, value of b: 20 After swap, value of a: 20 After swap, value of b: 10
Explanation
Assume that the variables a and b in the main() function are allotted locations with the memory address 100 and 200 respectively. As their addresses are passed to x and y (remember that they are pointers), the variables x, y and z in the swap() function are created at addresses 1000, 2000 and 3000 respectively.
Since "x" and "y" store the address of "a" and "b", "x" becomes 100 and "y" becomes 200, as the above figure shows.
Inside the swap() function, the first statement "z = *x" causes the value at address in "x" to be stored in "x" (which is 10). Similarly, in the statement "*x = *y;", the value at the address in "y" (which is 20) is stored in the location whose pointer is "x".
Finally, the statement "*y = z;" assigns the "z" to the variable pointed to by "y", which is "b" in the main() function. The values of "a" and "b" now get swapped.
The following figure visually demonstrates how it works −
Mixing Call by Value and Call by Reference
You can use a function calling mechanism that is a combination of Call by Value and Call by Reference. It can be termed as "mixed calling mechanism", where some of the arguments are passed by value and others by reference.
A function in C can have more than one arguments, but can return only one value. The Call by Reference mechanism is a good solution to overcome this restriction.
Example
In this example, the calculate() function receives an integer argument by value, and two pointers where its square and cube are stored.
#include <stdio.h> #include <math.h> /* function declaration */ int calculate(int, int *, int *); int main(){ int a = 10; int b, c; calculate(a, &b, &c); printf("a: %d \nSquare of a: %d \nCube of a: %d", a, b, c); } int calculate(int x, int *y, int *z){ *y = pow(x,2); *z = pow(x, 3); return 0; }
Output
When you run this code, it will produce the following output −
a: 10 Square of a: 100 Cube of a: 1000
The Call by Reference mechanism is widely used when a function needs to perform memory-level manipulations such as controlling the peripheral devices, performing dynamic allocation, etc.