Functions are a way to organize and structure code into reusable blocks. A function is a self-contained block of code that performs a specific task. It can be called from other parts of the program to execute that task whenever needed. 

Functions in C have the following syntax:

return_type function_name(parameter1, parameter2, ...) {

    // Function body

    // Code to perform the desired task

    // ...

    return value; // Optional return statement


Let's break down the components of a C function:

return_type: It specifies the data type of the value that the function returns after execution. If the function does not return a value, the return type is void.

function_name: It is the name of the function, which should be unique within the scope of the program.

parameters: They are optional inputs that the function can accept. Parameters are enclosed in parentheses and separated by commas. Each parameter consists of a data type followed by a name, e.g., int num, float x.

Function body: It is enclosed in curly braces {} and contains the actual code that performs the task of the function.

return statement: If the function has a return type other than void, it should end with a return statement that specifies the value to be returned.

Here's an example that demonstrates the declaration, definition, and usage of a simple function:

In this example, we declare a function named add that takes two integers as parameters and returns their sum. 

The function is defined to calculate the sum of the two parameters and return the result.

In the main function, we call the add function with the arguments 3 and 4 and store the result in the result variable. 

Finally, we print the result using printf.

Functions in C have the following characteristics:

Modularity: Functions provide a way to break down a program into smaller, self-contained modules. Each function focuses on a specific task, making the code more organized and easier to understand, debug, and maintain.

Reusability: Once a function is defined, it can be called and executed from multiple places within the program or even from different programs. This promotes code reuse and reduces redundancy, as you can use the same function to perform a specific task whenever needed.

Encapsulation: Functions encapsulate a set of related statements and data into a single entity. This helps in hiding the implementation details from the calling code, providing an interface to interact with the function. Encapsulation also allows for information hiding and protects the internal state of a function.

Abstraction: Functions allow you to abstract complex operations into simpler, higher-level actions. By giving a meaningful name to a function, you can use it as a higher-level construct in your code, focusing on what the function does rather than how it is implemented.

Code Readability: Functions help improve code readability by breaking down the program logic into smaller, well-defined tasks. This makes the code easier to understand and maintain, especially when functions have descriptive names and follow a modular design.

Parameter Passing: Functions can accept zero or more parameters as inputs. Parameters allow you to pass data into a function, enabling it to perform operations on the provided values. Parameters can be of various types, including built-in types (int, float, char, etc.), arrays, pointers, or even structures.

Return Values: Functions can return a value to the calling code using the return statement. The return type, specified in the function declaration, determines the type of the value returned. Functions can have a void return type if they don't need to return a value.

Function Overloading: C does not support function overloading, which means you cannot have multiple functions with the same name but different parameter lists. Each function must have a unique name within its scope.