Define functions in C
n C programming, a function is like a small, reusable block of code designed to perform a specific task. Think of it as a mini-program within your main program. Functions help you organize your code better and avoid repetition. They are written inside curly braces { }, which group together the statements that make up the function. In other programming languages, functions might also be called subroutines or procedures.
Example of real-life scenario:
For example, imagine you have a recipe for making coffee. Instead of writing out the steps to make coffee every time you want a cup, you have a recipe card with the instructions. Each time you need coffee, you just follow the steps on the card. Similarly, in C programming, you create a function to handle a specific task (like calculating the total price of items) so you can use it whenever needed without rewriting the code each time
Syntax of Functions in C:
The syntax of function can be divided into 3 aspects:
1.Function Declaration
2.Function Definition
3.Function Calls
How Does C Function Work?
Working of the C function can be broken into the following steps as mentioned below:
Declaring a function: Declaring a function is a step where we declare a function. Here we define the return types and parameters of the function.
Defining a function:
Calling the function: Calling the function is a step where we call the function by passing the arguments in the function.
Executing the function: Executing the function is a step where we can run all the statements inside the function to get the final result.
Returning a value: Returning a value is the step where the calculated value after the execution of the function is returned. Exiting the function is the final step where all the allocated memory to the variables, functions, etc is destroyed before giving full control to the main function.
1.Function declaration:
Function Declarations
In a function declaration, we must provide the function name, its return type, and the number and type of its parameters. A function declaration tells the compiler that there is a function with the given name defined somewhere else in the program.
In C programming, a function declaration is like giving a heads-up to the compiler about a function you’ll use later in your code. When you declare a function, you need to specify the function’s name, what type of value it will return, and what kind of information (parameters) it needs to perform its task.
syntax:
return_type name_of_the_function (parameter_1, parameter_2);
Example;
int bhanu(int a, int b);

Note:
A function in C must always be declared globally before calling it.
2.Function Definition:
Function Definition
The function definition consists of actual statements which are executed when the function is called (i.e. when the program control comes to the function).
A C function is generally defined and declared in a single step because the function definition always starts with the function declaration so we do not need to declare it explicitly. The below example serves as both a function definition and a declaration.
In C programming, a function definition is where you actually write the code that performs the function’s task. This is where you specify exactly what the function does when it’s called in your program.
syntax:
return_type function_name (para1_type para1_name, para2_type para2_name)
{
// body of the function
}
For example, if you have a function that calculates the area of a rectangle, the definition might look like this:
int calculateArea(int width, int height)
{
return width * height;
}

3.Function Call
Function Call
A function call is a statement that instructs the compiler to execute the function. We use the function name and parameters in the function call.
A function call is how you actually use a function in your program. When you call a function, you tell the program to execute the code inside that function. To do this, you simply use the function’s name and provide any necessary inputs (parameters).
In the below example, the first sum function is called and 10,30 are passed to the sum function. After the function call sum of a and b is returned and control is also returned back to the main function of the program.

Note: Function call is neccessary to bring the program control to the function definition. If not called, the function statements will not be executed.
Example program on c function:
#include <stdio.h>
int calculateArea(int width, int height);
int main() {
int width, height, area;
printf("Enter the width of the rectangle: ");
scanf("%d", &width);
printf("Enter the height of the rectangle: ");
scanf("%d", &height);
area = calculateArea(width, height);
printf("The area of the rectangle is: %d\n", area);
return 0;
}
int calculateArea(int width, int height) {
return width * height;
}
Explanation:
Function Declaration:
int calculateArea(int width, int height);
informs the compiler that there is a function named calculateArea that takes two integers as arguments and returns an integer.
Main Function:
The main function starts by declaring variables for width, height, and area.
It prompts the user to input the width and height of the rectangle.
It then calls the calculateArea function with the user-provided width and height and stores the result in the area variable.
Finally, it prints the calculated area.
Function Definition:
The calculateArea function takes width and height as input and returns their product, which is the area of the rectangle.
Function return type in c:
The return type of a function specifies the type of value the function will return once it has completed its task.
Here’s a brief explanation:
Return Type:
The return type is defined in the function’s declaration and definition.
It tells the compiler what kind of data the function will return. For instance, if a function is declared with int as its return type, it means the function will return an integer value.
Void Return Type: If a function doesn’t need to return any value, you use void as the return type.
This means the function performs its task but doesn’t return any result.
Example:
Function with Return Type:
int add(int a, int b) {
return a + b; // Returns the sum of a and b
}
Here, int is the return type, indicating that the function add will return an integer.
Function with void Return Type:
void printGreeting() {
printf(“Hello, world!\n”); // Prints a greeting but does not return anything
}
Here, void indicates that print
Greeting doesn’t return any value;
it only performs an action (printing a message).
Summary:
Return Type: Specifies the type of value returned by the function (e.g., int, float, char).Void: Used when the function does not return a value.
Function arguments:
Function arguments, or function parameters, are the values you provide to a function so it can perform its task. These arguments allow you to pass data into the function, which it can then use to produce a result.
Key Points:
Function Arguments: Values you pass to a function when you call it. These values are used by the function to perform its operations.
Function Parameters: Variables in the function definition that receive the values passed as arguments.
Category of functions:
In C programming language, functions can be called either with or without arguments and might return values. They may or might not return values to the calling functions.
1.Function with no arguments and no return value
2.Function with no arguments and with return value
3.Function with argument and with no return value
4.Function with arguments and with return value
1.Function with no arguments and no return value:
Description:
This type of function does not take any input parameters and does not return any value. It is typically used to perform an action, such as printing a message or modifying a global variable.
Example
,
#include<stdio.h>
void printMessage() {
printf("Hello, World!\n"); // Print a message to the console
}
int main() {
printMessage(); // Call the function
return 0; // Indicate successful completion
}
printMessage() is a function with no arguments and a void return type, meaning it performs an action but does not return any value.
2. Function with No Arguments and With Return Value:
Description:
This function does not take any input parameters but returns a value to the caller. It can be used to calculate and return a result based on internal logic.
Example:
#include<stdio.h>
int getNumber() {
return 42; // Return an integer value
}
int main() {
int num = getNumber(); // Call the function and store the returned value in num
printf("Number: %d\n", num); // Print the returned value
return 0;
}
Explanation
getNumber() returns an integer value (42) without requiring any input. The returned value is stored in the num variable in the main function.
3. Function with Arguments and With No Return Value:
Description:
This function takes one or more input parameters but does not return a value. It performs an action based on the input parameters, such as modifying data or printing results.
Example
#include<stdio.h>
void printSum(int a, int b) {
printf("Sum: %d\n", a + b); // Print the sum of two integers
}
int main() {
printSum(5, 3); // Call the function with arguments 5 and 3
return 0;
}
Explanation:
printSum(int a, int b) takes two integer parameters and prints their sum. It does not return any value, just performs an action based on the inputs.
4.Function with Arguments and With Return Value:
Description:
This function takes one or more input parameters and returns a value. It can perform a calculation or processing based on the input parameters and provide a result to the caller.
Example
#include<stdio.h>
int multiply(int x, int y) {
return x * y; // Return the product of two integers
}
int main() {
int result = multiply(4, 5); // Call the function with arguments 4 and 5, and store the return value
printf("Product: %d\n", result); // Print the returned value
return 0;
}
Explanation:
multiply(int x, int y) takes two integer parameters, calculates their product, and returns the result. The main function stores the result in result and prints it.
Recursion in C
Recursion is when a function in a program calls itself over and over until it meets a certain condition. Functions that do this are called recursive functions. This approach can simplify solving complex problems by breaking them down into smaller, more manageable pieces.In C programming, recursion is often used for tasks like calculating factorials, generating Fibonacci numbers, or creating subsets, among others.
Explanation with real life examples:
Consider a family tree:
To find a particular person’s ancestors, you start with that person and look at their parents. Each parent has their own set of parents, and so on.
In this analogy:
The process of looking up each person’s parents is like the recursive function call.
The base case is when you reach someone with no further ancestors to look up (like the root of the family tree).
Each time you trace back through the generations, you’re applying the same process of looking up ancestors, which is similar to how a recursive function works.
Syntax
returnType functionName(parameters) {
if (baseCondition) {
// Return base case value
} else {
// Recursive call
return functionName(modifiedParameters);
}
}
C program to print factorial of given number:
#include<stdio.h>
int factorial(int n) {
if (n == 0 || n == 1) {
return 1;
} else {
return n * factorial(n - 1);
}
}
int main() {
int num;
printf("Enter a positive integer: ");
scanf("%d", &num);
if (num < 0) {
printf("Factorial is not defined for negative numbers.\n");
} else {
printf("Factorial of %d is %d\n", num, factorial(num))
return 0;
}
passing arrays to function
In C, when you pass an array to a function, you’re actually passing a pointer to the first element of the array. This means that the function can access and modify the elements of the array directly.
Syntax
To pass an array to a function, you specify the array’s name (which acts as a pointer) and the function’s parameter list. You don’t need to specify the size of the array in the function parameter list
Example:
#include<stdio.h>
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int length = sizeof(numbers) / sizeof(numbers[0]);
printArray(numbers, length);
return 0;
}
Explanation:
Function Declaration (printArray):
void printArray(int arr[], int size) defines a function that takes an array arr and its size as arguments.
The int arr[] notation is equivalent to int *arr, which means the function receives a pointer to the first element of the array.
Function Definition:
Inside printArray, the array elements are accessed using the pointer arr, and the size parameter helps determine the number of elements to process.
Main Function (main):
int numbers[] = {1, 2, 3, 4, 5} initializes an array of integers.
int length = sizeof(numbers) / sizeof(numbers[0]) calculates the number of elements in the array.
printArray(numbers, length) calls the printArray function, passing the array and its size.
When you pass the array, you're passing a reference to the entire array, so any modifications made to the array elements inside the function will affect the original
Storage classes in c
C Storage Classes are used to describe the features of a variable/function. These features basically include the scope, visibility, and lifetime which help us to trace the existence of a particular variable during the runtime of a program.
C language uses 4 storage classes, namely:
1.auto
2.extern
3.static
4.register
1.auto:
This is the default storage class for all the variables declared inside a function or a block. Hence, the keyword auto is rarely used while writing programs in C language. Auto variables can be only accessed within the block/function they have been declared and not outside them (which defines their scope). Of course, these can be accessed within nested blocks within the parent block/function in which the auto variable was declared.
Scope:
Local to the block in which it is defined.
Lifetime:
Exists only while the block is executing.
Initialization:
Automatically initialized to a garbage value if not explicitly initialized.
Usage:
Default storage class for local variables.
Example
void function() {
auto int localVar = 10; // Local to this function
}
2.Extren:
Extern storage class simply tells us that the variable is defined elsewhere and not within the same block where it is used. Basically, the value is assigned to it in a different block and this can be overwritten/changed in a different block as well. So an extern variable is nothing but a global variable initialized with a legal value where it is declared in order to be used elsewhere. It can be accessed within any function/block.
Also, a normal global variable can be made extern as well by placing the ‘extern’ keyword before its declaration/definition in any function/block. This basically signifies that we are not initializing a new variable but instead, we are using/accessing the global variable only. The main purpose of using extern variables is that they can be accessed between two different files which are part of a large program.
Scope:
Global; it can be accessed from other files.
Lifetime:
Exists for the lifetime of the program.
Usage:
Declares a global variable or function that is defined in another file.
Example
int globalVar = 10; // Definition
3.Static
This storage class is used to declare static variables which are popularly used while writing programs in C language. Static variables have the property of preserving their value even after they are out of their scope! Hence, static variables preserve the value of their last use in their scope. So we can say that they are initialized only once and exist till the termination of the program. Thus, no new memory is allocated because they are not re-declared.
Their scope is local to the function to which they were defined. Global static variables can be accessed anywhere in the program. By default, they are assigned the value 0 by the compiler.
Scope: Local to the block in which it is defined, but retains its value between function calls (if used within a function) or is visible throughout the file (if used outside any function).
Lifetime:
Exists for the lifetime of the program.
Initialization:
Automatically initialized to zero if not explicitly initialized.
4.Register
This storage class declares register variables that have the same functionality as that of the auto variables. The only difference is that the compiler tries to store these variables in the register of the microprocessor if a free register is available. This makes the use of register variables to be much faster than that of the variables stored in the memory during the runtime of the program.
If a free registration is not available, these are then stored in the memory only. Usually, a few variables which are to be accessed very frequently in a program are declared with the register keyword which improves the running time of the program. An important and interesting point to be noted here is that we cannot obtain the address of a register variable using pointers.
Scope:
Local to the block in which it is defined.
Lifetime:
Exists only while the block is executing.
Initialization:
Automatically initialized to a garbage value if not explicitly initialized.
Usage:
Suggests that the variable be stored in a CPU register for faster access.
The actual storage location is up to the compiler, and you cannot take the address of a register variable.
Example:
void function() {
register int count = 0; // Suggests storing in a register
}
Local and global variables in C
Local Variables
Scope:
Local to the function or block in which they are defined. They can only be accessed within that function or block.
Lifetime:
Exists only while the function or block is executing.
They are created when the block is entered and destroyed when the block is exited.
Initialization:
Automatically initialized to a garbage value if not explicitly initialized.
Example:
#include<stdio.h>
void function() {
int localVar = 10; // Local variable
printf("Local variable inside function: %d\n", localVar);
}
int main() {
function();
// printf("%d\n", localVar); // Error: localVar not accessible here
return 0;
}
Explanation:
localVar is defined inside function and is not accessible outside it. It is created and destroyed every time function is called.
Global Variables
Scope: Accessible throughout the entire file in which they are declared.
If declared with the extern keyword, they can also be accessed across multiple files.
Lifetime:
Exists for the duration of the program’s execution. They are created when the program starts and destroyed when the program terminates.
Initialization: Automatically initialized to zero if not explicitly initialized.
Example
#include<stdio.h>
int globalVar = 20; // Global variable
void function() {
printf("Global variable inside function: %d\n", globalVar);
}
int main() {
printf("Global variable inside main: %d\n", globalVar);
function();
return 0;
}

Pointer in C
In C, a pointer is a variable that stores the memory address of another variable. Pointers are a powerful feature of C, allowing for direct memory manipulation, efficient array handling, dynamic memory allocation, and more.
Key Concepts:
Declaration and Initialization
A pointer is declared by specifying the type of data it points to, followed by an asterisk (*).
You initialize a pointer by assigning it the address of a variable using the address-of operator (&).
int num = 10;
int *ptr; // Declaration of a pointer to int
ptr = # // Initialization: ptr now holds the address of num
Dereferencing
Dereferencing a pointer means accessing the value stored at the memory address the pointer is pointing to, using the asterisk (*).
int value = *ptr; // Dereferencing ptr to get the value of num
Pointer Arithmetic
You can perform arithmetic operations on pointers, such as incrementing or decrementing them.
This is particularly useful for iterating over arrays.
int arr[] = {10, 20, 30};
int *p = arr; // Points to the first element of arr
Example
printf(“%d\n”, *p); // 10
p++; // Moves to the next integer
printf(“%d\n”, *p); // 20
Pointers and Arrays
An array name acts as a pointer to the first element of the array.
Pointers can be used to access array elements.
int arr[] = {1, 2, 3, 4};
int *p = arr;
for (int i = 0; i < 4; i++) {
printf(“%d “, *(p + i)); // Accessing elements using pointer arithmetic
}
C program to print the address of a variable along with its value:
#include<stdio.h>
int main() {
int num = 42; // Define an integer variable
// Print the value of the variable
printf("Value of num: %d\n", num);
// Print the address of the variable
printf("Address of num: %p\n", (void*)&num);
return 0;
}
Explanation
Variable Definition:
int num = 42;This defines an integer variable num and initializes it with the value 42.
Print Value:
printf("Value of num: %d\n", num);
This prints the value of num, which is 42.
Print Address:
printf("Address of num: %p\n", (void)&num); %p is the format specifier used to print a pointer (memory address).(void)&num casts the address of num to void* to match the %p format specifier. This is a common practice to avoid warnings or errors related to pointer types.When you run this program, it will output the value of num and its memory address, giving you insight into where num is stored
Accessing a value of a variable through pointer
To access the value of a variable through a pointer in C, we should follow these steps:
Declare a pointer variable that will hold the address of the original variable.
Initialize the pointer with the address of the variable using the address-of operator (&).
Dereference the pointer to access or modify the value stored at the address.
Example
#include<stdio.h>
int main() {
int num = 25;
int *ptr = # // Initialize pointer with the address of num
printf("Value of num: %d\n", num);
printf("Address of num: %p\n", (void*)&num);
printf("Value through pointer: %d\n", *ptr);
*ptr = 30; // Modify the value of num through the pointer
printf("New value of num: %d\n", num);
printf("New value through pointer: %d\n", *ptr);
return 0;
}
Explanation of the Reduced Code
Pointer Initialization:
The pointer ptr is initialized directly with the address of num in the declaration.
Print Statements:
Value and address of num are printed directly.
Value accessed through ptr is printed.
After modifying the value through ptr, the updated value is printed both through the pointer and directly.
This condensed version retains all essential functionality while removing redundant code.
Pointer as function Arguments:
Passing the pointers to the function means the memory location of the variables is passed to the parameters in the function, and then the operations are performed. The function definition accepts these addresses using pointers, addresses are stored using pointers.
Arguments Passing with pointers
A pointer to a function is passed in this example. As an argument, a pointer is passed instead of a variable and its address is passed instead of its value. As a result, any change made by the function using the pointer is permanently stored at the address of the passed variable. In C, this is referred to as call by reference.
Example:
#include<stdio.h>
void swap(int* a, int* b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int a = 10, b = 20;
printf("Values before swap function are: %d, %d\n",
a, b);
swap(&a, &b);
printf("Values after swap function are: %d, %d",
a, b);
return 0;
}
Pointer array
In C, a pointer array is a homogeneous collection of indexed pointer variables that are references to a memory location. It is generally used in C Programming when we want to point at multiple memory locations of a similar data type in our C program. We can access the data by dereferencing the pointer pointing to it.
Syntax
pointer_type *array_name [array_size];
Here,
pointer_type: Type of data the pointer is pointing to.
array_name: Name of the array of pointers.
array_size: Size of the array of pointers.
Note: It is important to keep in mind the operator precedence and associativity in the array of pointers declarations of different type as a single change will mean the whole different thing. For example, enclosing *array_name in the parenthesis will mean that array_name is a pointer to an array.
#include<stdio.h>
int main()
{
// declaring some temp variables
int var1 = 10;
int var2 = 20;
int var3 = 30;
// array of pointers to integers
int* ptr_arr[3] = { &var1, &var2, &var3 };
// traversing using loop
for (int i = 0; i < 3; i++) {
printf("Value of var%d: %d\tAddress: %p\n", i + 1, *ptr_arr[i], ptr_arr[i]);
}
return 0;
}
Dynamic Memory Allocation in C using malloc(), calloc(), free() and realloc()
Since C is a structured language, it has some fixed rules for programming. One of them includes changing the size of an array. An array is a collection of items stored at contiguous memory locations.

As can be seen, the length (size) of the array above is 9. But what if there is a requirement to change this length (size)?
For example,
If there is a situation where only 5 elements are needed to be entered in this array.
In this case, the remaining 4 indices are just wasting memory in this array.
So there is a requirement to lessen the length (size) of the array from 9 to 5.
Take another situation. In this, there is an array of 9 elements with all 9 indices filled.
But there is a need to enter 3 more elements in this array. In this case, 3 indices more are required.
So the length (size) of the array needs to be changed from 9 to 12.
This procedure is referred to as Dynamic Memory Allocation in C.
Therefore, C Dynamic Memory Allocation can be defined as a procedure in which the size of a data structure (like Array) is changed during the runtime.
C provides some functions to achieve these tasks.
There are 4 library functions provided by C defined under header file to facilitate dynamic memory allocation in C programming. They are:
malloc()
calloc()
free()
realloc()
1.malloc
In C, malloc (short for “memory allocation”) is a standard library function used to dynamically allocate a block of memory at runtime. It is defined in the header file.
This function is particularly useful when you need to allocate memory whose size is not known at compile time, or when you need to manage memory manually.
Syntaxvoid* malloc(size_t size);size_t size:
The number of bytes to allocate.
Return Value:
malloc returns a pointer to the allocated memory.
If the allocation fails, it returns NULL.

2.calloc() method
“calloc” or “contiguous allocation” method in C is used to dynamically allocate the specified number of blocks of memory of the specified type.
it is very much similar to malloc() but has two different points and these are:
It initializes each block with a default value ‘0’.
It has two parameters or arguments as compare to malloc().
Syntax
ptr = (cast-type*)calloc(n, element-size);
here, n is the no. of elements and element-size is the size of each element

3. free() method
“free” method in C is used to dynamically de-allocate the memory. The memory allocated using functions malloc() and calloc() is not de-allocated on their own. Hence the free() method is used, whenever the dynamic memory allocation takes place. It helps to reduce wastage of memory by freeing it.
Syntax:
free(ptr);

4. realloc() method
“realloc” or “re-allocation” method in C is used to dynamically change the memory allocation of a previously allocated memory. In other words, if the memory previously allocated with the help of malloc or calloc is insufficient, realloc can be used to dynamically re-allocate memory. re-allocation of memory maintains the already present value and new blocks will be initialized with the default garbage value.
Syntax
ptr = realloc(ptr, newSize);
where ptr is reallocated with new size ‘newSize’.
