C Functions
C - Functions
Section titled “C - Functions”A function is a self-contained block of code that performs a specific task. Functions are essential for structuring programs, promoting code reuse, and improving readability and maintainability. Every C program must have at least one function: main(), which is the entry point of execution.
Breaking down complex problems into smaller, manageable tasks, each handled by a function, is a fundamental principle of procedural programming.
Key Concepts:
Section titled “Key Concepts:”- Function Definition: Provides the actual implementation (the code) of the function.
- Function Declaration (Prototype): Tells the compiler about the function’s name, return type, and the types of its parameters. This allows the compiler to check calls to the function even before it encounters the function’s definition.
- Function Call: Executes the code within the function definition.
The C standard library provides a rich set of pre-defined functions (like printf(), scanf(), strcpy(), malloc(), etc.) that you can call in your programs after including the appropriate header files.
Defining a Function
Section titled “Defining a Function”The general syntax for defining a function in C is:
return_type function_name(parameter_type1 parameter_name1, parameter_type2 parameter_name2, ...) { // Function body: declarations and statements // ... code to perform the task ...
return value; // Optional: only if return_type is not void}Components of a function definition:
- Return Type: The data type of the value the function sends back to the caller. If the function doesn’t return a value, use the keyword
void. - Function Name: A unique identifier for the function. Follow standard C naming conventions (e.g., letters, numbers, underscores; cannot start with a number).
- Parameters (Arguments): Variables listed inside the parentheses that receive values (arguments) when the function is called. They act as local variables within the function. If a function takes no parameters, use
(void):return_type function_name(void) { ... }. - Function Body: The code block enclosed in curly braces
{}containing the instructions the function executes.
Example: A function to find the maximum of two integers
Section titled “Example: A function to find the maximum of two integers”/* * Function definition for max * Takes two integers as input * Returns the larger of the two integers */int max(int num1, int num2) { // Function header // Function body starts here int result; // Local variable declaration
if (num1 > num2) { result = num1; } else { result = num2; }
return result; // Return the calculated maximum value}Function Declarations (Prototypes)
Section titled “Function Declarations (Prototypes)”A function declaration, also known as a prototype, informs the compiler about the function’s signature before it’s called or defined. This is crucial if you call a function before its definition appears in the source code, or if the function is defined in a different source file.
The syntax is similar to the function header, but ends with a semicolon and parameter names are optional (though often useful for clarity):
return_type function_name(parameter_type1, parameter_type2, ...);For the max function defined above, the prototype would be:
int max(int num1, int num2); // Prototype with parameter names// or equivalently:int max(int, int); // Prototype without parameter namesPrototypes are typically placed at the top of the source file or in header files (.h) which are then included using #include.
Calling a Function
Section titled “Calling a Function”To use a function, you call it by using its name followed by parentheses containing the arguments (the actual values or variables being passed to the function’s parameters).
- Control transfers from the calling point to the first statement in the function’s body.
- The values of the arguments are copied into the corresponding function parameters.
- The function body executes.
- If a
returnstatement with a value is encountered, that value is sent back to the caller, and control returns to the point immediately after the function call. - If the function’s return type is
voidor the end of the function body (}) is reached without areturnstatement, control simply returns to the caller.
Example: Calling the max function
#include <stdio.h>#include <stdlib.h> // For EXIT_SUCCESS
// Function prototype (declaration) - Essential here because max is defined after mainint max(int num1, int num2);
int main(void) { // Standard main signature int a = 100; int b = 200; int ret;
// Calling the function and storing the returned value ret = max(a, b);
printf("Max value is: %d\n", ret);
return EXIT_SUCCESS;}
// Function definitionint max(int num1, int num2) { int result; if (num1 > num2) { result = num1; } else { result = num2; } return result;}Compiling and running this code produces:
Max value is: 200Function Arguments and Parameter Passing
Section titled “Function Arguments and Parameter Passing”Parameters declared in the function definition are called formal parameters. The values passed during a function call are called actual arguments.
C uses pass by value by default for function arguments. This means:
- Call by Value: A copy of the actual argument’s value is made and passed to the formal parameter. Changes made to the parameter inside the function do not affect the original argument in the caller.
- Simulating Call by Reference (Pass by Pointer): To allow a function to modify the original variable in the caller, you must pass the address of the variable (using the
&operator) as the argument. The corresponding formal parameter must be declared as a pointer (e.g.,int *ptr). Inside the function, you use the dereference operator (*) to access or modify the value at that address. This simulates call by reference.
The max function example uses call by value. The values of a and b are copied into num1 and num2. If max tried to modify num1 or num2, it would not change a or b in main.
Example of Pass by Pointer (Simulating Call by Reference):
#include <stdio.h>#include <stdlib.h>
// Function prototype: takes a pointer to an integervoid increment(int *value_ptr);
int main(void) { int counter = 10; printf("Before increment: %d\n", counter);
// Pass the address of 'counter' to the function increment(&counter);
printf("After increment: %d\n", counter); // Original 'counter' is modified return EXIT_SUCCESS;}
// Function definition: parameter is a pointervoid increment(int *value_ptr) { // Dereference the pointer to access and modify the original value (*value_ptr)++; // Parentheses are important due to operator precedence // Alternatively: *value_ptr = *value_ptr + 1;}Output:
Before increment: 10After increment: 11