Do you think IIT Guwahati certified course can help you in your career?
No
Introduction
C is a powerful programming language that allows developers to create reusable code blocks using user-defined functions. Here, we will learn more about creating and using functions in C.
We'll cover function syntax, parameter passing, return values, and best practices for writing effective functions. Towards the end, you'll have the knowledge and skills to build your custom functions in C.
In C programming, user-defined data types allow programmers to create data types that are customized to meet the specific needs of their programs. Unlike primitive data types (such as int, float, char), user-defined data types are created by the user, giving more control over data structure and organization. Common user-defined data types in C include:
Structures (struct): Allows grouping of different data types under one name. For example, a structure Person might contain a name (string), age (int), and height (float).
Unions (union): Similar to structures but saves memory by allowing different members to share the same memory location.
Enumerations (enum): Defines a set of named integer constants, improving code readability by representing states or options with meaningful names.
Typedef: Simplifies complex type definitions by creating an alias, making code easier to read and write.
Syntax
In C programming language, the syntax of a user-defined function in C is as follows,
return_type function_name (parameter1, parameter2, ..., parameterN)
{
// Function body
return expression; // Optional
The explanation of each part of the syntax is as follows;
'return_type': it is the data type of the value that the function returns to the calling program. If the function returns no value, the return type is 'void.'
'function_name': the function's name can be any valid C identifier.
'parameter1, parameter2, …, parameterN': a comma-separated list of variables or values passed to the function as input parameters.
function body: the statements that make up the function, enclosed in curly braces {}. In this block, the function performs its operations on the input parameters and may or may not return a value.
return expression: an optional statement that returns a value of the specified return type to the calling program. A function that does not have a return statement automatically returns zero (0) for int return types or NULL for pointer return types.
Here's an example of a user-defined function in C which calculates the factorial of a number
C
C
#include <stdio.h> //Function to calculate factorial of a number int find_Factorial(int n) { if (n == 0) { return 1; } else { return n * find_Factorial(n-1); } }
int main() { int num, result; printf("Enter a positive integer: "); scanf("%d", &num); //Calling the factorial function and storing the value in result variable result = find_Factorial(num); //Printing the factorial of a number printf("Factorial of %d = %d", num, result); return 0; }
a. In this example, the find_Factorial function takes an integer n as an input parameter and returns the factorial of that number.
b. The main function calls the find_Factorial function and prints the result.
c. When the program runs, it prompts the user to enter a positive integer stored in the num variable using the scanf function.
d. The find_Factorial function is then called with num as the input parameter, and the result is stored in the result variable.
e. Finally, the printf function displays the result on the screen.
For example, if the user enters 4, the program calculates 4! = 4 x 3 x 2 x 1 = 120 and displays the result Factorial of 4 = 24.
How to use User-Defined Functions in C?
User-defined functions in C are custom functions created by the programmer to perform specific tasks. These functions allow for code modularity, reusability, and better readability. Here's a step-by-step guide to using user-defined functions in C:
Function Declaration (Prototype): This tells the compiler about the function's name, return type, and parameters (if any) before it is actually used in the code. It is written at the beginning of the program or in a header file.
Function Definition: This is where the function's actual logic is written. It includes the function’s return type, name, parameter list, and the code block that defines its behavior.
Function Call: This is how the function is used in the main program or in other functions. When a function is called, it executes and may return a value if its return type is not void.
Here’s a simple example to illustrate how user-defined functions work:
C
C
#include <stdio.h>
// Function Declaration int multiply(int x, int y);
int main() { int result = multiply(4, 5); // Function Call printf("Result: %d\n", result); return 0; }
// Function Definition int multiply(int x, int y) { return x * y; }
The function multiply is declared, defined, and called in the main function.
multiply takes two integers as parameters and returns their product.
Parameter Passing
There are two ways of parameter-passing to a user-defined function in C: pass by value and pass by reference.
1.) Pass by value: In pass by value, the function receives a copy of the value of the argument passed to it. Any changes made to the parameter inside the function are not reflected in the original variable outside the function. Here's an example;
C
C
#include <stdio.h> //Function to calculate square of a number void find_Square(int n) { n = n * n; printf("Square inside function: %d\n", n); }
int main() { int num = 5; //Calling the square function find_Square(num); printf("Original value: %d\n", num); return 0; }
a. In this example, the find_Square function takes an integer n as a parameter and calculates its square.
b. Inside the function, the value of n is squared and printed on the screen.
c. In the main function, the variable num is initialized to 5, and the find_Square function is called with num as the argument.
d. However, the original value of num remains unchanged, as the function only received a copy of its value.
The output of the above code block is
2)Pass by reference: In this, the function receives the address of the variable as the parameter, allowing it to modify the original variable. Here's an example;
C
C
#include <stdio.h> //Function to swap two numbers void swap_Numbers(int *a, int *b) { int temp = *a; *a = *b; *b = temp; }
int main() { int x = 10, y = 20; printf("Before swap: x = %d, y = %d\n", x, y); //Calling the swap function swap_Numbers(&x, &y); printf("After swap: x = %d, y = %d\n", x, y); return 0; }
a. In this example, the swap_Numbers function takes two integer pointers, a and b, as parameters, allowing it to access x and y inside the function using the de-referencing operator *(it is an operator that is used to access the value of a variable stored at a specific memory address pointed to by a pointer variable).
b. The 'swap_Numbers' function then swaps the values of *a and *b using a temporary variable.
c. In the main function, the variables x and y are initialized to 10 and 20, respectively. The swap_Numbers function is called with the addresses of x and y as arguments, and the values of x and y are swapped inside the function.
d. As a result, the printf function displays the values x=20 and y=10 on the screen.
The result of the above code block is
Depending on your requirements, you can choose the appropriate method of passing parameters, such as whether you need to modify the original value.
Return Values
User-defined functions in C can return a value to the calling program using the return statement. The function's return type is declared in the function header, specifying the value type the function will return.
Here's an example where we use the 'return' statement to exit a function prematurely;
C
C
#include <stdio.h> //Function to calculate the factorial of a number int find_Factorial(int n) { if (n < 0) { return -1; } int result = 1; for (int i = 1; i <= n; i++) { result *= i; } return result; }
int main() { int num = 5; //calling the function to calculate the factorial int result = find_Factorial(num); if (result == -1) { printf("Invalid input!\n"); } else { printf("Factorial value: %d\n", result); } return 0; }
a. In this example, the find_Factorial function calculates the factorial of n using a loop.
b. However, if the input n is negative, the function returns -1 using the return statement to indicate an error condition.
c. In the main function, the find_Factorial function is called with num as its argument, and the return value is checked for an error condition using an if statement.
The output of the code block is
In summary, a return statement is a powerful tool that allows you to pass values from a user-defined function in C back to the calling program or to exit a function prematurely.
Scope and Lifetime
The scope of a user-defined function in C is limited to the file in which it is declared. This feature means that the function can only be called from within the file that contains its declaration. However, if you declare the function in a header file, other files can also use it.
The lifetime of a user-defined function in C is the duration for which it remains in memory. Once the program execution is complete, the function is automatically removed from memory. However, the variables defined inside the function have their scope and lifetime.
The variables declared inside a user-defined function in C have a local scope, meaning they are only accessible from within the function. When the function is called, the variables are created in memory and destroyed when the function returns.
For example,
C
C
#include <stdio.h> //Function to add two numbers int add_Numbers(int a, int b) { int sum = a + b; return sum; }
int main() { int num1 = 5; int num2 = 10; //Calling the function to add two numbers int result = add_Numbers(num1, num2); printf("Result: %d\n", result); return 0; }
a. In this example, the add_Numbers function takes two integer parameters, a and b, calculates their sum, and returns the result.
b. The main function calls the add_Numbers function with num1 and num2 as its arguments, and the return value is stored in the result variable.
c. The sum variable inside the add_Numbers function has a local scope and is destroyed once the function returns.
The output of the above code block is
In summary, the scope of a user-defined function in C is limited to the file in which it is declared. Meanwhile, the lifetime of the function is the duration for which it remains in memory during program execution. The variables declared inside a function have a local scope and lifetime and are destroyed once the function returns.
Best Practises
When writing user-defined functions in C programming language, it is necessary to follow best practices to ensure the code is readable, maintainable, and efficient. Some of the best practices are:
Keep the functions short and focused: Each function should perform a specific task. Keeping functions short and focused makes them easier to understand and maintain.
Use descriptive function names: Function names should indicate what the function does. This step helps in making the code more readable.
Use appropriate parameter types and names: The parameters passed to a function should have appropriate data types and meaningful names. This feature helps in making the function more self-documenting.
Use the return statement effectively: The return statement should be used effectively to convey the result of the function. It is recommended to have only one return statement in a function.
Avoid global variables: Global variables can make the code difficult to read and debug. It is recommended to avoid them whenever possible.
Use comments: Use comments to explain the purpose of the function, its inputs, outputs, and any assumptions it makes.
Write error-free code: Ensure that the code is free of any errors or bugs by testing it thoroughly.
Ensure portability: ensure the code is portable across different platforms and compilers.
Follow naming conventions: Follow naming conventions for variables, functions, and other identifiers recommended by the C language standards.
By following these steps, you can write user-defined functions that are more efficient, maintainable, and easier to understand.
Some more examples
1. Find the maximum of two numbers.
C
C
#include <stdio.h> //Function to calculate max number between two numbers int find_Max(int a, int b) { if (a > b) { return a; } else { return b; } }
int main() { int num1 = 5; int num2 = 10; //Calling the function to find the max value int max_num = find_Max(num1, num2); printf("Maximum number: %d\n", max_num); return 0; }
Here, the is_even function takes an integer parameter num, checks if it is even or odd, and returns 1 if it is even and 0 if it is odd. The main function calls the is_even function to check if a given number is even or odd.
The output of the above code block is.
3. Add two numbers.
C
C
#include <stdio.h> //Function to add two numbers int add_Numbers(int a, int b) { int sum = a + b; return sum; }
int main() { int num1 = 5; int num2 = 10; //calling the function to add two numbers int result = add_Numbers(num1, num2); printf("Result: %d\n", result); return 0; }
Modularity: Functions allow you to break down complex programs into smaller, manageable sections, making the code easier to understand and debug.
Code Reusability: A function can be called multiple times, reducing redundancy and minimizing the need to write the same code repeatedly.
Improved Readability: With descriptive function names and separated logic, user-defined functions make the code more organized and easier to follow.
Ease of Maintenance: By organizing code into functions, individual sections can be modified or updated without affecting other parts of the program.
Facilitates Testing and Debugging: Functions can be tested independently, allowing for focused debugging on specific parts of the code.
Disadvantages of User-Defined Functions
Increased Memory Usage: Each function call requires memory for parameters, return addresses, and local variables, which can lead to higher memory consumption.
Performance Overhead: Function calls add a small overhead, especially if the function is called frequently, which may affect the program’s performance.
Complexity in Large Programs: In very large programs, excessive function calls or poorly organized functions can make it difficult to track the flow of the program.
Dependency on Parameters: Functions may depend on specific input parameters, which can make them less flexible or lead to errors if incorrect parameters are passed.
Risk of Overusing Functions: Using too many small functions can make code harder to read and understand, especially if each function has only minimal responsibility.
Frequently Asked Questions
How many types of functions are there in C?
In C programming language, there are four types of functions: function without argument and return value, function with argument but without return value, function without argument but with a return value, and function with argument and with a return value.
What is the difference between user-defined and pre-defined functions in C?
User-defined functions are created by the programmer and are specific to program requirements. In contrast, predefined functions are already provided by the C language and cover a wide range of functionalities.
What is a recursive function in C?
It is a function that calls itself, either directly or indirectly. Recursive functions are useful to solve problems broken down into smaller sub-problems, often leading to more elegant and efficient code.
Conclusion
User-defined functions in C help to organize code by breaking it down into smaller, reusable functions that perform specific tasks. They make the code easier to maintain and improve efficiency. Functions take input parameters, return output values, and have a specific scope and lifetime.
Best practices for writing functions include keeping them short and self-contained, using descriptive names, and avoiding global variables. With this knowledge, you can write your user-defined functions in C to improve your code structure.
To learn more about C programming language, head to;