Call by Value, Address and Reference in C MCQs: 12 Solved Questions with Explanations

Solve 12 C questions on copied parameters, pointer writes, pointer-to-pointer swaps and array decay. Each answer includes a short trace and the exact exam trap.

KnowledgeGate Team

Exam prep & CS education

Updated 8 Aug 20268 min read

A function changes its parameter, yet the variable in main refuses to move. That is the call by value, address and reference trap. C has only call by value: apparent call by reference passes an address by value.

Ten of these twelve questions are past papers: eight from GATE between 2004 and 2025, and two from UGC NET 2014. Four recurring patterns account for all ten. Attempt each question before reading its trace, and when a trace stops making sense, rebuild it statement by statement alongside the C Language learn module.

Call by value: the function gets a copy

Every C argument is copied. Assigning to a parameter changes only that copy. Caller data changes through a return value or a passed address.

Q1. Predict the output

#include <stdio.h>
void fun(int x)
{
    x = 30;
}
int main()
{
    int y = 20;
    fun(y);
    printf("%d", y);
    return 0;
}

(a) 30

(b) 20

(c) Compiler Error

(d) Run Time Error

Answer: (b) 20. fun receives a copy of y. x = 30 changes the copy, which disappears on return. The original y remains 20.

Q2. GATE 2004

Consider the following C function:

void swap(int a, int b)
{
    int temp;
    temp = a;
    a = b;
    b = temp;
}

In order to exchange the values of two variables x and y:

(a) Call swap(x, y)

(b) Call swap(&x, &y)

(c) swap(x, y) cannot be used as it does not return any value

(d) swap(x, y) cannot be used as the parameters are passed by value

Answer: (d). swap(x, y) shuffles copies. Option (b) sends addresses to int parameters, which would need to be int *. A void function can still write through pointers, so (c) is not the reason. See the solved GATE 2004 question.

Q3. GATE 2017

Consider the following function implemented in C:

void printxy(int x, int y) {
    int *ptr;
    x = 0;
    ptr = &x;
    y = *ptr;
    *ptr = 1;
    printf("%d, %d", x, y);
}

The output of invoking printxy(1, 1) is:

(a) 0, 0

(b) 0, 1

(c) 1, 0

(d) 1, 1

Answer: (c) 1, 0. Copies arrive as x = 1, y = 1. Then x = 0; ptr = &x; y = *ptr makes y = 0; and *ptr = 1 makes local x = 1. See the solved GATE 2017 question.

Call by address: pass the pointer, change the caller

Passing &v gives its address to the function, so *p can reach the caller. These are NAT questions with integer answers.

Q4. GATE 2025, NAT

#include <stdio.h>
void foo(int *p, int x) {
    *p = x;
}
int main() {
    int *z;
    int a = 20, b = 25;
    z = &a;
    foo(z, b);
    printf("%d", a);
    return 0;
}

The output of the given C program is __________. (Answer in integer)

Answer: 25. z holds &a; x receives 25; and *p = x stores 25 in a. See the solved GATE 2025 question.

Q5. GATE 2016, NAT

void f(int *p, int m) {
    m = m + 5;
    *p = *p + m;
    return;
}
void main() {
    int i = 5, j = 10;
    f(&i, j);
    printf("%d", i + j);
}

The value printed by the following program is __________.

Answer: 30. i goes by address and j by value. Inside f, m = 10 + 5 = 15, while j stays 10. Then *p = 5 + 15 = 20, so i + j = 20 + 10 = 30. See the solved GATE 2016 question.

Q6. GATE 2015, NAT

void f1(int a, int b) {
    int c;
    c = a; a = b; b = c;
}
void f2(int *a, int *b) {
    int c;
    c = *a; *a = *b; *b = c;
}
int main() {
    int a = 4, b = 5, c = 6;
    f1(a, b);
    f2(&b, &c);
    printf("%d", c - a - b);
}

The output of the following C program is __________.

Answer: -5. f1 swaps copies, leaving a = 4, b = 5. f2 makes b = 6, c = 5. Thus c - a - b = 5 - 4 - 6 = -5. See the solved GATE 2015 question.

The classic trap: reassigning the pointer parameter

The pointer is also passed by value. *p = ... changes caller data; p = ... only rebinds the local copy.

Q7. What does the program print?

void fun(int *p)
{
    int q = 10;
    p = &q;
}
int main()
{
    int r = 20;
    int *p = &r;
    fun(p);
    printf("%d", *p);
    return 0;
}

(a) 10

(b) 20

(c) Compiler error

(d) Runtime Error

Answer: (b) 20. fun rebinds local p to &q. The pointer in main still points to r, so *p is 20. Q4 wrote through *p; Q7 assigns to p.

Q8. GATE 2010

What does the following program print?

#include <stdio.h>
void f(int *p, int *q)
{
    p = q;
    *p = 2;
}
int i = 0, j = 1;
int main()
{
    f(&i, &j);
    printf("%d %d \n", i, j);
    getchar();
    return 0;
}

(a) 2 2

(b) 2 1

(c) 0 1

(d) 0 2

Answer: (d) 0 2. Initially p = &i and q = &j. Local p = q points p at j, then *p = 2 changes j. Variable i remains 0. See the solved GATE 2010 question.

Two-panel memory diagram for Q8: at entry p points to i and q to j, and after p = q and *p = 2 both point at j, which becomes 2 while i stays 0.

Simulating call by reference needs one more star

Changing a caller's pointer requires its address, such as char **. Reassigning a one-star parameter repeats Q7's trap.

Q9. GATE 2018

Consider the following C program:

#include <stdio.h>
void fun1(char *s1, char *s2) {
    char *tmp;
    tmp = s1;
    s1 = s2;
    s2 = tmp;
}
void fun2(char **s1, char **s2) {
    char *tmp;
    tmp = *s1;
    *s1 = *s2;
    *s2 = tmp;
}
int main() {
    char *str1 = "Hi", *str2 = "Bye";
    fun1(str1, str2); printf("%s %s ", str1, str2);
    fun2(&str1, &str2); printf("%s %s", str1, str2);
    return 0;
}

The output of the program above is:

(a) Hi Bye Bye Hi

(b) Hi Bye Hi Bye

(c) Bye Hi Hi Bye

(d) Bye Hi Bye Hi

Answer: (a) Hi Bye Bye Hi. fun1 swaps local copies, so the first print is Hi Bye. fun2 swaps through &str1 and &str2, making the second Bye Hi. A char * needs a char **. See the solved GATE 2018 question.

Q10. GATE 2008

What is printed by the following C program?

#include <stdio.h>
int f(int x, int *py, int **ppz)
{
    int y, z;
    **ppz += 1;
    z = **ppz;
    *py += 2;
    y = *py;
    x += 3;
    return x + y + z;
}
void main()
{
    int c, *b, **a;
    c = 4;
    b = &c;
    a = &b;
    printf("%d", f(c, b, a));
    getchar();
}

(a) 18

(b) 19

(c) 21

(d) 22

Answer: (b) 19. **ppz += 1 makes shared c = 5, so z = 5. Next, *py += 2 makes c = 7, so y = 7. Copied x goes from 4 to 7. Total: 7 + 7 + 5 = 19. See the solved GATE 2008 question.

Arrays and the theory the definitions carry

An array argument decays to a pointer to its first element. C copies the pointer, so the function can still change caller elements.

Q11. UGC NET 2014

When an array is passed as parameter to a function, which of the following statements is correct?

(a) The function can change values in the original array.

(b) In C, parameters are passed by value, the function cannot change the original value in the array.

(c) It results in compilation error when the function tries to access the elements in the array.

(d) Results in a run time error when the function tries to access the elements in the array.

Answer: (a). C copies the pointer to element zero. Since a[i] is *(ptr + i), writes reach the caller's memory. Option (b) applies the value rule to the elements, not the pointer. See the solved UGC NET 2014 array question.

Q12. UGC NET 2014

Consider the following statements S1, S2 and S3:

S1: In call-by-value, anything that is passed into a function call is unchanged in the caller's scope when the function returns.

S2: In call-by-reference, a function receives implicit reference to a variable used as argument.

S3: In call-by-reference, caller is unable to see the modified variable used as argument.

(a) S3 and S2 are true.

(b) S3 and S1 are true.

(c) S2 and S1 are true.

(d) S1, S2, S3 are true.

Answer: (c). S1 defines call by value; S2 defines true call by reference. S3 reverses the point of reference: the caller can see the change. Thus S1 and S2 are true. See the solved UGC NET 2014 definitions question.

How GATE and UGC NET test parameter passing in C

Exams use four patterns: mixed p and *p output traces (Q3, Q5, Q8, Q10); swaps from broken value code to char ** (Q2, Q6, Q9); array and definition theory (Q11, Q12); and GATE NAT traces (Q4 to Q6), where options cannot catch an error.

Draw memory boxes. The star count identifies the target: a value changes its copy, *p reaches data, and **p reaches through another pointer. A PYQ-first practice strategy exposes these repeated traps.

The short version and your next step

  • C copies every argument, including pointer values.

  • *p = value writes to pointed-to data, while p = address only rebinds the local pointer copy.

  • Changing a caller's pointer requires one more star.

  • Array names decay to pointers, so a function can modify the original elements.

  • Trace statements from top to bottom using memory boxes.

Every GATE question above is worked line by line inside GATE Guidance by Sanchit Sir, which also carries more than thirty further solved questions on passing values, addresses and pointers in C. The C Programming Course builds the same pointer material from declaration upward if you want the C-first route. You can also browse GATE CS preparation options.