Wednesday, October 16, 2024

ASSIGNMENT-5

Q1: Explain types of arrays with an example.

Arrays are used to store multiple values of the same type in a single variable. We will discuss three types of arrays: one-dimensional, two-dimensional, and multidimensional arrays.

Accessing Elements in an Array

In programming, an array is a collection of elements that are stored in contiguous memory locations. The elements in an array can be accessed using their index, which represents their position within the array. The indexing of an array typically starts from 0, meaning the first element is at index 0, the second at index 1, and so on.

Accessing Array Elements

To access an element in an array, you specify the array name followed by the index of the element in square brackets. For example, if you have an array named arr, accessing the element at index i is done using arr[i].

Here's a simple example in C:

#include <iostream>
using namespace std;

int main() {
int arr[3];
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;

printf("arr[0]: %4d ", arr[0] );
printf("arr[1]: %4d ", arr[1] );
printf("arr[2]: %4d ", arr[2] );

return 0;
}

In this example, we have an array arr with three elements. We access each element using its index and print its value.

Traversing an Array

To access all elements in an array, you can traverse the array using a loop. This process involves iterating over the array indices and accessing each element sequentially.

Here's an example of traversing an array in C:

#include <stdio.h>

int main() {
int table_of_two[10] = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20};
for (int i = 0; i < 10; i++) {
printf("%4d", table_of_two[i] );
}
return 0;
}

In this code, we have an array table_of_two containing the first ten multiples of two. We use a for loop to traverse the array and print each element.

Determining Array Size

The size of an array, which is the total number of elements it can hold, is often determined at the time of declaration. However, you can also calculate the size of an array dynamically using the sizeof operator. The size of the array is obtained by dividing the total size of the array by the size of an individual element.

Here's how you can find the size of an array in C:

#include <stdio.h>
using namespace std;

int main() {
int arr[] = {1, 2, 3, 4, 5};
int n = sizeof(arr) / sizeof(arr[0]);
printf("Length of the array: %d", n);
return 0;
}

In this example, sizeof(arr) gives the total size in bytes of the array arr, and sizeof(arr[0]) gives the size of one element. Dividing these two gives us the number of elements in the array.

1. One-dimensional Array:

A one-dimensional array is a linear array where elements are stored sequentially.

Example:


#include <stdio.h>

int main() {
int arr[5] = {1, 2, 3, 4, 5}; // One-dimensional array initialization
printf("One-dimensional Array: ");
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]); // Accessing array elements
}
return 0;
}

Explanation:

  • The array arr contains 5 integers.
  • We access each element of the array using a for loop, printing each one sequentially.

2. Two-dimensional Array:

A two-dimensional array can be visualized as a table of rows and columns.

Example:


#include <stdio.h>

int main() {
int arr[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; // 2D array initialization
printf("Two-dimensional Array:\n");
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printf("%d ", arr[i][j]); // Accessing 2D array elements
}
printf("\n");
}
return 0;
}

Explanation:

  • arr is a 2D array of size 3x3. It is initialized with values in a matrix-like form.
  • Nested for loops are used to access and print the array elements row by row.

3. Multidimensional Array:

Higher-dimensional arrays are possible, such as 3D arrays, where elements are accessed via multiple indices.

Example:


#include <stdio.h>

int main() {
int arr[2][2][2] = {{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}}; // 3D array initialization
printf("Multidimensional Array:\n");
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 2; k++) {
printf("%d ", arr[i][j][k]); // Accessing 3D array elements
}
printf("\n");
}
printf("\n");
}
return 0;
}

Explanation:

  • arr is a 3D array of size 2x2x2, representing layers of 2D arrays.
  • Three nested loops are used to access and print each element in the 3D array.

Q2: Explain character array with an example.

A character array is a series of characters stored in contiguous memory locations, typically used to represent strings.

A character array in C is essentially a sequence of characters stored in contiguous memory locations. You can think of it as a string or a line of text.

Here's a simple example:

#include <stdio.h>

int main() {

    char greeting[] = "Hello, World!";

        printf("%s\n", greeting);

    return 0;

}

In this example, the character array greeting holds the string "Hello, World!". When you use printf with %s, it prints the entire character array as a string.


Now, let's look at another example where you can modify characters in the array:

#include <stdio.h>

int main() {

    char name[] = "John Doe";

    name[5] = 'X'; // Change 'D' to 'X'

    printf("%s\n", name); // Output will be "John Xoe"

    return 0;

}

In this case, we change the character at index 5 from 'D' to 'X'. Arrays are handy for manipulating strings in such a way.

Character arrays can also be used to take input from the user:

#include <stdio.h>

int main() {

    char name[50];

    printf("Enter your name: ");

    fgets(name, sizeof(name), stdin); // safer than gets(), avoids buffer overflow

    printf("Hello, %s", name);

    return 0;

}

Here, fgets reads a line of text from standard input and stores it in the name array. This makes it safer than using gets, which can lead to buffer overflow.

Example:


#include <stdio.h>

int main() {
char name[6] = "Hello"; // Character array (string) initialization
printf("Character Array: ");
for (int i = 0; i < 5; i++) {
printf("%c", name[i]); // Accessing and printing each character
}
return 0;
}

Explanation:

  • name is a character array with 6 elements (including the null terminator \0).
  • The loop prints each character from the array individually.

Q3: Explain the following string functions with examples.

strcmp()
Compares two strings.

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

int main() {
    char str1[] = "Hello";
    char str2[] = "World";

    int result = strcmp(str1, str2);
    printf("strcmp result: %d\n", result); // returns negative because "Hello" < "World"

    return 0;
}
strlen()
Returns the length of a string.

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

int main() {
    char str[] = "Hello, World!";
    printf("Length of the string: %lu\n", strlen(str)); // prints the length of str

    return 0;
}
strcat()
Concatenates (joins) two strings.

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

int main() {
    char str1[20] = "Hello";
    char str2[] = " World";

    strcat(str1, str2);
    printf("%s\n", str1); // prints "Hello World"

    return 0;
}
strcpy()
Copies one string into another.

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

int main() {
    char dest[20];
    char src[] = "Hello, World!";

    strcpy(dest, src);
    printf("%s\n", dest); // prints "Hello, World!"

    return 0;
}
strstr()
Finds the first occurrence of a substring in a string.
#include <stdio.h>
#include <string.h>

int main() {
    char str[] = "Hello, World!";
    char *sub = strstr(str, "World");

    if (sub) {
        printf("Found: %s\n", sub); // prints "World!"
    }

    return 0;
}
strupr()
Converts a string to uppercase. Note: This function is not standard in C, but available in some compilers like Turbo C.

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

int main() {
    char str[] = "Hello";

    for(int i = 0; str[i]; i++){
      str[i] = toupper(str[i]);
    }

    printf("%s\n", str); // prints "HELLO"

    return 0;
}
strchr()
Finds the first occurrence of a character in a string.
#include <stdio.h>
#include <string.h>

int main() {
    char str[] = "Hello, World!";
    char *pos = strchr(str, 'W');

    if (pos) {
        printf("Found: %s\n", pos); // prints "World!"
    }

    return 0;
}
strncmp()
Compares the first n characters of two strings.
#include <stdio.h>
#include <string.h>

int main() {
    char str1[] = "Hello";
    char str2[] = "Hello, World";

    int result = strncmp(str1, str2, 5);
    printf("strncmp result: %d\n", result); // returns 0 because first 5 chars are equal

    return 0;
}
strrev()
Reverses a string. Note: This function is not standard in C, but available in some compilers like Turbo C.
#include <stdio.h>
#include <string.h>

void reverse(char *str) {
    int n = strlen(str);
    for (int i = 0; i < n / 2; i++) {
        char temp = str[i];
        str[i] = str[n - i - 1];
        str[n - i - 1] = temp;
    }
}

int main() {
    char str[] = "Hello";
    reverse(str);
    printf("%s\n", str); // prints "olleH"

    return 0;
}
strlwr()
Converts a string to lowercase. Note: This function is not standard in C, but available in some compilers like Turbo C.

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

void strlwr(char *str) {
    for (int i = 0; str[i]; i++) {
        str[i] = tolower(str[i]);
    }
}

int main() {
    char str[] = "Hello, World!";
    strlwr(str);
    printf("%s\n", str); // prints "hello, world!"

    return 0;
}
strncat()
Concatenates the first n characters of one string to another.

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

int main() {
    char str1[20] = "Hello";
    char str2[] = " World";

    strncat(str1, str2, 3);
    printf("%s\n", str1); // prints "Hello Wo"

    return 0;
}
strncpy()
Copies the first n characters of one string into another.

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

int main() {
    char dest[20];
    char src[] = "Hello, World!";

    strncpy(dest, src, 5);
    dest[5] = '\0'; // null-terminate the string
    printf("%s\n", dest); // prints "Hello"

    return 0;
}
strcat(s1, s2)
Concatenates two strings, s1 and s2.

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

int main() {
    char s1[20] = "Good";
    char s2[] = " Day";

    strcat(s1, s2);
    printf("%s\n", s1); // prints "Good Day"

    return 0;
}
puts()
Writes a string to stdout.
#include <stdio.h>

int main() {
    char str[] = "Hello, World!";
    puts(str); // prints "Hello, World!" followed by a newline

    return 0;
}
strcpy(s1, s2)
Copies string s2 into s1.

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

int main() {
    char s1[20];
    char s2[] = "Copy this!";

    strcpy(s1, s2);
    printf("%s\n", s1); // prints "Copy this!"

    return 0

Below is a full program that demonstrates various string functions:

#include <stdio.h>
#include <string.h>
int main() {
char s1[20] = "Hello";
char s2[20] = "World";
char s3[20];
// strcmp(): Compare two strings
int result = strcmp(s1, s2);
printf("strcmp(s1, s2): %d\n", result);
// strlen(): Get the length of the string
printf("strlen(s1): %lu\n", strlen(s1));
// strcat(): Concatenate s2 to s1
strcat(s1, s2);
printf("strcat(s1, s2): %s\n", s1);
// strcpy(): Copy s2 into s3
strcpy(s3, s2);
printf("strcpy(s3, s2): %s\n", s3);
// strstr(): Find "World" in s1
char *sub = strstr(s1, "World");
if (sub) {
printf("strstr(s1, \"World\"): %s\n", sub);
}
// strupr(): Convert string to uppercase
printf("Before strupr: %s\n", s1);
strupr(s1);
printf("After strupr: %s\n", s1);
// strchr(): Find first occurrence of 'o'
char *pos = strchr(s1, 'O');
if (pos) {
printf("strchr(s1, 'O'): %s\n", pos);
}
// strrev(): Reverse the string
strrev(s1);
printf("strrev(s1): %s\n", s1);
return 0;
}

Explanation:

  • The program demonstrates various string functions from the string.h library.
  • Functions like strcmp, strlen, strcat, strcpy, strstr, and strchr are commonly used for string operations.

Q4: What is UDF? Explain types of UDF.

A User-Defined Function (UDF) is a block of code that performs a specific task, defined by the programmer. UDFs help break down complex problems into smaller, manageable parts and allow code reuse, making programs more modular and easier to understand.

Types of UDFs in C

Functions with No Arguments and No Return Value

These functions do not take any input arguments and do not return a value.

Used for tasks like printing a message.

Example:

#include <stdio.h>

void greet() {

    printf("Hello, World!\n");

}

int main() {

    greet();

    return 0;

}

Functions with No Arguments and a Return Value

These functions do not take any input arguments but return a value.

Used for calculations or obtaining system information.

Example:

#include <stdio.h>

int getFive() {

    return 5;

}

int main() {

    int number = getFive();

    printf("Number: %d\n", number);

    return 0;

}

Functions with Arguments and No Return Value

These functions take input arguments but do not return a value.

Used for tasks that need input but do not produce a result to return.

Example:

#include <stdio.h>

void printMessage(char message[]) {

    printf("%s\n", message);

}

int main() {

    printMessage("Hello, C Programming!");

    return 0;

}

Functions with Arguments and a Return Value

These functions take input arguments and return a value.

Most versatile and commonly used type of UDF.

Example:

#include <stdio.h>

int add(int a, int b) {

    return a + b;

}

int main() {

    int sum = add(5, 3);

    printf("Sum: %d\n", sum);

    return 0;

}

Example Explained: Prime Number Check

Here’s a more detailed example using a function to check if a number is prime.

#include <stdio.h>

#include <stdbool.h>

// Function to check if a number is prime

bool isPrime(int n) {

    if (n <= 1) return false;

    for (int i = 2; i <= n / 2; i++) {

        if (n % i == 0) return false;

    }

    return true;

}

int main() {

    int number;

    printf("Enter a positive integer: ");

    scanf("%d", &number);

    if (isPrime(number)) {

        printf("%d is a prime number.\n", number);

    } else {

        printf("%d is not a prime number.\n", number);

    }

    return 0;

}

Detailed Breakdown

Function Prototype: The declaration of the function, specifying its return type and parameters.

bool isPrime(int n);

Function Definition: Contains the actual code for the function.

bool isPrime(int n) {

    if (n <= 1) return false;

    for (int i = 2; i <= n / 2; i++) {

        if (n % i == 0) return false;

    }

    return true;

}

Function Call: Where the function is invoked in the main function.

if (isPrime(number)) {

    printf("%d is a prime number.\n", number);

} else {

    printf("%d is not a prime number.\n", number);

}

This function checks if a number is prime by iterating through all numbers from 2 to half of the input number. If the input number is divisible by any of these, it's not prime.


Q5: Declaring and using functions, and explaining components of a function.

Declaring and using functions in C can make your programs more modular and easier to manage. Here’s a comprehensive overview:

Components of a Function

Function Declaration (Prototype): This tells the compiler about the function name, return type, and parameters without providing the actual body.

Function Definition: This contains the actual body of the function where the logic is implemented.

Function Call: This is where the function is invoked in the program.

Declaring a Function

To declare a function, you specify the return type, the function name, and parameters (if any).

#include <stdio.h>

// Function Declaration

int add(int, int);

int main() {

    int a = 5, b = 10;

    // Function Call

    int sum = add(a, b);

    printf("Sum: %d\n", sum);

    return 0;

}

// Function Definition

int add(int x, int y) {

    return x + y;

}

Explanation of Components

Function Declaration:

int add(int, int);

Return Type: Indicates the type of value the function returns, e.g., int.

Function Name: The name of the function, e.g., add.

Parameters: The types and names of parameters the function takes, e.g., int, int.

Function Definition:

int add(int x, int y)

 {

    return x + y;

}

Return Type: The same type as declared.

Function Name: The same name as declared.

Parameters: The names can be different from the declaration, but types must match.

Body: Contains statements that define what the function does. Here, it returns the sum of x and y.

Function Call:

int sum = add(a, b);

Function Name: The name of the function to be called.

Arguments: The actual values passed to the function, matching the parameters in type and order.

Example: Calculating Factorial

Let’s look at a slightly more complex example where we calculate the factorial of a number using a recursive function.

#include <stdio.h>

// Function Declaration

int factorial(int n);

int main() {

    int number = 5;

    // Function Call

    printf("Factorial of %d is %d\n", number, factorial(number));

    return 0;

}

// Function Definition

int factorial(int n) {

    if (n == 0) return 1;  // Base case

    else return n * factorial(n - 1);  // Recursive call

}

Explanation

Function Declaration: int factorial(int n);

Function Call: printf("Factorial of %d is %d\n", number, factorial(number));

Function Definition:

int factorial(int n) {

    if (n == 0) return 1;  // Base case

    else return n * factorial(n - 1);  // Recursive call

}

This example demonstrates recursion, where the factorial function calls itself with a decremented value of n until it reaches the base case (n == 0).

Key Points (need of user define functions)

Modularity: Functions break down a program into smaller, manageable parts.

Reusability: Functions can be reused across different programs or parts of the same program.

Readability: Functions make programs easier to read and understand.

Functions are fundamental in C programming, enabling structured, modular, and maintainable code. 


Q6: Difference between call by value and call by reference.

Functions can be invoked in two ways: Call by Value or Call by Reference. These two ways are generally differentiated by the type of values passed to them as parameters.

The parameters passed to the function are called actual parameters whereas the parameters received by the function are called formal parameters.

Call By Value in C

In call by value method of parameter passing, the values of actual parameters are copied to the function’s formal parameters.

  • There are two copies of parameters stored in different memory locations.
  • One is the original copy and the other is the function copy.
  • Any changes made inside functions are not reflected in the actual parameters of the caller.

Example of Call by Value

The following example demonstrates the call-by-value method of parameter passing

// C program to illustrate call by value
#include <stdio.h>

// Function Prototype
void swapx(int x, int y);

// Main function
int main()
{
    int a = 10, b = 20;

    // Pass by Values
    swapx(a, b); // Actual Parameters

    printf("In the Caller:\na = %d b = %d\n", a, b);

    return 0;
}

// Swap functions that swaps
// two values
void swapx(int x, int y) // Formal Parameters
{
    int t;

    t = x;
    x = y;
    y = t;

    printf("Inside Function:\nx = %d y = %d\n", x, y);
}
Output
Inside Function:
x = 20 y = 10
In the Caller:
a = 10 b = 20

Thus actual values of a and b remain unchanged even after exchanging the values of x and y in the function.

Call by Reference in C

In call by reference method of parameter passing, the address of the actual parameters is passed to the function as the formal parameters. In C, we use pointers to achieve call-by-reference.

  • Both the actual and formal parameters refer to the same locations.
  • Any changes made inside the function are actually reflected in the actual parameters of the caller.

Example of Call by Reference

The following C program is an example of a call-by-reference method.

// C program to illustrate Call by Reference
#include <stdio.h>

// Function Prototype
void swapx(int*, int*);

// Main function
int main()
{
    int a = 10, b = 20;

    // Pass reference
    swapx(&a, &b); // Actual Parameters

    printf("Inside the Caller:\na = %d b = %d\n", a, b);

    return 0;
}

// Function to swap two variables
// by references
void swapx(int* x, int* y) // Formal Parameters
{
    int t;

    t = *x;
    *x = *y;
    *y = t;

    printf("Inside the Function:\nx = %d y = %d\n", *x, *y);
}
Output
Inside the Function:
x = 20 y = 10
Inside the Caller:
a = 20 b = 10

Thus actual values of a and b get changed after exchanging values of x and y.

Difference between the Call by Value and Call by 

Call By Value

Call By Reference

While calling a function, we pass the values of variables to it. Such functions are known as “Call By Values”.While calling a function, instead of passing the values of variables, we pass the address of variables(location of variables) to the function known as “Call By References.
In this method, the value of each variable in the calling function is copied into corresponding dummy variables of the called function.In this method, the address of actual variables in the calling function is copied into the dummy variables of the called function.
With this method, the changes made to the dummy variables in the called function have no effect on the values of actual variables in the calling function.With this method, using addresses we would have access to the actual variables and hence we would be able to manipulate them.
In call-by-values, we cannot alter the values of actual variables through function calls.In call by reference, we can alter the values of variables through function calls.
Values of variables are passed by the Simple technique.Pointer variables are necessary to define to store the address values of variables.
This method is preferred when we have to pass some small values that should not change.This method is preferred when we have to pass a large amount of data to the function.
Call by value is considered safer as original data is preservedCall by reference is risky as it allows direct modification in original data

Q7: What is recursion? Explain with an example.

Function calls it self is call Recursion.

Recursion occurs when a function calls itself to solve a smaller version of the problem.

In programming, recursion is a technique where a function calls itself to solve a problem. The idea is to break down a problem into smaller, similar subproblems, until you reach a base case that can be solved directly.

Example in C: Calculating Factorial

Example:


#include <stdio.h>

// Recursive function to calculate factorial
int factorial(int n) {
if (n == 1) {
return 1;
} else {
return n * factorial(n - 1); // Function calls itself
}
}
int main() {
int num = 5;
int result = factorial(num);
printf("Factorial of %d is %d\n", num, result);
return 0;
}

Base case:

The if statement checks if n is 0. If so, the function returns 1, which is the factorial of 0.

Recursive case:

If n is not 0, the function calls itself with the argument n - 1. This continues until the base case is reached.

Unwinding:

Once the base case is reached, the recursive calls start "unwinding," returning values back up the chain of calls until the final result is returned to the original call.

In this example, factorial(5) calls factorial(4), which calls factorial(3), and so on until factorial(0) is reached. Then, the results are multiplied and returned back up the chain.

Key points:

  • Every recursive function must have a base case to stop the recursion.
  • Recursion can be a powerful technique, but it can also be less efficient than iterative solutions for some problems.
  • Use recursion when it makes the code clearer and more concise.

Explanation:

  • The factorial function calls itself to reduce the problem size.
  • For example, factorial(5) calculates 5 * factorial(4) and so on until factorial(1) is reached, which terminates the recursion.