FUNCTIONS & POINTERS

Introduction

  • Functions and Pointers are vital concepts in C programming that help manage complexity and enable efficient code execution through reusable blocks of code.

Functions

Definition
  • A function is a named block of code that performs a specific task.
  • Functions allow for code reuse by defining a piece of logic once and using it multiple times within a program, thus maintaining a clean and organized structure.
  • A function only executes when it is explicitly called.
  • It allows for data passing through parameters.
Purpose and Importance
  • Functions are instrumental in:
    • Performing actions.
    • Reusing code efficiently.
Types of Functions
  1. User Defined Functions: Functions created by the programmer.
  2. Library Functions: Pre-defined functions in C standard library.
Creating a Function
  • A custom function is declared using the structure: Data_type function_name(parameters list) {}
    • Example:
      int myFunction(a) { // code to be executed }
Function Call
  • Functions are not executed upon declaration; they must be called within the main() function or elsewhere:
    • Syntax to Call a Function: function_name();
    • Example:
      int myFunction(argument list);
Example of a Function Call
  • Given the following function:
  void myFunction() {
      printf("I just got executed!");
  }
  • Call in main():
  int main() {
      myFunction();
      return 0;
  }
  • Output: "I just got executed!"
Calling Functions Multiple Times
  • A function can be invoked multiple times:
  int main() {
      myFunction();
      myFunction();
      return 0;
  }
  • Output:
    "I just got executed!"
    (Displayed twice)
Passing Information: Parameters and Arguments
  • Parameters are data passed into functions.
  • Syntax for parameters:
  returnType functionName(parameter1, parameter2, parameter3) {
      // code to be executed
  }
  • It is critical to ensure the number of arguments matches the number of parameters during function calls.
Return Values
  • The void keyword indicates no return value. To return a value, use a data type (e.g., int, float):
    • Example:
      int myFunction(int x) { return 5 + x; } void main() { printf("Result is: %d", myFunction(3)); }
  • Output: 8 (5 + 3)

Library Functions

  • Functions included in the C standard library categorized into:
Input/Output Functions
  • printf(): Outputs text to the console.
  • scanf(): Accepts user input.
Mathematical Functions
  • sqrt(): Computes square root of a number.
  • pow(): Computes power of a number.
String Functions
  • strlen(): Determines the length of a string.
  • strcpy(): Copies one string to another.
Examples of Library Functions
  1. Mathematical Functions
    • Code:
   #include <stdio.h>
   #include <math.h>
   int main() {
       double result_sqrt = sqrt(25.0);
       double result_pow = pow(2.0, 3.0);
       printf("Square root of 25: %.2f\n", result_sqrt);
       printf("2 raised to the power of 3: %.2f\n", result_pow);
       return 0;
   }
  1. String Functions
    • Code:
   #include <stdio.h>
   #include <string.h>
   int main() {
       char str1[] = "Hello";
       char str2[20];
       printf("Length of str1: %zu\n", strlen(str1));
       strcpy(str2, str1);
       printf("Copied string: %s\n", str2);
       return 0;
   }

Recursion

  • Recursion is defined as a technique where a function calls itself.
    • It simplifies complex problems by breaking them into smaller, simpler sub-problems.
Example of Recursion
  • Function to sum numbers from 1 to 10:
   int sum(int k);
   void main() {
       int result = sum(10);
       printf("%d", result);
   }
  • Function Definition:
   int sum(int k) {
       if (k > 0) {
           return k + sum(k - 1);
       } else {
           return 0;
       }
   }
  • Explanation:
    • The sum(k) function adds k to the sum of all previous numbers until k == 0, at which point it returns 0.
    • Thus, the output calculates:
   10 + sum(9)\n    --> 10 + (9 + sum(8))\n    --> 10 + (9 + (8 + sum(7))) ...\n   ```

## Memory Addresses and Pointers

### Memory Address Concept
- In C, every variable resides at a specific memory address, which signifies its location in memory.
- To retrieve a variable's address, use the **reference operator** (&).
  - **Example**:

int myAge = 43;
printf("%p", &myAge); // Outputs the memory address

- The output will typically contain hexadecimal characters.

### Pointers
- A **pointer** stores the memory address of another variable.
- Created using the asterisk (*) operator:
  - **Example**:

int myAge = 43;
int *ptr = &myAge; // Pointer declaration

- To print pointer values, format specifier `%p` is used:

printf("%p\n", ptr);

- To get the value a pointer points to, use the dereference operator (*):

printf("%d\n", *ptr); // Outputs value of myAge

### Key Features of Pointers
- They allow for low-level memory manipulation and more efficient function data passing.
- Pointers are essential for creating dynamic data structures like linked lists and trees.

### Pointer Usage Examples
- **Creating a Pointer**:

int myAge = 43;
int *ptr = &myAge; // Pointer points to myAge

### Dereferencing Example
- **Dereference Approach**:

printf("Value through pointer: %d\n", *ptr);
```

Conclusion: Pointer Characteristics
  • Pointers help access and modify data in memory without directly referencing the variable.
  • They enhance dynamic data handling and enable the creation of complex data structures.

Storage Classes in C

  • Storage classes define the scope, lifetime, and storage location of variables:
Four Main Storage Classes
  1. auto
    • Local to function/block, lifetime until end of scope.
    • Default value can be garbage.
  2. static
    • Local to function/block but preserves value throughout program execution.
  3. register
    • Similar to auto but suggests storage in CPU register for faster access.
  4. extern
    • Global variable accessible across multiple files and retains value throughout the program.
Summary of Storage Classes
Storage ClassStorage LocationInitial ValueScopeLifetime
autoStackGarbageWithin blockEnd of block
externData segmentZeroGlobal, Multiple FilesTill end of program
staticData segmentZeroWithin blockTill end of program
registerCPU RegisterGarbageWithin blockEnd of block
Memory Allocation
  • Static Memory: Allocated at compile-time.
  • Dynamic Memory: Allocated at runtime, using malloc() or calloc(). Use <stdlib.h> to access these functions.
  • Malloc vs Calloc:
    • malloc(size) - Allocates memory but does not initialize.
    • calloc(n, size) - Allocates memory and initializes all bytes to zero, slower due to initialization process.