Solutions to BCA Examination (May 2018) - C Programming
Section-A: Very Short Answer Questions
-
Differentiate between string and character array.
- A string in C is an array of characters terminated by a null character
\0. Strings are used to store and manipulate text data, and the standard library provides functions likestrlen,strcpy, andstrcatto handle strings. - A character array is simply a collection of characters. It may or may not have a null character. If it doesn’t, it cannot be considered a string. Character arrays are used for generic storage and manipulation of characters.
- A string in C is an array of characters terminated by a null character
-
What is a generic pointer? How can it be converted to a specific type of pointer?
- A generic pointer in C is a pointer of type
void*. It can point to any data type because it has no associated type information. - To convert a generic pointer to a specific type, you use type casting. For example:
int x = 10; void *ptr = &x; int *int_ptr = (int*)ptr;
- A generic pointer in C is a pointer of type
-
What is the output?
#include <stdio.h> int func(int a) { int a = 2; printf("%d", func(a)); return 0; } int func(int a) { if (a > 1) return func(--a) * 10; else return 0; }- Answer:
The code snippet contains a duplicate definition of
funcand will not compile. However, if you resolve this issue, the recursive function's base case would return 0, leading to 0 as the final output for any input.
- Answer:
The code snippet contains a duplicate definition of
-
Explain the difference between
malloc()andcalloc()functions.malloc(): Allocates a block of memory of the specified size but does not initialize it. The memory contains garbage values.calloc(): Allocates memory for an array of elements and initializes all bytes to zero. Syntax includes two parameters: the number of elements and their size.
-
Explain the importance of the
#definepreprocessor directive.- The
#definedirective is used for defining symbolic constants and macros. It improves code readability, reduces redundancy, and makes maintenance easier. For example:#define PI 3.14159 #define SQUARE(x) ((x) * (x))
- The
Section-B: Short Answer Questions
-
Write a program to sort an array.
#include <stdio.h> void sortArray(int arr[], int n) { for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - i - 1; j++) { if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } int main() { int arr[] = {5, 2, 9, 1, 5, 6}; int n = sizeof(arr) / sizeof(arr[0]); sortArray(arr, n); printf("Sorted array: "); for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } return 0; } -
Write a C program to find the reverse of each word of a string.
#include <stdio.h> #include <string.h> void reverseWord(char *start, char *end) { while (start < end) { char temp = *start; *start = *end; *end = temp; start++; end--; } } void reverseWords(char str[]) { char *start = str, *end = str; while (*end) { if (*end == ' ' || *(end + 1) == '\0') { reverseWord(start, (*end == ' ') ? end - 1 : end); start = end + 1; } end++; } } int main() { char str[] = "how are you"; reverseWords(str); printf("Reversed words: %s", str); return 0; } -
Differentiate between
rewind()andfseek(). Canfseek()work as an alternative torewind()?rewind(): Resets the file position to the beginning of a file.fseek(): Moves the file pointer to a specified position, based on an offset and a reference position.- Yes,
fseek(fp, 0, SEEK_SET)can work as an alternative torewind(fp).
Section-C: Detailed Answer Questions
-
(a) Why are arrays needed? Write a program to calculate the number of duplicate entries in an array.
- Arrays are needed to store multiple elements of the same data type in contiguous memory locations, enabling efficient indexing and manipulation.
- Program:
#include <stdio.h> void countDuplicates(int arr[], int n) { int count = 0; for (int i = 0; i < n - 1; i++) { for (int j = i + 1; j < n; j++) { if (arr[i] == arr[j]) { count++; break; } } } printf("Number of duplicate entries: %d", count); } int main() { int arr[] = {1, 2, 3, 2, 4, 5, 1}; int n = sizeof(arr) / sizeof(arr[0]); countDuplicates(arr, n); return 0; }
-
(b) With an example, explain how pointers can be used to dynamically allocate space for a two-dimensional array.
- Explanation: Pointers can dynamically allocate memory for a 2D array by allocating memory row by row using
malloc(). - Example:
#include <stdio.h> #include <stdlib.h> int main() { int rows = 3, cols = 4; int **arr = (int**)malloc(rows * sizeof(int*)); for (int i = 0; i < rows; i++) { arr[i] = (int*)malloc(cols * sizeof(int)); } for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { arr[i][j] = i * cols + j; printf("%d ", arr[i][j]); } printf("\n"); } for (int i = 0; i < rows; i++) { free(arr[i]); } free(arr); return 0; }
11. (a) Create a Structure BANK to Maintain Customer Records
Below is the solution that implements a structure
BANK, which includes features for adding a new customer, updating their balance, and displaying customer details.Program to Create and Manage Bank Customer Records
#include <stdio.h> #include <string.h> // Structure definition for BANK struct BANK { int cust_id; char name[50]; char account_type[20]; double balance; }; // Function to add a new record void add_record(struct BANK *customer, int id, const char *name, const char *type, double balance) { customer->cust_id = id; strcpy(customer->name, name); strcpy(customer->account_type, type); customer->balance = balance; } // Function to update balance (deposit/withdraw) void update_balance(struct BANK *customer, double amount, int deposit) { if (deposit) { customer->balance += amount; // Deposit printf("Amount Deposited. New Balance: %.2f\n", customer->balance); } else if (customer->balance >= amount) { customer->balance -= amount; // Withdraw printf("Amount Withdrawn. New Balance: %.2f\n", customer->balance); } else { printf("Insufficient Balance for Withdrawal.\n"); } } // Function to display customer details void display_record(struct BANK customer) { printf("\nCustomer ID: %d\n", customer.cust_id); printf("Name: %s\n", customer.name); printf("Account Type: %s\n", customer.account_type); printf("Balance: %.2f\n", customer.balance); } int main() { struct BANK customer; // Add a new customer add_record(&customer, 101, "John Doe", "Savings", 5000.00); printf("Initial Record:\n"); display_record(customer); // Update the balance (Deposit 2000) printf("\nDepositing Amount...\n"); update_balance(&customer, 2000.00, 1); // Update the balance (Withdraw 1500) printf("\nWithdrawing Amount...\n"); update_balance(&customer, 1500.00, 0); return 0; }
Output for the Above Program:
Initial Record: Customer ID: 101 Name: John Doe Account Type: Savings Balance: 5000.00 Depositing Amount... Amount Deposited. New Balance: 7000.00 Withdrawing Amount... Amount Withdrawn. New Balance: 5500.00
11. (b) Menu-Driven Program for Bank Management
This program allows a user to interact with multiple customer records in a menu-driven way. Users can add records, deposit/withdraw money, and view all customer records.
Code for the Menu-Driven Program
#include <stdio.h> #include <stdlib.h> #include <string.h> // Structure definition for BANK struct BANK { int cust_id; char name[50]; char account_type[20]; double balance; }; // Function prototypes void add_record(struct BANK *customers, int *count); void deposit_money(struct BANK *customers, int count); void withdraw_money(struct BANK *customers, int count); void display_all_records(struct BANK *customers, int count); int main() { struct BANK customers[100]; int count = 0, choice; while (1) { printf("\n--- Bank Management System ---\n"); printf("1. Add New Record\n"); printf("2. Deposit Money\n"); printf("3. Withdraw Money\n"); printf("4. Display All Records\n"); printf("5. Exit\n"); printf("Enter your choice: "); scanf("%d", &choice); switch (choice) { case 1: add_record(customers, &count); break; case 2: deposit_money(customers, count); break; case 3: withdraw_money(customers, count); break; case 4: display_all_records(customers, count); break; case 5: exit(0); default: printf("Invalid Choice! Try Again.\n"); } } return 0; } // Function to add a new record void add_record(struct BANK *customers, int *count) { printf("Enter Customer ID: "); scanf("%d", &customers[*count].cust_id); printf("Enter Name: "); scanf(" %[^\n]", customers[*count].name); printf("Enter Account Type: "); scanf("%s", customers[*count].account_type); printf("Enter Initial Balance: "); scanf("%lf", &customers[*count].balance); (*count)++; printf("Record Added Successfully!\n"); } // Function to deposit money void deposit_money(struct BANK *customers, int count) { int id, i; double amount; printf("Enter Customer ID: "); scanf("%d", &id); for (i = 0; i < count; i++) { if (customers[i].cust_id == id) { printf("Enter Deposit Amount: "); scanf("%lf", &amount); customers[i].balance += amount; printf("Deposit Successful. Updated Balance: %.2f\n", customers[i].balance); return; } } printf("Customer ID Not Found.\n"); } // Function to withdraw money void withdraw_money(struct BANK *customers, int count) { int id, i; double amount; printf("Enter Customer ID: "); scanf("%d", &id); for (i = 0; i < count; i++) { if (customers[i].cust_id == id) { printf("Enter Withdrawal Amount: "); scanf("%lf", &amount); if (customers[i].balance >= amount) { customers[i].balance -= amount; printf("Withdrawal Successful. Updated Balance: %.2f\n", customers[i].balance); } else { printf("Insufficient Balance.\n"); } return; } } printf("Customer ID Not Found.\n"); } // Function to display all customer records void display_all_records(struct BANK *customers, int count) { printf("\n--- Customer Records ---\n"); for (int i = 0; i < count; i++) { printf("ID: %d, Name: %s, Type: %s, Balance: %.2f\n", customers[i].cust_id, customers[i].name, customers[i].account_type, customers[i].balance); } }
Key Features of the Program:
- Add Record: Enables the user to input customer details.
- Deposit Money: Allows deposits into a customer's account.
- Withdraw Money: Enables withdrawals while checking for sufficient balance.
- Display Records: Lists all customer details.
Output Example for Menu-Driven Program:
--- Bank Management System --- 1. Add New Record 2. Deposit Money 3. Withdraw Money 4. Display All Records 5. Exit Enter your choice: 1 Enter Customer ID: 101 Enter Name: John Doe Enter Account Type: Savings Enter Initial Balance: 5000 Record Added Successfully! Enter your choice: 4 --- Customer Records --- ID: 101, Name: John Doe, Type: Savings, Balance: 5000.0012. Macros in C Programming
Macros are preprocessor directives in C, which are processed before the compilation stage. They provide a way to define constants, inline functions, or repetitive tasks in a program, improving code readability and maintainability.
12(a). What is a Macro?
A macro is a fragment of code that is given a name. Whenever the name is used, it gets replaced by the contents of the macro. Macros are handled by the preprocessor, and they are defined using the
#definedirective.Types of Macros:
- Object-like Macro: Used to define constants.
- Function-like Macro: Used to define reusable code blocks, mimicking functions.
Examples of Object-like Macros
#include <stdio.h> #define PI 3.14159 // Defining a constant for Pi #define MAX 100 // Defining the maximum limit int main() { printf("Value of PI: %.2f\n", PI); printf("Maximum Limit: %d\n", MAX); return 0; }Output:
Value of PI: 3.14 Maximum Limit: 100Examples of Function-like Macros
Function-like macros are used to perform small operations without the overhead of a function call. However, they do not check for types or scope, so careful usage is necessary.
#include <stdio.h> #define SQUARE(x) ((x) * (x)) // Macro to calculate square of a number #define MAXIMUM(a, b) ((a) > (b) ? (a) : (b)) // Macro to find maximum int main() { int num = 5; printf("Square of %d: %d\n", num, SQUARE(num)); printf("Maximum of 5 and 10: %d\n", MAXIMUM(5, 10)); return 0; }Output:
Square of 5: 25 Maximum of 5 and 10: 1012(b). Difference Between Macro and Function
Aspect Macro Function Definition Preprocessor directive; substituted before compilation. Block of code executed during runtime. Execution Inline substitution, no function call overhead. Requires a function call. Type Checking No type checking; may cause unexpected behavior. Enforces type checking. Debugging Difficult to debug due to direct text substitution. Easier to debug. Scope Global; cannot be limited to a specific block or function. Local to where it's defined. 12(c). Advantages and Disadvantages of Macros
Advantages:
- Improves Readability: Constants like
#define PI 3.14are easier to understand. - No Function Call Overhead: Increases performance for small operations.
- Reusability: Macros can replace repetitive code, making programs concise.
Disadvantages:
- No Type Checking: Misuse may lead to unexpected errors.
- Complexity in Debugging: Errors in macros are harder to trace.
- Code Bloat: Inline expansion may increase program size.
12(d). Applications of Macros
- Defining Constants: Commonly used for values that do not change (e.g.,
PI,MAX_LIMIT). - Inline Functions: To perform small, repetitive tasks (e.g.,
SQUARE(x)). - Conditional Compilation: Used for platform-specific code (e.g.,
#ifdefdirectives).
12(e). Example: Conditional Compilation with Macros
Macros are often used to include or exclude code depending on conditions, making the code portable.
#include <stdio.h> #define WINDOWS 1 // 1 for Windows, 0 for Linux int main() { #if WINDOWS printf("This code runs on Windows.\n"); #else printf("This code runs on Linux.\n"); #endif return 0; }Output (when
WINDOWSis 1):This code runs on Windows.12(f). Limitations of Macros
- Lack of Scope: Macros cannot have local scope, which can lead to naming conflicts.
- No Debugging Information: Preprocessor removes macros before compilation, so debugging tools cannot trace them.
- Unintended Side Effects: Improper usage of macros like
SQUARE(a + b)may expand incorrectly (((a + b) * (a + b))).
Complete Example Combining Macro Concepts
Below is a complete example demonstrating multiple macro functionalities:
#include <stdio.h> #define PI 3.14159 #define AREA_CIRCLE(r) (PI * (r) * (r)) #define DEBUG 1 // Enable debugging int main() { float radius = 5.0; #if DEBUG printf("Debugging is enabled.\n"); #endif printf("Area of Circle with radius %.2f: %.2f\n", radius, AREA_CIRCLE(radius)); return 0; }Output (with
DEBUGenabled):Debugging is enabled. Area of Circle with radius 5.00: 78.5413. Explain the use of bitwise operators in programming
Bitwise Operators in C
Bitwise operators in C perform operations at the binary level. These operators work directly on bits and are commonly used in low-level programming such as embedded systems, cryptography, and memory optimization.
Types of Bitwise Operators
-
Bitwise AND (
&)- Performs a logical AND operation on each bit of two numbers.
- The result is
1if both bits are1; otherwise, it is0.
Example:
int a = 5, b = 3; // Binary: a = 0101, b = 0011 int result = a & b; // result = 0001 (1 in decimal) printf("Bitwise AND: %d\n", result);Output:
Bitwise AND: 1 -
Bitwise OR (
|)- Performs a logical OR operation on each bit of two numbers.
- The result is
1if either bit is1.
Example:
int a = 5, b = 3; // Binary: a = 0101, b = 0011 int result = a | b; // result = 0111 (7 in decimal) printf("Bitwise OR: %d\n", result);Output:
Bitwise OR: 7 -
Bitwise XOR (
^)- Performs an exclusive OR operation on each bit.
- The result is
1if the bits are different; otherwise, it is0.
Example:
int a = 5, b = 3; // Binary: a = 0101, b = 0011 int result = a ^ b; // result = 0110 (6 in decimal) printf("Bitwise XOR: %d\n", result);Output:
Bitwise XOR: 6 -
Bitwise NOT (
~)- Inverts all bits of a number (1 becomes 0, and 0 becomes 1).
- Works only on a single operand.
Example:
int a = 5; // Binary: a = 0101 int result = ~a; // result = 1010 (in two's complement: -6 in decimal) printf("Bitwise NOT: %d\n", result);Output:
Bitwise NOT: -6 -
Left Shift (
<<)- Shifts the bits of a number to the left by a specified number of positions.
- Each shift doubles the number.
Example:
int a = 5; // Binary: a = 0101 int result = a << 1; // result = 1010 (10 in decimal) printf("Left Shift: %d\n", result);Output:
Left Shift: 10 -
Right Shift (
>>)- Shifts the bits of a number to the right by a specified number of positions.
- Each shift halves the number (ignoring the remainder).
Example:
int a = 5; // Binary: a = 0101 int result = a >> 1; // result = 0010 (2 in decimal) printf("Right Shift: %d\n", result);Output:
Right Shift: 2
Program Demonstrating All Bitwise Operators
Here is a program to demonstrate all the bitwise operators:
#include <stdio.h> int main() { int a = 5, b = 3; // Binary: a = 0101, b = 0011 // Bitwise AND printf("Bitwise AND (a & b): %d\n", a & b); // Bitwise OR printf("Bitwise OR (a | b): %d\n", a | b); // Bitwise XOR printf("Bitwise XOR (a ^ b): %d\n", a ^ b); // Bitwise NOT printf("Bitwise NOT (~a): %d\n", ~a); // Left Shift printf("Left Shift (a << 1): %d\n", a << 1); // Right Shift printf("Right Shift (a >> 1): %d\n", a >> 1); return 0; }Output
Bitwise AND (a & b): 1 Bitwise OR (a | b): 7 Bitwise XOR (a ^ b): 6 Bitwise NOT (~a): -6 Left Shift (a << 1): 10 Right Shift (a >> 1): 2Applications of Bitwise Operators
-
Setting and Clearing Bits
- To set a bit: Use
|(OR) with a mask. - To clear a bit: Use
&(AND) with the complement of a mask.
Example: Setting the 2nd bit of a number
int num = 5; // Binary: 0101 num = num | (1 << 1); // Set 2nd bit printf("After Setting 2nd Bit: %d\n", num); // Output: 7Example: Clearing the 2nd bit of a number
int num = 7; // Binary: 0111 num = num & ~(1 << 1); // Clear 2nd bit printf("After Clearing 2nd Bit: %d\n", num); // Output: 5 - To set a bit: Use
-
Swapping Two Numbers Without Using a Temporary Variable
int a = 5, b = 3; a = a ^ b; // Step 1 b = a ^ b; // Step 2 a = a ^ b; // Step 3 printf("After Swapping: a = %d, b = %d\n", a, b);Output:
a = 3, b = 5 -
Efficient Multiplication and Division by Powers of 2
- Left shift (
<<) multiplies a number by 2. - Right shift (
>>) divides a number by 2.
Example:
int num = 4; printf("Multiplying by 2: %d\n", num << 1); // Output: 8 printf("Dividing by 2: %d\n", num >> 1); // Output: 2 - Left shift (
-
Finding Whether a Number is Even or Odd
- Use the
&operator to check the least significant bit.
int num = 5; if (num & 1) printf("%d is Odd\n", num); else printf("%d is Even\n", num);Output:
5 is Odd - Use the
Conclusion
Bitwise operators are essential tools in C programming for optimizing code performance. They allow direct manipulation of bits, making them highly efficient in tasks such as:
- Encryption
- Data compression
- Graphics processing
- Embedded systems development.
By understanding and applying these operators, developers can write powerful and optimized programs.

Comments
Post a Comment