Unit 5 – Function
Categories of Function according to Return Type
Functions in C can be categorized based on their return types into several groups.
Here are the common categories of functions according to return type:
1. Void Functions (Functions with no return type):
- Void functions do not return any value.
- They are typically used for performing actions or tasks without returning any
result.
- Example:
void greet() {
printf("Hello, world!\n");
}
2. Functions with a return type:
- These functions return basic data types such as int, char, float, double, etc. or
pointers, structures, unions, arrays, etc.
A function in C can be called either with arguments or without arguments. These
functions may or may not return values to the calling functions. All C functions can
be called either with arguments or without arguments in a C program. Also, they
may or may not return any values.
Types of Function According to Arguments and Return
Value
Functions can be differentiated into 4 types according to the arguments passed and
value returns these are:
1. Function with arguments and return value
2. Function with arguments and no return value
3. Function with no arguments and with return value
4. Function with no arguments and no return value
1. Function with Arguments and Return Value
This function takes arguments and returns a value.
Example:
#include <stdio.h>
// Function with arguments and return value
int add(int a, int b) {
return a + b; // Returns the sum of a and b
}
int main() {
int result = add(5, 3); // Call function with arguments
printf("Sum: %d\n", result); // Output: Sum: 8
return 0;
}
Arguments: int a, int b
Return value: int (the sum of a and b)
2. Function with Arguments and No Return Value
This function takes arguments but does not return any value (void).
Example:
#include <stdio.h>
// Function with arguments and no return value
void printSum(int a, int b) {
printf("Sum: %d\n", a + b); // Prints the sum of a and b
}
int main() {
printSum(5, 3); // Call function with arguments
return 0;
}
Arguments: int a, int b
Return value: void (nothing is returned)
3. Function with No Arguments and With Return Value
This function does not take any arguments but returns a value.
Example:
#include <stdio.h>
// Function with no arguments and with return value
int getFive() {
return 5; // Returns the value 5
}
int main() {
int result = getFive(); // Call function with no arguments
printf("Returned value: %d\n", result); // Output: Returned value: 5
return 0;
}
Arguments: None
Return value: int (the value 5)
4. Function with No Arguments and No Return Value
This function takes no arguments and does not return any value (void).
Example:
#include <stdio.h>
// Function with no arguments and no return value
void greet() {
printf("Hello, world!\n"); // Prints a greeting message
}
int main() {
greet(); // Call function with no arguments
return 0;
}
Arguments: None
Return value: void (nothing is returned)
Summary:
Function with arguments and return value: Takes arguments and returns
a value.
Function with arguments and no return value: Takes arguments but
returns void (nothing).
Function with no arguments and with return value: Takes no arguments
but returns a value.
Function with no arguments and no return value: Takes no arguments
and returns nothing (void).
Call by Value Vs Call by reference
-Will be covered in later unit in pointers. But’s lets have an early peek
Call by Value
Call by value in C is where in the arguments we pass value and that value can be
used in function for performing the operation. Values passed in the function are
stored in temporary memory so the changes performed in the function don’t affect
the actual value of the variable passed.
Example:
// C Program to implement
// Call by value
#include <stdio.h>
// Call by value
int sum(int x, int y)
{
int c;
c = x + y;
// Integer value retured
return c;
}
// Driver Code
int main()
{
// Integer Declared
int a = 3, b = 2;
// Function Called
int c = sum(a, b);
printf("Sum of %d and %d : %d", a, b, c);
return 0;
}
Output
Sum of 3 and 2 : 5
Call by Reference
Call by reference is the method in C where we call the function with the passing
address as arguments. We pass the address of the memory blocks which can be
further stored in a pointer variable that can be used in the function. Now, changes
performed in the values inside the function can be directly reflected in the main
memory.
// C Program to implement
// Call by reference
#include <stdio.h>
// Call by reference
void swap(int* x, int* y)
{
int temp = *x;
*x = *y;
*y = temp;
}
// Driver Code
int main()
{
// Declaring Integer
int x = 1, y = 5;
printf("Before Swapping: x:%d , y:%d\n", x, y);
// Calling the function
swap(&x, &y);
printf("After Swapping: x:%d , y:%d\n", x, y);
return 0;
}
Output
Before Swapping: x:1 , y:5
After Swapping: x:5 , y:1
Concept of Local, global, Static and Register Variable
In C programming, variables are categorized based on their scope (where they
can be accessed) and lifetime (how long they exist in memory). The four main
types of variables—local, global, static, and register—are differentiated based on
these aspects.
Here’s an explanation of each:
1. Local Variables
Definition: A local variable is declared inside a function or block and can
only be accessed within that function or block.
Scope: The scope is limited to the function or block in which it is declared.
Lifetime: The lifetime of a local variable is limited to the duration of the
function or block. When the function or block execution is finished, the
variable is destroyed.
Storage: Stored in the stack.
Example:
#include <stdio.h>
void function() {
int x = 10; // Local variable
printf("Value of x: %d\n", x); // Can access 'x' here
}
int main() {
function();
// printf("%d", x); // Error: 'x' is not accessible here
return 0;
}
Here, x is a local variable within the function and cannot be accessed
outside it.
The variables which are declared inside the function, compound statement (or
block) are called Local variables.
a and b are called local variables. They are available only inside the function in
which they are defined (in this case function_1()). If you try to use these variables
outside the function in which they are defined, you will get an error. Another
important point is that variables a and b only exist until function_1() is executing.
As soon as function function_1() ends, variables a and b are destroyed.
2. Global Variables
Definition: A global variable is declared outside of all functions, usually at
the top of the file. It can be accessed by any function in the program.
Scope: The scope is the entire file (and other files if declared with extern).
Lifetime: The lifetime of a global variable is the entire execution time of the
program. It exists from when the program starts until it finishes.
Storage: Stored in the data segment (not the stack).
Example:
#include <stdio.h>
int x = 10; // Global variable
void function() {
printf("Value of x: %d\n", x); // Accessing the global variable
}
int main() {
function();
printf("Value of x in main: %d\n", x); // Accessing the global variable
return 0;
}
Here, x is a global variable and can be accessed both in function and main
because it is defined outside of them.
3. Static Variables
Definition: A static variable retains its value between function calls. It is
initialized only once and keeps its value even after the function call ends. If
it is not initialized, then it is automatically initialized to 0.
Scope: If declared inside a function, the scope is local to the function, but it
retains its value across multiple function calls. If declared outside any
function (at global scope), the scope is limited to that file.
Lifetime: The lifetime is the entire duration of the program, like global
variables, but the scope is more restricted.
Storage: Stored in the data segment, but its memory location is fixed
throughout the program's execution.
Example (Inside a function):
#include <stdio.h>
void counter() {
static int count = 0; // Static variable
count++;
printf("Counter: %d\n", count);
}
int main() {
counter(); // Counter: 1
counter(); // Counter: 2
counter(); // Counter: 3
return 0;
}
Here, count is a static variable that retains its value across calls to counter(),
unlike a regular local variable.
Example (Global scope):
#include <stdio.h>
static int x = 10; // Static variable
void function() {
printf("Value of x: %d\n", x); // Can access the static global variable
}
int main() {
function();
// x = 20; // Error if trying to access 'x' from another file, because it's static
return 0;
}
Here, x is a static global variable. It is restricted to the file it is declared in,
so it cannot be accessed in other files, even though it exists for the entire
program's lifetime.
Output:
12
4. Register Variables
Definition: A register variable is stored in the processor's registers (if
possible) for faster access. However, this is a suggestion to the compiler, and
it may choose to ignore it if there are not enough registers available.
Scope: The scope is limited to the function in which it is declared.
Lifetime: The lifetime is the duration of the function, just like local
variables.
Storage: Stored in the CPU registers (if supported and possible).
Example:
#include <stdio.h>
void function() {
register int x = 10; // Register variable
printf("Value of x: %d\n", x);
}
int main() {
function();
return 0;
}
Here, x is a register variable. It is stored in a register (if the CPU allows it)
for faster access. Note that using register is a hint to the compiler, and the
compiler might store the variable in memory if there are no available
registers.
Summary of Differences:
Type Scope Lifetime Storage
Local Local to a Exists only during
Stack
Variables function/block function/block execution
Accessible by all
Global Exists for the entire duration
functions in the file (or Data segment
Variables of the program
program)
Retains value across function
Static Local to a function (or
calls, exists for the entire Data segment
Variables file if global)
program duration
Register Exists only during function CPU registers
Local to a function
Variables execution (if available)
Key Points to Remember:
Local variables are temporary and only exist during the function execution.
Global variables can be accessed throughout the program, maintaining their
value for the entire program's duration.
Static variables retain their values across function calls, but their scope may
be limited to the function or file.
Register variables are stored in CPU registers for fast access (if possible),
but the compiler decides if they should be stored in registers.
In C programming, if there is a name conflict where the same variable name is
used in different scopes (such as global and local scopes), the variable in the
innermost scope takes precedence over the outer ones. This is due to the concept
of variable shadowing.
Here’s a breakdown of how conflicts are resolved depending on the scope:
1. Local vs Global Variable Conflict (Shadowing)
If you declare a local variable with the same name as a global variable, the local
variable will shadow or hide the global variable within its scope. The local
variable will be used whenever the variable is accessed within that scope. Outside
that scope, the global variable is still accessible.
Example:
#include <stdio.h>
int x = 10; // Global variable
void function() {
int x = 5; // Local variable shadows the global variable
printf("Inside function: x = %d\n", x); // Uses the local variable (x = 5)
}
int main() {
printf("Global x = %d\n", x); // Uses the global variable (x = 10)
function();
printf("Global x after function = %d\n", x); // Still uses the global variable (x =
10)
return 0;
}
Output:
Global x = 10
Inside function: x = 5
Global x after function = 10
Inside the function, the local x (value 5) shadows the global x (value 10), so
the local value is used.
Outside the function, the global x (value 10) is used.
2. Static Variables and Shadowing
If a local variable with the same name as a global variable is declared static, the
static local variable still shadows the global variable within its scope. However,
unlike regular local variables, static variables retain their values across function
calls.
Example:
#include <stdio.h>
int x = 10; // Global variable
void function() {
static int x = 5; // Static local variable (shadows the global variable)
printf("Inside function: x = %d\n", x); // Uses the static local variable (x = 5)
x++; // Modifies the static variable
}
int main() {
printf("Global x = %d\n", x); // Uses the global variable (x = 10)
function();
function(); // Static variable x retains value from previous call
printf("Global x after function = %d\n", x); // Still uses the global variable (x =
10)
return 0;
}
Output:
Global x = 10
Inside function: x = 5
Inside function: x = 6
Global x after function = 10
The static local variable x shadows the global x within the function.
The static x retains its value across calls to function() (hence, the second
call to function() prints x = 6).
The global x remains unchanged outside the function.
3. Function Parameter and Local Variable Conflict
This creates a name conflict because both the local variable and the parameter
exist in the same scope, and the local variable shadows the parameter within the
function.
Not Allowed: Declaring a local variable with the same name as a parameter in
the same scope.
Allowed: Declaring a local variable with the same name as a parameter in a
nested inner scope. For example, declaring a variable with the same name inside a
for loop is allowed. Here, the local variable shadows the parameter variable.
Example:
#include <stdio.h>
void function(int x) { // Function parameter x
int x = 5; // Local variable x, will throw compile error
printf("Inside function: x = %d\n", x); // Uses the local variable x (x = 5)
}
int main() {
function(10); // Passes 10 as argument to the function
return 0;
}
4. Resolution of Conflicts with extern
If you want to refer to a global variable from another file or avoid ambiguity, you
can use the extern keyword to refer to the global variable explicitly.
Example:
// File 1: globals.c
#include <stdio.h>
int x = 10; // Global variable
void function() {
extern int x; // Referencing the global variable explicitly
printf("Inside function: x = %d\n", x); // Uses the global variable (x = 10)
}
// File 2: main.c
#include <stdio.h>
extern int x; // Global variable declaration
int main() {
printf("Global x = %d\n", x); // Uses the global variable (x = 10)
function();
return 0;
}
Here, extern tells the compiler that x is defined in another file, avoiding conflicts
and ensuring the global variable is used.
Key Points to Remember:
1. Variable Shadowing: A local variable (or function parameter) with the
same name as a global variable or static variable will shadow the outer
variable within its scope.
2. Scope: The scope of a variable determines which version of the variable is
used. In general, the inner scope takes precedence over the outer ones.
3. Static Variables: Static variables can be shadowed by local variables, but
they retain their value between function calls.
4. Conflicts in Function: Declaring both a local variable and a function
parameter with the same name is generally not allowed and may result in a
compiler error. It might be allowed with some compilers.
5. extern for Global Variables: Use extern to explicitly refer to global
variables across multiple files and avoid confusion or conflicts.
To avoid conflicts, it's best practice to give variables unique names when possible,
especially in larger programs.