BE Computer Engineering (Pokhara University) Programming in C (PU, CMP 124) Question Paper 2079 Nepal
This is the official BE Computer Engineering (Pokhara University) Programming in C (PU, CMP 124) question paper for 2079, as set in the regular annual examination. It carries 100 full marks and a time allowance of 180 minutes, across 12 questions. On Kekkei you can attempt this Programming in C (PU, CMP 124) past paper online with a timer, get instant AI feedback and step-by-step solutions, and track the topics where you lose marks — completely free. Whether you are revising for your BE Computer Engineering (Pokhara University) Programming in C (PU, CMP 124) exam or solving previous years' question papers, this 2079 paper is a great way to practise under real exam conditions.
Section A: Long Answer Questions
Attempt all / any as specified.
(a) Explain the basic structure of a C program with the help of a suitable example, clearly identifying the preprocessor directives, the main() function, declaration section and the executable statements. (6)
(b) Differentiate between the following pairs of data types in C, stating the typical size and range of each on a 32-bit system: (i) int vs unsigned int and (ii) float vs double. Explain what is meant by type conversion and distinguish between implicit and explicit (type-casting) conversion with one example each. (6)
(a) Basic structure of a C program (6)
Every C program is built from a few well-defined sections. A minimal example:
#include <stdio.h> /* 1. Preprocessor directive */
#define PI 3.14159 /* symbolic constant */
int main(void) /* 2. main() function */
{
float r, area; /* 3. Declaration section */
printf("Enter radius: "); /* 4. Executable statements */
scanf("%f", &r);
area = PI * r * r;
printf("Area = %f\n", area);
return 0; /* return value to OS */
}
- Preprocessor directives (
#include,#define): processed before compilation.#include <stdio.h>pulls in the standard I/O header soprintf/scanfcan be used;#definecreates symbolic constants/macros. main()function: the entry point where execution begins. Every C program must have exactly onemain().- Declaration section: variables (e.g.
float r, area;) are declared with their data types before use. - Executable statements: the actual instructions (input, processing, output) ending with
return 0;which signals successful termination.
(b) Data types, sizes and type conversion (6)
(i) int vs unsigned int (typically 4 bytes / 32 bits each):
| Type | Size | Range |
|---|---|---|
int | 4 bytes | to = to |
unsigned int | 4 bytes | to = to |
int is signed (stores negatives using the sign bit); unsigned int has no sign bit, so all bits represent magnitude, doubling the positive range.
(ii) float vs double:
| Type | Size | Range (approx.) | Precision |
|---|---|---|---|
float | 4 bytes | ~6–7 digits | |
double | 8 bytes | ~15–16 digits |
double (double precision) stores more bits, giving greater range and accuracy than float (single precision).
Type conversion means converting a value of one data type into another.
- Implicit conversion (type promotion): done automatically by the compiler, usually from a lower to a higher type to avoid data loss.
int i = 5; float f; f = i + 2.5; /* i promoted to float automatically -> 7.5 */ - Explicit conversion (type casting): done manually by the programmer using a cast operator
(type).float x = 7.9; int y = (int)x; /* x explicitly cast to int -> 7 (fraction dropped) */
(a) What is recursion? Differentiate between recursion and iteration in terms of memory usage and execution speed. (4)
(b) Write a C program using a recursive function to compute the factorial of a non-negative integer n entered by the user. Show how the recursive calls are placed on and removed from the stack for the input n = 4. (6)
(c) Explain call by value and call by reference with a C example of a swap() function for each, and state which one actually exchanges the values of the caller's variables and why. (4)
(a) Recursion vs Iteration (4)
Recursion is a technique in which a function calls itself (directly or indirectly) to solve a problem by reducing it to smaller sub-problems, until a base case stops the calls.
| Aspect | Recursion | Iteration |
|---|---|---|
| Memory usage | High — each call pushes a new stack frame (parameters, locals, return address) | Low — uses a single set of variables |
| Execution speed | Slower — overhead of function calls and stack management | Faster — no call overhead |
| Risk | Stack overflow if too deep | No such risk |
| Code | Compact, elegant | Often longer but efficient |
(b) Recursive factorial + stack trace (6)
#include <stdio.h>
long factorial(int n) {
if (n == 0 || n == 1) /* base case */
return 1;
return n * factorial(n - 1); /* recursive case */
}
int main(void) {
int n;
printf("Enter a non-negative integer: ");
scanf("%d", &n);
printf("%d! = %ld\n", n, factorial(n));
return 0;
}
Stack behaviour for n = 4 — calls are pushed until the base case, then popped as they return:
Pushing (winding):
factorial(4) -> 4 * factorial(3)
factorial(3) -> 3 * factorial(2)
factorial(2) -> 2 * factorial(1)
factorial(1) -> 1 (base case reached)
Popping (unwinding) — each frame returns its result to the one below it:
factorial(1) returns 1
factorial(2) returns 2 * 1 = 2
factorial(3) returns 3 * 2 = 6
factorial(4) returns 4 * 6 = 24
Final result: .
(c) Call by value vs Call by reference (4)
Call by value: a copy of the argument is passed; changes inside the function do not affect the caller's variables.
void swap(int x, int y) { /* copies */
int t = x; x = y; y = t;
} /* a, b in main remain unchanged */
Call by reference: the addresses of the variables are passed (via pointers); the function works on the originals.
void swap(int *x, int *y) { /* addresses */
int t = *x; *x = *y; *y = t;
}
int main(void){ int a=3,b=5; swap(&a,&b); /* now a=5, b=3 */ }
Call by reference actually exchanges the caller's values, because the function dereferences the passed addresses and modifies the original memory locations, whereas call by value only modifies local copies.
(a) What is a pointer? Explain the & (address-of) and * (dereference) operators with a short program that prints the address and value of a variable using a pointer. (5)
(b) Explain the relationship between arrays and pointers in C. Given the declaration int a[5];, show how a[i] can be accessed using pointer notation. (4)
(c) Describe the use of the functions malloc(), calloc(), realloc() and free() for dynamic memory management. Write a C program that dynamically allocates memory for n integers, reads them, and prints their sum. (5)
(a) Pointers and the & / * operators (5)
A pointer is a variable that stores the memory address of another variable rather than a data value itself.
&(address-of) gives the memory address of a variable.*(dereference / indirection) accesses the value stored at the address held by a pointer.
#include <stdio.h>
int main(void) {
int x = 10;
int *p = &x; /* p holds the address of x */
printf("Address of x : %p\n", (void*)p); /* same as &x */
printf("Value of x : %d\n", *p); /* dereference -> 10 */
return 0;
}
(b) Arrays and pointers (4)
In C, an array name acts as a constant pointer to its first element: a is equivalent to &a[0]. Pointer arithmetic accounts for element size, so a + i points to element i.
For int a[5];, element a[i] can be accessed equivalently as:
int a[5] = {10,20,30,40,50};
int *p = a;
printf("%d", a[2]); /* 30 */
printf("%d", *(a + 2)); /* 30 */
printf("%d", *(p + 2)); /* 30 */
Thus a[i], *(a+i), *(p+i) and p[i] are all equivalent.
(c) Dynamic memory management (5)
malloc(size)— allocates a block ofsizebytes; memory is uninitialised (garbage). Returnsvoid*orNULLon failure.calloc(n, size)— allocates memory fornelements ofsizebytes each and initialises all bytes to zero.realloc(ptr, newsize)— resizes a previously allocated block tonewsizebytes, preserving existing data.free(ptr)— releases memory previously allocated, preventing memory leaks.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n, i, sum = 0;
printf("Enter n: ");
scanf("%d", &n);
int *arr = (int*)malloc(n * sizeof(int));
if (arr == NULL) { printf("Allocation failed\n"); return 1; }
for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
sum += arr[i];
}
printf("Sum = %d\n", sum);
free(arr); /* release memory */
return 0;
}
(a) Define a structure Student containing the members roll (integer), name (character array) and marks (float). Write a C program that reads the records of n students and writes them to a file named students.dat, then reads the records back from the file and displays them. (7)
(b) Differentiate between a structure and a union in C with respect to memory allocation, using a suitable example. (3)
(a) Student structure with file I/O (7)
#include <stdio.h>
struct Student {
int roll;
char name[50];
float marks;
};
int main(void) {
int n, i;
struct Student s;
FILE *fp;
printf("How many students? ");
scanf("%d", &n);
/* ---- write records to file ---- */
fp = fopen("students.dat", "wb");
if (fp == NULL) { printf("Cannot open file\n"); return 1; }
for (i = 0; i < n; i++) {
printf("Roll, Name, Marks: ");
scanf("%d %s %f", &s.roll, s.name, &s.marks);
fwrite(&s, sizeof(struct Student), 1, fp);
}
fclose(fp);
/* ---- read records back and display ---- */
fp = fopen("students.dat", "rb");
if (fp == NULL) { printf("Cannot open file\n"); return 1; }
printf("\nRoll\tName\tMarks\n");
while (fread(&s, sizeof(struct Student), 1, fp) == 1) {
printf("%d\t%s\t%.2f\n", s.roll, s.name, s.marks);
}
fclose(fp);
return 0;
}
The records are written in binary mode with fwrite() and read back with fread() until end of file.
(b) Structure vs Union (3)
| Aspect | struct | union |
|---|---|---|
| Memory | Allocates separate memory for every member; total size = sum of member sizes (plus padding) | Allocates memory equal to the size of its largest member; all members share it |
| Access | All members hold valid values simultaneously | Only one member holds a valid value at a time |
struct S { int a; char b; float c; }; /* size ~ 12 bytes */
union U { int a; char b; float c; }; /* size = 4 bytes (largest) */
In a union, writing to one member overwrites the others because they occupy the same memory location, so unions save memory when only one member is needed at a time.
Section B: Short Answer Questions
Attempt all / any as specified.
Differentiate between while and do-while loops. Write a C program using a loop to check whether a given integer is a prime number.
while vs do-while
while loop | do-while loop |
|---|---|
| Entry-controlled — condition tested before the body | Exit-controlled — condition tested after the body |
| Body may execute zero times if the condition is false initially | Body always executes at least once |
Syntax: while(cond){ ... } | Syntax: do{ ... }while(cond); |
C program to check whether a number is prime
#include <stdio.h>
int main(void) {
int n, i, isPrime = 1;
printf("Enter an integer: ");
scanf("%d", &n);
if (n <= 1)
isPrime = 0;
else {
for (i = 2; i <= n / 2; i++) {
if (n % i == 0) { isPrime = 0; break; }
}
}
if (isPrime) printf("%d is a prime number\n", n);
else printf("%d is not a prime number\n", n);
return 0;
}
A number is prime if it is not divisible by any integer from to .
Evaluate the following C expressions, given int a = 5, b = 2, c; and state the value of the result and of any modified variable in each case:
(a) c = a++ + ++b;
(b) c = a % b + a / b;
(c) c = (a > b) ? a : b;
Also explain the difference between the = and == operators.
Given int a = 5, b = 2, c; (each part evaluated independently from these initial values):
(a) c = a++ + ++b;
a++is post-increment: uses5, thenabecomes6.++bis pre-increment:bbecomes3, value used is3.- .
- Result:
c = 8,a = 6,b = 3.
(b) c = a % b + a / b; (with a = 5, b = 2)
a % b= (remainder).a / b= (integer division).- .
- Result:
c = 3.
(c) c = (a > b) ? a : b; (with a = 5, b = 2)
- Condition
a > bi.e.5 > 2is true, so the value before:(a) is chosen. - Result:
c = 5.
= vs ==
=is the assignment operator: it stores the value on its right into the variable on its left, e.g.x = 5.==is the equality (relational) operator: it compares two operands and yields1(true) or0(false), e.g.x == 5.
Using = where == is intended (e.g. if (x = 5)) is a common bug — it assigns instead of comparing and the condition becomes true for any non-zero value.
Write a C program that reads a string from the user and counts the number of vowels, consonants and spaces in it without using any built-in string library function.
C program to count vowels, consonants and spaces (no string library)
#include <stdio.h>
int main(void) {
char str[200], ch;
int i = 0, vowels = 0, consonants = 0, spaces = 0;
printf("Enter a string: ");
fgets(str, sizeof(str), stdin); /* reads line incl. spaces */
for (i = 0; str[i] != '\0'; i++) {
ch = str[i];
/* convert uppercase to lowercase manually */
if (ch >= 'A' && ch <= 'Z')
ch = ch + 32;
if (ch == 'a' || ch == 'e' || ch == 'i' ||
ch == 'o' || ch == 'u')
vowels++;
else if (ch >= 'a' && ch <= 'z')
consonants++;
else if (ch == ' ')
spaces++;
}
printf("Vowels = %d\n", vowels);
printf("Consonants = %d\n", consonants);
printf("Spaces = %d\n", spaces);
return 0;
}
The loop walks the array until the null terminator '\0'. Each character is classified using ASCII range checks only (no strlen, isalpha, etc.). Uppercase letters are folded to lowercase by adding 32 so a single set of comparisons suffices.
Write a C program to find the largest and the second largest element in a one-dimensional array of n integers entered by the user.
C program to find largest and second largest elements
#include <stdio.h>
#include <limits.h>
int main(void) {
int n, i, a[100];
int largest = INT_MIN, second = INT_MIN;
printf("Enter number of elements: ");
scanf("%d", &n);
printf("Enter %d integers:\n", n);
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
for (i = 0; i < n; i++) {
if (a[i] > largest) {
second = largest; /* old largest becomes second */
largest = a[i];
} else if (a[i] > second && a[i] != largest) {
second = a[i];
}
}
printf("Largest = %d\n", largest);
if (second == INT_MIN)
printf("No distinct second largest element\n");
else
printf("Second largest = %d\n", second);
return 0;
}
The array is scanned once. Whenever a new maximum is found, the previous maximum slides down to second; otherwise an element larger than second (but not equal to the largest) updates second. This single-pass approach runs in time.
Differentiate between the break and continue statements with a suitable example of each. Write a C program using nested loops to print the following pattern:
1
1 2
1 2 3
1 2 3 4
break vs continue
breakimmediately terminates the nearest enclosing loop (orswitch) and transfers control to the statement after it.for (i = 1; i <= 10; i++) { if (i == 5) break; /* loop stops at 5; prints 1 2 3 4 */ printf("%d ", i); }continueskips the rest of the current iteration and jumps to the loop's next iteration (condition/update).for (i = 1; i <= 5; i++) { if (i == 3) continue; /* skips 3; prints 1 2 4 5 */ printf("%d ", i); }
C program to print the pattern
#include <stdio.h>
int main(void) {
int i, j;
for (i = 1; i <= 4; i++) { /* one row per i */
for (j = 1; j <= i; j++) /* print 1..i */
printf("%d ", j);
printf("\n");
}
return 0;
}
Output:
1
1 2
1 2 3
1 2 3 4
The outer loop controls the row number, and the inner loop prints numbers 1 to i on that row.
Explain how a two-dimensional array is stored in memory in C (row-major order). Write a C program to read a 3 x 3 matrix and find the sum of its diagonal elements.
Storage of a 2-D array (row-major order)
C stores a two-dimensional array in row-major order: the elements of the first row are stored contiguously, followed by the second row, and so on (memory is one-dimensional). For an array int a[R][C], the address of element a[i][j] is:
Example for int a[2][3] — storage order is:
a[0][0], a[0][1], a[0][2], a[1][0], a[1][1], a[1][2].
C program: sum of diagonal elements of a 3 x 3 matrix
#include <stdio.h>
int main(void) {
int a[3][3], i, j, sum = 0;
printf("Enter 9 elements of 3x3 matrix:\n");
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
scanf("%d", &a[i][j]);
for (i = 0; i < 3; i++)
sum += a[i][i]; /* main diagonal: row index == column index */
printf("Sum of main diagonal = %d\n", sum);
return 0;
}
The main-diagonal elements are those where the row index equals the column index, i.e. a[0][0], a[1][1], a[2][2].
List the different file opening modes in C (r, w, a, r+, w+, a+) and explain the purpose of each. State the difference between a text file and a binary file.
File opening modes in C
| Mode | Purpose |
|---|---|
r | Open an existing file for reading only. Fails (returns NULL) if the file does not exist. |
w | Open for writing. Creates the file if absent; if it exists, its contents are truncated (erased). |
a | Open for appending. Writes are added at the end; file created if absent; existing data preserved. |
r+ | Open existing file for reading and writing. File must already exist; contents not erased. |
w+ | Open for reading and writing; creates/truncates the file (existing contents lost). |
a+ | Open for reading and appending; created if absent, writes always go to the end. |
(Adding b, e.g. rb, wb, opens the file in binary mode.)
Text file vs Binary file
| Text file | Binary file |
|---|---|
| Stores data as human-readable characters (ASCII) | Stores data in the same internal byte format as in memory |
Newlines may be translated (e.g. \n ↔ \r\n) | No character translation occurs |
| Numbers stored as digit characters | Numbers stored as raw bytes (e.g. 4-byte int) |
Read/written with fprintf, fscanf, fgets | Read/written with fwrite, fread |
Write short notes on any THREE of the following:
(a) Storage classes in C (auto, register, static, extern)
(b) The C preprocessor and #define macros
(c) Difference between getchar()/putchar() and scanf()/printf()
(d) Enumerated data type (enum)
Short notes on any THREE:
(a) Storage classes in C
A storage class defines a variable's scope, lifetime, default initial value and storage location.
auto— default for local variables; scope is local to the block, lifetime ends when the block exits, stored in stack, garbage initial value.register— requests the variable be stored in a CPU register for faster access (e.g. loop counters);&(address) cannot be taken.static— preserves a local variable's value between function calls (lifetime = whole program); initialised once to 0 by default; scope still local.extern— declares a global variable defined in another file/translation unit, giving it external linkage so it can be shared across files.
(b) The C preprocessor and #define macros
The preprocessor runs before compilation and handles all lines beginning with #. #include inserts header files and #define creates macros. A #define macro performs simple textual substitution:
#define PI 3.14159 /* object-like (symbolic constant) */
#define SQ(x) ((x)*(x)) /* function-like macro */
area = PI * SQ(r); /* expands to ((r)*(r)) */
Macros have no type checking and are not actual functions; parentheses are used to avoid precedence errors.
(c) getchar()/putchar() vs scanf()/printf()
getchar()/putchar()read/write a single character at a time from/to standard I/O; they are simple and fast for character processing.scanf()/printf()are formatted I/O functions that handle multiple values of different data types using format specifiers (%d,%f,%s, …). They are more flexible but heavier than the single-character functions.
(d) Enumerated data type (enum)
An enum defines a user-defined type whose values are named integer constants, improving readability.
enum Weekday { MON, TUE, WED, THU, FRI }; /* MON=0, TUE=1, ... */
enum Weekday today = WED; /* today holds 2 */
By default the first constant is 0 and each subsequent one increases by 1; values may also be assigned explicitly (e.g. enum {LOW=1, HIGH=10};).
Frequently asked questions
- Where can I find the BE Computer Engineering (Pokhara University) Programming in C (PU, CMP 124) question paper 2079?
- The full BE Computer Engineering (Pokhara University) Programming in C (PU, CMP 124) 2079 (regular) question paper is available free on Kekkei. You can read every question online and attempt the paper under timed exam conditions.
- Does the Programming in C (PU, CMP 124) 2079 paper come with solutions?
- Yes. Every question on this Programming in C (PU, CMP 124) past paper includes a step-by-step solution, plus instant AI feedback when you attempt it on Kekkei.
- How many marks is the BE Computer Engineering (Pokhara University) Programming in C (PU, CMP 124) 2079 paper?
- The BE Computer Engineering (Pokhara University) Programming in C (PU, CMP 124) 2079 paper carries 100 full marks and is meant to be completed in 180 minutes, across 12 questions.
- Is practising this Programming in C (PU, CMP 124) past paper free?
- Yes — reading and attempting this Programming in C (PU, CMP 124) past paper on Kekkei is completely free.