0% found this document useful (0 votes)
10 views15 pages

Unit 3

The document provides an overview of functions in C programming, detailing their definition, declaration, and the differences between pass by value and pass by reference. It explains recursion with a focus on binary search, including its implementation and advantages. Additionally, it covers structures and unions, emphasizing their role in grouping different data types into a single unit.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views15 pages

Unit 3

The document provides an overview of functions in C programming, detailing their definition, declaration, and the differences between pass by value and pass by reference. It explains recursion with a focus on binary search, including its implementation and advantages. Additionally, it covers structures and unions, emphasizing their role in grouping different data types into a single unit.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 15

Functions in C: Definition and Declaration

In C programming, functions are a way to break down a program into smaller, modular, and
reusable blocks of code. Functions allow for better organization and efficiency, as you can
use the same code multiple times without rewriting it.

✅ 1. Definition of a Function in C
A function is a block of code that performs a specific task. It has a name, a return type,
parameters (optional), and a body containing the code to be executed.

Syntax of a Function Definition


return_type function_name(parameters)
{
// body of the function
// code to perform the task
return value; // return statement (if return_type is not void)
}

 return_type: The type of data that the function returns (e.g., int, float, char, void
if it returns nothing).
 function_name: The name of the function. It should be a valid identifier.
 parameters: Optional; these are the inputs the function takes. They are specified
inside parentheses. If the function doesn't take any inputs, the parentheses are empty.
 body: The code inside curly braces {} that performs the function's task.

Example of Function Definition


#include <stdio.h>

// Function definition
int add(int a, int b) {
return a + b; // returns the sum of a and b
}

int main() {
int result = add(5, 3); // Calling the function
printf("The sum is: %d\n", result); // Output: 8
return 0;
}

Explanation:

 int add(int a, int b): The function add takes two integer parameters and returns
an integer value (the sum).
 The function is called in main() with add(5, 3) and the result is printed.
✅ 2. Declaration of a Function in C
The declaration of a function, also known as the function prototype, is a declaration of the
function's return type, name, and parameters. It tells the compiler about the function's
signature (name, return type, and parameters) before the function is actually defined. This is
important when the function definition comes after the point where it is used.

Syntax of Function Declaration


return_type function_name(parameters);

 return_type: Specifies what type of value the function returns.


 function_name: The name of the function.
 parameters: Specifies the parameters (types) that the function accepts.

Example of Function Declaration


#include <stdio.h>

// Function declaration
int add(int, int);

int main() {
int result = add(5, 3); // Calling the function
printf("The sum is: %d\n", result); // Output: 8
return 0;
}

// Function definition
int add(int a, int b) {
return a + b; // returns the sum of a and b
}

Explanation:

 Function Declaration: The line int add(int, int); declares the function before it
is defined. It tells the compiler that there exists a function add that takes two integer
parameters and returns an integer.
 Function Definition: The actual code of the function add is defined later.

Why Do We Need Function Declarations?

Function declarations are required when:

1. The function is called before its definition.


2. You want to inform the compiler about the function's return type and parameters.

This helps ensure that the function is called correctly with the correct arguments, and the
program can be compiled successfully.
Example: Using Function Declaration and Definition
#include <stdio.h>

// Function declaration
void greet_user();

int main() {
greet_user(); // Calling the function
return 0;
}

// Function definition
void greet_user() {
printf("Hello, welcome to the C programming world!\n");
}

Explanation:

 void greet_user();: This declares a function greet_user() that takes no


parameters and returns no value (void).
 The function is called inside the main() function to display a greeting message.

✅ 1. Pass by Value
In pass by value, a copy of the argument is passed to the function. This means the function works
with a copy of the variable, and any changes made to the parameter inside the function do not affect
the original variable outside the function.

How Pass by Value Works:

 When a function is called, a copy of the argument (the actual value) is created and passed to
the function.
 The function operates on this copy, and any modifications are local to the function.
 The original variable in the calling function remains unchanged.

Syntax of Pass by Value:


return_type function_name(type parameter) {
// code
}

Example of Pass by Value


#include <stdio.h>

void swap_by_value(int x, int y) {


int temp;
temp = x; // Store x in temp
x = y; // Assign y to x
y = temp; // Assign temp (original x) to y
printf("Inside function (pass by value): x = %d, y = %d\n", x, y);
}

int main() {
int a = 10, b = 20;
printf("Before swapping: a = %d, b = %d\n", a, b);
swap_by_value(a, b); // Passes copies of a and b
printf("After swapping (pass by value): a = %d, b = %d\n", a, b); //
Original values remain unchanged
return 0;
}

Explanation:

 swap_by_value() function receives copies of a and b from main().


 Inside the function, the values are swapped, but only the local copies of the variables are
affected.
 The original variables a and b in main() are not changed after the function call.

Output:
Before swapping: a = 10, b = 20
Inside function (pass by value): x = 20, y = 10
After swapping (pass by value): a = 10, b = 20

Advantages of Pass by Value:

 Protects the original data from accidental modification.


 Simple to implement.

Disadvantages of Pass by Value:

 If the function needs to modify the original variable, the changes will not be reflected
outside the function.

✅ 2. Pass by Reference
In pass by reference, a reference (or address) to the original variable is passed to the function, not a
copy of the variable. This allows the function to modify the original variable's value.

How Pass by Reference Works:

 When a function is called, it receives the address of the argument.


 The function can then modify the value stored at that address, which means the original
variable in the calling function is modified.
Syntax of Pass by Reference:

To pass by reference in C, you typically use pointers. A pointer holds the memory address of the
variable, and when passed to a function, the function can modify the original variable.

return_type function_name(type *parameter) {


// code
}

Example of Pass by Reference

Swapping Using Pass by Reference


In pass by reference, the function receives the address (reference) of the arguments, which allows it
to modify the original variables.

Example: Swapping Using Pass by Reference


#include <stdio.h>

void swap_by_reference(int *x, int *y) {


int temp;
temp = *x; // Dereference x to get the value and store in temp
*x = *y; // Dereference y to get the value and assign to x
*y = temp; // Assign temp (original x) to y
printf("Inside function (pass by reference): x = %d, y = %d\n", *x,
*y);
}

int main() {
int a = 10, b = 20;
printf("Before swapping: a = %d, b = %d\n", a, b);
swap_by_reference(&a, &b); // Passes addresses of a and b
printf("After swapping (pass by reference): a = %d, b = %d\n", a, b);
// Original values are changed
return 0;
}

Explanation:

 swap_by_reference() function receives the addresses of a and b from main(), which


allows it to modify the actual variables.
 The values of a and b are swapped by dereferencing the pointers inside the function, and
the changes are reflected in the original variables.

Output:
Before swapping: a = 10, b = 20
Inside function (pass by reference): x = 20, y = 10
After swapping (pass by reference): a = 20, b = 10
Advantages of Pass by Reference:

 Allows the function to modify the original data.


 More efficient for large structures or arrays, as it avoids copying the data.

Disadvantages of Pass by Reference:

 The original data can be modified unintentionally, so extra care is needed.


 More complex due to the need for pointers.

✅ 3. Comparison of Pass by Value vs. Pass by Reference


Feature Pass by Value Pass by Reference

Data passed A copy of the data. The address (reference) of the data.

Original data The original data is not modified. The original data can be modified.

Memory More memory efficient as no copy is


Requires more memory as a copy is created.
usage created.

When the function does not need to modify When the function needs to modify the
Use case
the original data. original data.

Complexity Simpler, easier to use. Requires pointers, more complex.

Recursion - Binary Search Using Recursive Functions

Recursion is a technique where a function calls itself in order to solve a problem. Binary
search is an efficient searching algorithm that works on a sorted array. It repeatedly divides
the search interval in half, making it faster than linear search.

In a recursive binary search, the function calls itself with a new range (subarray) to narrow
down the search.

Binary Search Algorithm (Recursive Approach)

The general idea behind binary search is:

1. Compare the target element with the middle element of the array.
2. If the target is equal to the middle element, the search is successful.
3. If the target is smaller than the middle element, search the left half of the array.
4. If the target is greater than the middle element, search the right half of the array.

This process is repeated recursively until the element is found or the search interval becomes
empty.

Steps of Recursive Binary Search:

1. Find the middle element of the array.


2. Compare the middle element with the target:
o If it matches, return the index.
o If it is smaller, search the left subarray.
o If it is larger, search the right subarray.
3. Repeat the process on the subarray.

Recursive Binary Search Code Example in C


#include <stdio.h>

// Function for recursive binary search


int binarySearch(int arr[], int left, int right, int target) {
// Base case: If the search interval is invalid (left > right)
if (left > right) {
return -1; // Target not found
}

// Find the middle index


int mid = left + (right - left) / 2;

// Check if target is present at mid


if (arr[mid] == target) {
return mid; // Target found, return its index
}

// If target is smaller than mid, search the left half


if (arr[mid] > target) {
return binarySearch(arr, left, mid - 1, target);
}
// If target is larger than mid, search the right half
else {
return binarySearch(arr, mid + 1, right, target);
}
}

int main() {
// Example array (must be sorted for binary search to work)
int arr[] = {2, 3, 4, 10, 40, 50, 80};
int n = sizeof(arr) / sizeof(arr[0]);
int target = 40;

// Perform binary search


int result = binarySearch(arr, 0, n - 1, target);
// Output the result
if (result != -1) {
printf("Element %d found at index %d\n", target, result);
} else {
printf("Element %d not found\n", target);
}

return 0;
}

Explanation:

1. binarySearch() is the recursive function that performs binary search.


o It takes the array arr[], the current search boundaries left and right, and
the target value.
o It first calculates the middle index mid and compares the middle element with
the target.
o Depending on the comparison, it either returns the index or calls itself
recursively on the left or right subarray.
2. Base Case: When left > right, the search is unsuccessful, and -1 is returned.
3. Recursive Calls: The function calls itself with updated boundaries (left to mid-1 or
mid+1 to right).

Output for target = 40:

Element 40 found at index 4

If the target were not found, the output would be:

mathematica
CopyEdit
Element 40 not found

Key Points About Recursive Binary Search:

 Time Complexity: The time complexity of binary search (recursive or iterative) is


O(log n), where n is the number of elements in the array. This makes binary search
much faster than linear search, which has a time complexity of O(n).
 Space Complexity: In the recursive approach, space complexity is O(log n) due to
the recursive call stack (depth of recursion is proportional to the logarithm of the array
size). For iterative approaches, it would be O(1).

Advantages of Recursion in Binary Search:

 Recursion provides a cleaner and simpler implementation of binary search.


 It reduces the need for explicit loops and manually adjusting the boundaries of the
array.
Disadvantages:

 Recursive functions can be less efficient due to the overhead of function calls,
especially in languages with limited recursion depth (such as C).
 Stack overflow can occur if the recursion depth is too large (e.g., for very large
arrays).

Structures and Unions in C

In C programming, structures and unions are user-defined data types that allow you to group
different types of variables together into a single unit. Structures allow you to combine different
data types, while unions allow you to store different data types in the same memory location.

Introduction to Structures

A structure in C is a collection of variables (of different data types) grouped together under a single
name. Each element in the structure is called a member or field. Structures are used to represent a
record or an entity with multiple attributes.

Need for Structure Data Type

Before structures, you could only store individual variables of simple types like int, float, or char.
However, in many real-world scenarios, you need to group different data types together. For
example, to represent a student, you might need to store the student's name, roll number, marks,
etc., all of which are different data types.

A structure helps you group all these related data elements under one name, making it easier to
manage and access the data.

Structure Definition

A structure definition declares the structure type, including its members, but does not create any
variables. You define the structure by using the struct keyword, followed by the structure name
and the members inside curly braces.

Syntax of Structure Definition:


struct structure_name {
data_type member1;
data_type member2;
// more members
};

Example of Structure Definition:


#include <stdio.h>

// Structure definition for a student


struct Student {
int rollNumber;
char name[50];
float marks;
};

int main() {
// Creating a structure variable
struct Student student1;

// Accessing members and assigning values


student1.rollNumber = 101;
strcpy(student1.name, "John Doe"); // Copying string into name
student1.marks = 85.5;

// Printing structure members


printf("Roll Number: %d\n", student1.rollNumber);
printf("Name: %s\n", student1.name);
printf("Marks: %.2f\n", student1.marks);

return 0;
}

Explanation:

1. The structure Student is defined with three members: rollNumber, name, and marks.
2. A structure variable student1 is created and its members are accessed and assigned values.
3. The members are printed using printf().

Structure Declaration

After defining a structure, you can create variables of that structure type. The declaration of a
structure variable is done by specifying the structure name followed by the variable name.

Syntax of Structure Declaration:


struct structure_name variable_name;

You can declare multiple structure variables in one line, separated by commas.

Example of Structure Declaration:


struct Student student2, student3;

This creates two structure variables, student2 and student3, of type struct Student.

Structure within a Structure

In C, a structure can contain another structure as a member. This is called a nested structure or
structure within a structure.
Syntax of Structure within a Structure:
struct OuterStructure {
data_type member1;
struct InnerStructure member2; // Inner structure as a member
};
Example of Structure within a Structure:
#include <stdio.h>
#include <string.h>

// Define a structure for Address


struct Address {
char street[100];
char city[50];
int zipCode;
};

// Define a structure for Employee with Address as a member


struct Employee {
int id;
char name[50];
struct Address address; // Nested structure
};

int main() {
struct Employee employee1;

// Assigning values to the members of the nested structure


employee1.id = 101;
strcpy(employee1.name, "Alice");

// Assigning values to the Address structure members


strcpy(employee1.address.street, "123 Main St");
strcpy(employee1.address.city, "New York");
employee1.address.zipCode = 10001;

// Printing the Employee details, including Address


printf("Employee ID: %d\n", employee1.id);
printf("Employee Name: %s\n", employee1.name);
printf("Employee Address: %s, %s, %d\n",
employee1.address.street, employee1.address.city,
employee1.address.zipCode);

return 0;
}

Explanation:

1. The Address structure contains fields for street, city, and zip code.
2. The Employee structure contains an Address structure as one of its members.
3. We create a structure variable employee1 and assign values to the members of both the
Employee and Address structures.
4. The employee's details, including the address, are printed.
Memory Allocation for Structures

The memory required for a structure is the sum of the memory required by all its members. The
memory for the structure is allocated sequentially, and the size of the structure depends on the data
types of its members.

Structure Size Calculation:

To calculate the size of a structure, you can use the sizeof() operator in C.

printf("Size of structure: %zu bytes\n", sizeof(struct Employee));

Advantages of Structures:

 Organization: Structures allow you to logically group different data types, making code
easier to manage and understand.
 Flexibility: You can store a combination of different data types that belong to the same
entity (e.g., a Student with int, char[], and float).

Summary of Structure Concepts:

 Structure Definition: Defines the structure's layout (members and their types).
 Structure Declaration: Declares variables of a structure type.
 Structure within Structure: You can use a structure as a member of another structure, which
helps model more complex entities.

Union in C Programming

A union is a special data type in C that allows storing different data types in the same memory
location. Unlike structures, where each member gets its own memory, in a union, all members share
the same memory. This means a union can store only one of its members at a time, and the size of
the union is determined by the largest member.

Definition of a Union

A union is defined using the union keyword, followed by the union name and its members.

Syntax of a Union:
union union_name {
data_type member1;
data_type member2;
// other members
};
Key Differences Between Structures and Unions:

Feature Structure Union

Memory All members share the same memory


Each member has its own memory
Allocation location

Size is the sum of the sizes of all


Size Size is the size of the largest member
members

Accessing All members can be accessed Only one member can be accessed at a
Members simultaneously time

When you need to store different types When you want to save memory and store
Use Case
of data simultaneously only one piece of data at a time

Union Example:
#include <stdio.h>

// Define a union to store different data types


union Data {
int i;
float f;
char str[20];
};

int main() {
// Create a union variable
union Data data;

// Storing an integer value


data.i = 10;
printf("data.i = %d\n", data.i);

// Storing a float value


data.f = 3.14;
printf("data.f = %.2f\n", data.f);

// Storing a string
strcpy(data.str, "Hello, Union!");
printf("data.str = %s\n", data.str);

// After writing to one member, the previous value is overwritten.


printf("data.i = %d\n", data.i); // Output might be garbage value as
data.f or data.str overwrite it

return 0;
}

Explanation:

 The union Data can hold an int, a float, or a char[] (string).


 However, only one of these members can hold a value at any given time. When we store a
value in one member (e.g., data.f), it overwrites the previous value (e.g., data.i).
 This allows unions to save memory since they store only one of their members at a time.

Programs Using Structures and Unions Together

Now, let's create a program that demonstrates the use of both structures and unions. We will define
a structure containing a union and then show how both are used together.

Program Example: Structure Containing a Union


#include <stdio.h>
#include <string.h>

// Define a union for different types of data


union Data {
int i;
float f;
char str[20];
};

// Define a structure that contains the union


struct Info {
int id;
union Data data;
};

int main() {
// Creating a structure variable
struct Info info1;

// Assign values to structure members


info1.id = 1;

// Assign an integer value to the union member


info1.data.i = 100;
printf("Info 1 - ID: %d, Data (int): %d\n", info1.id, info1.data.i);

// Assign a float value to the union member (overwrites the int)


info1.data.f = 3.14;
printf("Info 1 - ID: %d, Data (float): %.2f\n", info1.id,
info1.data.f);

// Assign a string to the union member (overwrites the float)


strcpy(info1.data.str, "Hello, Union!");
printf("Info 1 - ID: %d, Data (string): %s\n", info1.id,
info1.data.str);

// Accessing previous data (which is overwritten by the latest


assignment)
printf("Info 1 - ID: %d, Data (int): %d\n", info1.id, info1.data.i);
// Will print garbage value
return 0;
}

Explanation:

1. Union Data: Contains three members: i, f, and str.


2. Structure Info: Contains an integer id and a union data. This structure allows the data
union to hold different types of data, but only one at a time.
3. The program demonstrates how a union overwrites its previous value each time a new
member is assigned a value.
4. Each time we assign a new value to a member of the union, the previous value is lost.

Output:
Info 1 - ID: 1, Data (int): 100
Info 1 - ID: 1, Data (float): 3.14
Info 1 - ID: 1, Data (string): Hello, Union!
Info 1 - ID: 1, Data (int): 1078523331 // May show a garbage value

Key Points About the Program:

 Union Usage: You can store different types of data in the same memory space, saving
memory, but only one member can hold a value at a time.
 Structure Usage: Structures allow you to group related data together, and in this case, a
structure is used to hold a union and another piece of data (the ID).

When to Use Union vs. Structure:

 Structure: Use when you need to store multiple related pieces of data simultaneously (e.g., a
Student structure with name, rollNumber, marks, etc.).
 Union: Use when you need to store different types of data, but only one type at a time (e.g.,
a Data union where i, f, or str might be used, but never more than one at once).

You might also like