Browse papers
A

Section A: Long Answer Questions

Attempt all / any as specified.

4 questions
1long12 marks

(a) With the help of a neat diagram, explain the basic structure of a C program, clearly describing the role of the preprocessor directives, the main() function, declaration section and the executable statements. (6)

(b) Distinguish between int, float, double and char data types in C in terms of their typical size (in bytes) and range. Write a C program that reads a Celsius temperature from the user and prints the equivalent Fahrenheit temperature, using appropriate data types and format specifiers. (6)

(a) Basic structure of a C program

A C program is organised into well-defined sections. A typical layout is:

#include <stdio.h>      /* 1. Preprocessor directive */
#define PI 3.14159       /* symbolic constant */

int main(void)           /* 3. main() function    */
{
    int radius = 5;      /* 4. Declaration section */
    float area;

    area = PI * radius * radius;  /* 5. Executable statements */
    printf("Area = %f\n", area);
    return 0;
}

Diagram (described): a vertical stack of boxes — Preprocessor directives on top, then Global declarations, then the main() function box which itself contains an inner box split into Declaration section and Executable statements, ending with return.

  • Preprocessor directives (#include, #define): processed before compilation. #include pastes header files (e.g. stdio.h for printf/scanf); #define defines macros/constants.
  • main() function: the mandatory entry point; execution always begins here. Returns an int status code to the OS (0 = success).
  • Declaration section: declares the variables and their data types used in the function before they are used.
  • Executable statements: the actual instructions (assignments, I/O, loops, function calls) that perform the program's logic, terminated by ;.

(b) int, float, double, char

TypeTypical sizeTypical range
char1 byte128-128 to 127127 (or 00255255 unsigned)
int4 bytes2,147,483,648-2{,}147{,}483{,}648 to 2,147,483,6472{,}147{,}483{,}647
float4 bytes±3.4×1038\approx \pm 3.4\times10^{38}, ~6–7 significant digits
double8 bytes±1.7×10308\approx \pm 1.7\times10^{308}, ~15–16 significant digits

char stores a single character/small integer, int whole numbers, float single-precision reals, double double-precision reals (more accuracy and range).

Celsius to Fahrenheit program (F=95C+32F = \frac{9}{5}C + 32):

#include <stdio.h>

int main(void)
{
    float celsius, fahrenheit;

    printf("Enter temperature in Celsius: ");
    scanf("%f", &celsius);

    fahrenheit = (9.0f / 5.0f) * celsius + 32.0f;

    printf("%.2f C = %.2f F\n", celsius, fahrenheit);
    return 0;
}

Note the use of float with the %f format specifier and 9.0/5.0 (floating-point division) to avoid integer truncation.

program-structuredata-typesoperators
2long14 marks

(a) Differentiate between the while, do...while and for looping constructs in C with their general syntax and a suitable example of each. State clearly the situation in which a do...while loop is preferred. (7)

(b) Write a C program using a switch...case statement that behaves as a simple calculator. The program should read two operands and an operator (+, -, *, /) from the user and display the result. Handle the division-by-zero case appropriately. (7)

(a) while vs do...while vs for

ConstructSyntaxType
whilewhile(cond){ body }Entry-controlled
do...whiledo{ body }while(cond);Exit-controlled
forfor(init; cond; update){ body }Entry-controlled

while (test first):

int i = 1;
while (i <= 5) { printf("%d ", i); i++; }

do...while (body runs at least once):

int i = 1;
do { printf("%d ", i); i++; } while (i <= 5);

for (counter loops):

for (int i = 1; i <= 5; i++) printf("%d ", i);
  • while and for are entry-controlled: the condition is tested before the body, so the body may run zero times.
  • do...while is exit-controlled: the condition is tested after the body, so the body always runs at least once.

When do...while is preferred: when the loop body must execute at least once regardless of the condition — e.g. displaying a menu and reading the user's choice, or input validation ("keep asking until a valid value is entered").

(b) Calculator using switch...case

#include <stdio.h>

int main(void)
{
    float a, b, result;
    char op;

    printf("Enter operand1 operator operand2: ");
    scanf("%f %c %f", &a, &op, &b);

    switch (op) {
        case '+': result = a + b; printf("%.2f\n", result); break;
        case '-': result = a - b; printf("%.2f\n", result); break;
        case '*': result = a * b; printf("%.2f\n", result); break;
        case '/':
            if (b == 0)
                printf("Error: division by zero!\n");
            else
                printf("%.2f\n", a / b);
            break;
        default:
            printf("Invalid operator!\n");
    }
    return 0;
}

The division case explicitly checks b == 0 before dividing, and default handles any operator other than + - * /.

control-flowloops
3long14 marks

(a) What is recursion? Explain the concept of a recursive function with the help of the factorial example, and discuss how it differs from an iterative solution in terms of memory and the function call stack. (6)

(b) Write a C program that uses a user-defined function to search for a given element in a one-dimensional integer array using the linear search technique. The function should return the index of the element if found, or -1 otherwise. (8)

(a) Recursion

Recursion is a technique in which a function calls itself (directly or indirectly) to solve a problem by reducing it into smaller sub-problems of the same kind. Every recursive function must have:

  1. a base case that stops the recursion, and
  2. a recursive case that moves toward the base case.

Factorial examplen!=n×(n1)!n! = n \times (n-1)! with 0!=10! = 1:

int factorial(int n) {
    if (n <= 1) return 1;      /* base case */
    return n * factorial(n - 1); /* recursive case */
}

For factorial(4): 4×3×2×1=244\times3\times2\times1 = 24.

Recursion vs iteration:

AspectRecursionIteration
MemoryEach call pushes a new stack frame (parameters, return address, locals); nn calls use O(n)O(n) stack spaceUses a fixed amount of memory (a few variables)
Call stackGrows with depth; risk of stack overflow for large nnNo extra stack growth
SpeedFunction-call overhead makes it generally slowerGenerally faster
CodeShorter, closer to the mathematical definitionMore verbose but efficient

Thus recursion is elegant but more memory-intensive because the function call stack stores one frame per pending call until the base case unwinds them.

(b) Linear search with a user-defined function

#include <stdio.h>

int linearSearch(int arr[], int n, int key)
{
    for (int i = 0; i < n; i++)
        if (arr[i] == key)
            return i;   /* found: return index */
    return -1;          /* not found */
}

int main(void)
{
    int n, key;
    int arr[100];

    printf("Enter number of elements: ");
    scanf("%d", &n);
    printf("Enter %d elements: ", n);
    for (int i = 0; i < n; i++)
        scanf("%d", &arr[i]);

    printf("Enter element to search: ");
    scanf("%d", &key);

    int pos = linearSearch(arr, n, key);
    if (pos != -1)
        printf("Element found at index %d\n", pos);
    else
        printf("Element not found\n");
    return 0;
}
functionsrecursionarrays
4long12 marks

(a) What is a pointer? Explain the meaning of the & (address-of) and * (dereference) operators with a suitable example showing how a pointer is declared, initialized and used to modify the value of a variable. (6)

(b) Explain the difference between malloc() and calloc(). Write a C program that dynamically allocates memory for n integers (where n is entered by the user), reads them, prints their sum, and finally frees the allocated memory. (6)

(a) Pointers, & and *

A pointer is a variable that stores the memory address of another variable.

  • & (address-of operator): returns the memory address of a variable.
  • * (dereference / indirection operator): in a declaration it marks a pointer; in an expression it accesses the value stored at the address held by the pointer.
#include <stdio.h>

int main(void)
{
    int x = 10;
    int *p;        /* p is a pointer to int       */
    p = &x;        /* p now holds the address of x */

    printf("x = %d\n", x);     /* 10 */
    printf("*p = %d\n", *p);   /* 10 -> value at address */

    *p = 25;       /* modify x THROUGH the pointer */
    printf("x = %d\n", x);     /* 25 */
    return 0;
}

Writing *p = 25; changes x itself, showing how a pointer is used to modify another variable's value indirectly.

(b) malloc() vs calloc()

malloc(size)calloc(n, size)
Takes one argument (total bytes)Takes two arguments (count, size of each)
Memory is uninitialised (garbage values)Memory is initialised to zero
Slightly fasterSlightly slower (does zeroing)

Both return a void* to the allocated block (or NULL on failure) and the memory must be released with free().

Dynamic allocation program:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int n, sum = 0;

    printf("Enter n: ");
    scanf("%d", &n);

    int *arr = (int *) malloc(n * sizeof(int));
    if (arr == NULL) {
        printf("Memory allocation failed\n");
        return 1;
    }

    printf("Enter %d integers: ", n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
        sum += arr[i];
    }

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

    free(arr);   /* release the memory */
    return 0;
}
pointersdynamic-memory
B

Section B: Short Answer Questions

Attempt all / any as specified.

7 questions
5short6 marks

Explain the difference between the logical operators (&&, ||, !) and the bitwise operators (&, |, ^) in C. Evaluate the expression a = 5 + 3 * 2 - 8 / 4 step by step using operator precedence and show the final value of a.

Logical vs bitwise operators

Logical operators (&&, ||, !) work on whole operands as truth values (zero = false, non-zero = true) and yield 1 or 0. They use short-circuit evaluation.

  • a && b -> true only if both are true
  • a || b -> true if at least one is true
  • !a -> logical negation

Bitwise operators (&, |, ^) operate on each individual bit of the operands.

  • a & b -> bitwise AND, a | b -> bitwise OR, a ^ b -> bitwise XOR
  • Example: 5 & 3 = 0101 & 0011 = 0001 = 1; 5 | 3 = 7; 5 ^ 3 = 6.

Evaluating a = 5 + 3 * 2 - 8 / 4

Precedence: * and / (higher, left-to-right) before + and -.

  1. 3 * 2 = 6
  2. 8 / 4 = 2
  3. Expression becomes 5 + 6 - 2
  4. 5 + 6 = 11
  5. 11 - 2 = 9

Final value: a=9a = 9.

operatorsexpressions
6short6 marks

Write a C program that reads a string from the user (without using the built-in strlen() function) and counts the number of vowels, consonants and spaces present in it.

Counting vowels, consonants and spaces

#include <stdio.h>

int main(void)
{
    char str[200];
    int vowels = 0, consonants = 0, spaces = 0;

    printf("Enter a string: ");
    fgets(str, sizeof(str), stdin);   /* reads line incl. spaces */

    for (int i = 0; str[i] != '\0'; i++) {  /* no strlen() used */
        char c = str[i];
        if (c >= 'A' && c <= 'Z') c = c + 32; /* to lowercase */

        if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
            vowels++;
        } else if (c >= 'a' && c <= 'z') {
            consonants++;
        } else if (str[i] == ' ') {
            spaces++;
        }
    }

    printf("Vowels = %d\n", vowels);
    printf("Consonants = %d\n", consonants);
    printf("Spaces = %d\n", spaces);
    return 0;
}

The loop runs until the null terminator '\0', so the string length is found manually without strlen(). Each character is converted to lowercase, then classified as a vowel, a consonant, or a space.

arraysstrings
7short6 marks

Differentiate between call by value and call by reference in C with a suitable example. Illustrate by writing a function swap() that successfully exchanges the values of two variables passed from main().

Call by value vs call by reference

Call by valueCall by reference
A copy of the argument is passedThe address of the argument is passed (via pointers)
Changes inside the function do not affect the caller's variablesChanges do affect the caller's variables
Original data is protectedOriginal data can be modified

In C, all arguments are passed by value; "call by reference" is simulated by passing pointers (addresses).

Working swap() using call by reference

A value-based swap fails because it only swaps copies. Passing addresses lets swap() modify the originals:

#include <stdio.h>

void swap(int *a, int *b)   /* receives addresses */
{
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main(void)
{
    int x = 10, y = 20;
    printf("Before: x = %d, y = %d\n", x, y);

    swap(&x, &y);   /* pass addresses */

    printf("After:  x = %d, y = %d\n", x, y); /* x=20, y=10 */
    return 0;
}

Output: x = 20, y = 10 — the exchange is reflected in main() because swap() operates on the actual memory locations.

functionsarrays
8short6 marks

(a) How does a structure differ from a union in terms of memory allocation? (2)

(b) Define a structure Student having members roll (integer), name (string) and marks (float). Write a C program to read details of 3 students into an array of structures and display the name of the student with the highest marks. (4)

(a) Structure vs union (memory)

In a structure, every member gets its own separate memory; the total size is (at least) the sum of all member sizes. In a union, all members share the same memory; its size equals the size of its largest member, and only one member holds a valid value at a time.

(b) Student structure program

#include <stdio.h>

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

int main(void)
{
    struct Student s[3];
    int i, maxIndex = 0;

    for (i = 0; i < 3; i++) {
        printf("Enter roll, name, marks of student %d: ", i + 1);
        scanf("%d %s %f", &s[i].roll, s[i].name, &s[i].marks);
    }

    for (i = 1; i < 3; i++)
        if (s[i].marks > s[maxIndex].marks)
            maxIndex = i;

    printf("Topper: %s (marks = %.2f)\n",
           s[maxIndex].name, s[maxIndex].marks);
    return 0;
}

The program reads 3 students into an array of structures, then scans for the maximum marks and prints the corresponding name.

structuresunions
9short6 marks

Explain the different modes (r, w, a) used to open a file in C. Write a C program that opens a text file named data.txt, writes the numbers from 1 to 10 into it, and then closes the file, checking for any error during file opening.

File opening modes

ModeMeaning
"r"Read — file must already exist; opens for reading from the start. Fails (returns NULL) if the file is absent.
"w"Write — creates a new file (or truncates an existing one to empty), then writes from the start.
"a"Append — opens/creates a file and writes at the end, preserving existing contents.

Program: write 1..10 to data.txt

#include <stdio.h>

int main(void)
{
    FILE *fp;

    fp = fopen("data.txt", "w");
    if (fp == NULL) {                 /* error check */
        printf("Error opening file!\n");
        return 1;
    }

    for (int i = 1; i <= 10; i++)
        fprintf(fp, "%d\n", i);

    fclose(fp);
    printf("Numbers 1 to 10 written successfully.\n");
    return 0;
}

fopen with mode "w" creates/overwrites data.txt; the returned pointer is checked against NULL to detect failure; fprintf writes each number; fclose flushes and releases the file.

file-handling
10short6 marks

Write a C program to check whether a given positive integer entered by the user is a prime number or not, and display an appropriate message.

Prime-number checking program

A prime number is a positive integer greater than 1 having exactly two divisors: 1 and itself. We test divisibility by every integer from 2 up to n\sqrt{n} (or n/2n/2).

#include <stdio.h>

int main(void)
{
    int n, i, isPrime = 1;

    printf("Enter a positive integer: ");
    scanf("%d", &n);

    if (n <= 1) {
        isPrime = 0;          /* 0 and 1 are not prime */
    } else {
        for (i = 2; i * i <= n; i++) {   /* check up to sqrt(n) */
            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;
}

The break exits as soon as a factor is found. Using i * i <= n checks only up to n\sqrt{n}, which is efficient.

control-flowloops
11short6 marks

Write short notes on any TWO of the following: (a) Storage classes in C (auto, static, register, extern); (b) #define macros versus constant variables; (c) Type conversion and type casting in C.

Answering any two of the following.

(a) Storage classes in C

Storage classes define a variable's scope, lifetime, default value and storage location.

  • auto: default for local variables; scope = the block, lifetime = until the block ends, stored in stack, garbage initial value.
  • static: retains its value between function calls; lifetime = whole program; default value 0; scope still local (or file scope for globals).
  • register: suggests the compiler keep the variable in a CPU register for fast access; & cannot be applied; otherwise like auto.
  • extern: declares a global variable defined elsewhere (another file), giving it program-wide linkage without re-allocating it.

(b) #define macros vs constant variables

  • #define PI 3.14 is a preprocessor macro: textual substitution done before compilation. It has no data type, occupies no storage, and is not type-checked.
  • const float PI = 3.14; is a real, typed variable stored in memory that is read-only. It is type-checked, can be inspected by a debugger, and respects scope rules.

In general const is safer (type-checked, scoped); #define is also used for conditional compilation and macros with parameters.

(c) Type conversion vs type casting

  • Type conversion (implicit): the compiler automatically converts one type to another, e.g. in float f = 5; the int 5 is promoted to float. In mixed expressions a lower type is promoted to a higher type (int -> float -> double).
  • Type casting (explicit): the programmer forces a conversion using the cast operator, e.g. float avg = (float) sum / n; to get a floating-point result from two integers. Syntax: (type) expression.
data-typesprogram-structure

Frequently asked questions

Where can I find the BE Computer Engineering (Pokhara University) Programming in C (PU, CMP 124) question paper 2078?
The full BE Computer Engineering (Pokhara University) Programming in C (PU, CMP 124) 2078 (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) 2078 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) 2078 paper?
The BE Computer Engineering (Pokhara University) Programming in C (PU, CMP 124) 2078 paper carries 100 full marks and is meant to be completed in 180 minutes, across 11 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.