Functions

Introduction

In programming, a function is a block of code that performs a specific task and can be called from other parts of a program. It can take input (arguments), perform some operations on them, and then return a result. Functions are used to modularize code, improve code readability, and reduce code duplication.

Syntax:

Here’s the syntax for a function in C programming language:

return_type function_name(argument1, argument2, ..., argumentN) {
    // code to perform the task
    return result;
}
  • return_type specifies the type of data that the function will return. For example, it could be int, float, double, char, or void (if the function doesn’t return anything).
  • function_name is the name of the function. It should be a descriptive name that indicates what the function does.
  • argument1, argument2, ..., argumentN are the input arguments that the function takes. They are optional, but if the function requires input, then it should specify the data types and names of the arguments inside the parentheses.
  • The body of the function is enclosed in curly braces {}. This is where you write the code that performs the task.
  • return statement is used to return a value from the function. If the function doesn’t return anything, then the return type should be void and no return statement is necessary.

Example:

Suppose you are designing a program to perform some mathematical calculations on a set of numbers. Rather than writing the code for each calculation directly in your main program, you can define functions to perform each calculation and then call those functions from your main program.

Here’s an example program that uses functions to perform some mathematical calculations:

#include <stdio.h>

int sum(int a, int b) {
    return a + b;
}

int product(int a, int b) {
    return a * b;
}

int main() {
    int x = 5;
    int y = 7;
    int z;

    z = sum(x, y);
    printf("Sum of %d and %d is %d\n", x, y, z);

    z = product(x, y);
    printf("Product of %d and %d is %d\n", x, y, z);

    return 0;
}

In this program, we define two functions called sum and product, which take two integer arguments and return the sum and product of those arguments, respectively.

In the main function, we create two integer variables called x and y, and then call the sum function with those variables as arguments to compute the sum of x and y. We store the result of the sum function in a variable called z, and then use printf to print out the result.

We then call the product function in a similar way to compute the product of x and y, and again use printf to print out the result.

When we run this program, the output will be:

Sum of 5 and 7 is 12
Product of 5 and 7 is 35

Declaring, Defining and Calling

In C programming, a function needs to be declared, defined, and called in order to be executed. Here is what each of these steps means:

  • Declaring a Function: Before you can use a function in your program, you need to declare it. A function declaration tells the compiler about the function name, return type, and parameter list. It does not contain the actual code for the function. Here’s an example of declaring a function:
int max(int a, int b);  // function declaration
  • Defining a Function: After declaring a function, you need to define it. The function definition contains the actual code that performs the function’s task. It includes the function header, which specifies the function name, return type, and parameter list, as well as the function body, which contains the code that performs the function’s task. Here’s an example of defining a function:
int max(int a, int b) {  // function definition
    if (a > b)
        return a;
    else
        return b;
}
  • Calling a Function: Once you have declared and defined a function, you can call it in your program to perform its task. To call a function, you simply provide its name and the arguments it requires (if any) in parentheses. The function then executes and returns its result (if it has a return value). Here’s an example of calling a function:
result = max(x, y);  // calling the max function

In summary, declaring a function tells the compiler about the function name, return type, and parameter list. Defining a function provides the actual code that performs the function’s task. Calling a function executes the function and returns its result.

Here’s an example code of with demonstration.

#include <stdio.h>

// function declaration or prototyping
int max(int a, int b);

int main() {
    int x = 5, y = 10, result;
    
    // calling the max function
    result = max(x, y);
    
    // printing the result
    printf("The maximum of %d and %d is %d\n", x, y, result);
    
    return 0;
}

// function definition
int max(int a, int b) {
    if (a > b)
        return a;
    else
        return b;
}

Function Arguments

If a function is to use arguments, it must declare variables that accept the values of the arguments. These variables are called the formal parameters of the function. They behave like other local variables inside the function and are created upon entry into the function and destroyed upon exit.

As shown in the following function, the parameters are declared inside the parentheses following the function name. The declaration consists of the parameter type, followed by the parameter name. For example:

int add(int a, int b) {
  return a + b;
}

In the above example, the function add takes two integer parameters a and b.

When a function is called, the arguments are passed as values or references to the corresponding parameters. For example:

int result = add(2, 3);

In this example, the function add is called with two integer arguments, 2 and 3, which are passed to the parameters a and b respectively.

In C, there are several ways to pass arguments to a function, including call by value, call by reference. The choice of passing mechanism depends on the specific requirements of the function and the program.

Call by Value and Call by Reference

Call by value and call by reference are two different ways of passing function arguments to a function in C.

  • In call by value, the function argument is copied into the formal parameter of the function. In this case, changes made to the parameter have no effect on the argument. For Example
void increment(int x) {
    x = x + 1;
    printf("Inside function: %d\n", x);
}

int main() {
    int num = 5;
    increment(num);
    printf("Outside function: %d\n", num);
    return 0;
}
 

In the above example, the increment() function takes an integer argument x by value. The function increments the value of x by 1 inside the function, but this change is not reflected in the original value of num outside the function.

  • In call by reference, the function argument is passed by reference, which means that a reference or pointer to the argument is passed to the function. The function can modify the original value of the argument passed to it. Changes made to the argument inside the function are reflected in the original value of the argument outside the function. For Example
void increment(int *x) {
    (*x)++;
    printf("Inside function: %d\n", *x);
}

int main() {
    int num = 5;
    increment(&num);
    printf("Outside function: %d\n", num);
    return 0;
}

Passing Array to a Function

In C/C++, passing an array to a function is different from passing a normal variable, Let’s understand this.

When you pass a normal variable to a function, a copy of the variable is created and passed to the function. Any changes made to the variable inside the function are only reflected in the copy, and not in the original variable outside the function.

However, when you pass an array to a function as an argument, what actually passed is the address of the first element of array. This is an exception to the call by value parameter passing convention. In this case the function can modify the contents of the array and those modifications will be reflected in the original array that was passed to the function.

Here’s an example to illustrate the difference:

#include <stdio.h>

void changeVar(int *x) {
    x += 1;
}

void changeArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        arr[i] += 1;
    }
}

int main() {
    int x = 5;
    changeVar(x);
    printf("%d\n", x);  // This will output 6

    int arr[] = {1, 2, 3};
    int size = sizeof(arr) / sizeof(arr[0]);
    changeArray(arr, size);
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);  // This will output 2 3 4
    }
    printf("\n");
    return 0;
}

Another example, converting lower case to upper case

#include <stdio.h>
#include <ctype.h>  // We need this library for the toupper() function

void toUpperCase(char str[]) {
    int i = 0;
    while (str[i] != '\0') {
        str[i] = toupper(str[i]);
        i++;
    }
}

int main() {
    char str[] = "hello world";
    printf("Before: %s\n", str);  // This will output "hello world"
    toUpperCase(str);
    printf("After: %s\n", str);  // This will output "HELLO WORLD"
    return 0;
}

argc and argv Arguments to main()

Sometimes it is useful to pass information into a program when you run it. Generally you pass information into the main() function via command line arguments.

There are two special built in arguments, argv and argc, that are used to receive command line arguments.

  • argc is an integer that represents the number of command-line arguments passed to the program. The first argument, argv[0], is always the name of the program itself.
  • argv is an array of strings or an array of pointers to characters, where each element is a command-line argument passed to the program. The command-line arguments are separated by spaces.

Here’s an example program that demonstrates how to use argc and argv:

#include <stdio.h>

int main(int argc, char *argv[]) {
    printf("Number of command-line arguments: %d\n", argc);

    printf("Command-line arguments:\n");
    for (int i = 0; i < argc; i++) {
        printf("%d: %s\n", i, argv[i]);
    }

    return 0;
}

If we compile this program and run it with command-line arguments, we’ll see output like this:

$ gcc example.c -o example
$ ./example foo bar baz
Number of command-line arguments: 4
Command-line arguments:
0: ./example
1: foo
2: bar
3: baz

In this example, we pass three command-line arguments to the program: foo, bar, and baz. The program prints out the number of arguments (4, including the program name), and then prints each argument and its index.

The return Statement

The return statement has two important use cases, First, it cause an immediate exit from the function that it is in. Second, it may be used to return a value.

Exit early and Return a value

  • To exit the function early: A function can also use the return statement to exit the function early if certain conditions are met. This can be useful in cases where the function cannot complete its operation due to some error or unexpected condition. For example, a function that searches for a specific value in an array can use the return statement to exit the function early if the value is found, as follows:
int find_index(int array[], int size, int value) {
    for (int i = 0; i < size; i++) {
        if (array[i] == value) {
            return i;
        }
    }
    return -1; // Return -1 if value not found
}

In this example, the find_index function searches for the index of the first occurrence of value in the array and returns the index if it is found using the return statement. If the value is not found, the function returns -1 using another return statement after the loop.

  • To return a value from the function: A function can perform some operations on its inputs and return a result to the calling code using the return statement. For example, a function that adds two integers and returns the result can use the return statement as follows:
int add(int a, int b) {
    int result = a + b;
    return result;
}

In this example, the add function calculates the sum of a and b and returns the result to the calling code using the return statement.

Returning Pointers

Function of Type void

A function of type void is a function that does not return any value. This means that the function performs some operations or tasks, but it does not produce any result or output that can be used by the calling code.

Here is an example of a function of type void:

#include <stdio.h>

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    int x = 5;
    int y = 10;

    printf("Before swap: x = %d, y = %d\n", x, y);

    swap(&x, &y);

    printf("After swap: x = %d, y = %d\n", x, y);

    return 0;
}

Functions of type void can be used to perform operations that update the state of a program or data structure, but do not need to return a value. In this case, the swap function modifies the values of its input arguments, which allows the calling code to access the updated values after the function call.

What does main( ) Return?

The main() function in C/C++ is a special function that serves as the entry point for a program. It is called by the operating system when the program is run, and it is the first function to be executed.

In C/C++, the main() function is declared with a return type of int, which means that it is expected to return an integer value to the operating system when it finishes executing. The return value is a status code that indicates whether the program terminated successfully or encountered an error.

By convention, a main() function that terminates without errors returns a value of 0, which signifies success. However, you can choose to return any integer value that makes sense for your program, depending on how you want to handle success and failure cases.

Here’s an example of a main() function that returns an integer value:

#include <stdio.h>

int main() {
    printf("Hello, World!\n");

    return 0; // Return 0 to indicate success
}

In this example, the main() function prints the message “Hello, World!” to the console using the printf() function, and then returns 0 to the operating system to indicate that the program has completed successfully.

Recursion

Recursion is a technique in computer programming where a function calls itself repeatedly until it reaches a base case. In other words, recursion is a way of solving a problem by breaking it down into smaller sub-problems that can be solved using the same approach.

Here’s an example of a recursive function in C that calculates the factorial of a given integer:

#include <stdio.h>

int factorial(int n) {
    if (n == 0) {
        return 1;  // base case
    } else {
        return n * factorial(n - 1);  // recursive case
    }
}

int main() {
    int num = 5;
    int result = factorial(num);
    printf("%d! = %d\n", num, result);
    return 0;
}

Advantages and Disadvantages of Recursion

Recursion is a powerful programming technique that can simplify complex problems by breaking them down into smaller subproblems. Here are some advantages and disadvantages of using recursion:

Advantages:

  1. Clarity and simplicity: Recursion can make code easier to read and understand, especially for problems that involve repetitive or complex logic.
  2. Modularity and reusability: Recursion allows you to write modular code that can be reused in different contexts.
  3. Efficiency: In some cases, recursion can be more efficient than iterative solutions, especially when dealing with problems that have a recursive structure.

Disadvantages:

  1. Stack overflow: Recursion can lead to stack overflow errors if the function calls itself too many times without returning.
  2. Performance: Recursion can be less efficient than iterative solutions for problems that don’t have a recursive structure, due to the overhead of function calls.
  3. Debugging: Recursion can be harder to debug than iterative solutions because of the nested function calls.

Overall, recursion is a powerful tool that can be very useful in the right situations. However, it’s important to use it judiciously and understand its limitations to avoid potential pitfalls.

Function Prototypes

A function prototype is a declaration of a function that specifies its name, return type, and the number and types of its parameters. It is used to inform the compiler about the function’s signature before the function is actually defined or called.

Function prototypes are typically placed in a header file that can be included in multiple source files. This allows the function to be used across different parts of a program without having to redefine the function’s signature in each source file.

Here is an example of a function prototype:

int add(int a, int b);

Function Prototypes are generally same as function declaration, which was also discussed in the above(3) section

    Leave a Reply

    Your email address will not be published.

    Need Help?