C Programming Mixed-Concept Questions Explained: Arrays, Pointers, Functions and Output Tracing
Learn a four-pass method for tracing C programs that combine arrays, pointer aliases, function calls, static storage and side effects, with a complete worked output trace.
KnowledgeGate Team
Exam prep & CS education

A single C question can depend on pointer aliases, function parameters, static storage and side effects at the same time. Mixed-concept sets deliberately cross chapters, so trace each rule separately rather than reaching for one memorised pattern. Tracing one program carefully through two calls settles most such questions; the rest turn on spotting that an expression has no dependable output at all.
1. C mixed-concept questions: track objects, values and aliases separately
For each line, keep a four-track state sheet:
Each identifier's type and current value.
Each object's storage duration and lifetime.
Every pointer or array alias.
Side effects completed at that step.
Names, stored objects and addresses are related, not interchangeable.
With int a[3] = {2, 4, 6}; int *p = a + 1;, p points to a[1]. Thus p - a == 1, p[0] == a[1] == 4, and p[1] == a[2] == 6. After p[0] = 5, the array is {2, 5, 6}. Both dereferences are in bounds, so this is defined.
Use the GATE CS Exam category for broader GATE CS preparation beyond this single topic.
2. C expression tracing: conversion, precedence and sequencing are different rules
Tokens determine what the parser sees, precedence and associativity determine grouping, and sequencing determines when side effects complete.
Conversion happens after the earlier calculation:
int x = 7 / 2;stores3.double y = 7 / 2;stores3.0, because integer division happens before conversion todouble.double z = 7 / 2.0;stores3.5.17 % 5is2.
int i = 3; int x = i++; int y = i + 2; gives x = 3, then i = 4, then y = 6. By contrast, i = i++ + 1; modifies i more than once without the required sequencing. That is undefined behaviour. Never present one compiler's observed result as the language answer.
3. C arrays, pointers and functions: follow the address that is actually passed
In most expressions, a converts to a pointer to a[0], so a + 1 points to the second element. In its scope, sizeof a measures the whole array. A parameter int p[] becomes a pointer with no count. &a points to the whole array and has a different type.
A function receiving int *p, int n can modify caller elements. Passing a + 1 makes p[0] alias a[1]. Only a[1] and a[2] are available, so pass n = 2.
Before tracing, write the valid index range for the pointer passed.
![Array a[3] = {2, 4, 6} with pointer p = a + 1 aliasing a[1] and a[2], and the after-state {2, 5, 6} produced by p[0] = 5.](https://cdn.knowledgegate.ai/blog-assets/blog_asset_1784245118776_2hquea.jpg)
4. Worked C program: combine array mutation, pointer offsets and static state
Trace the standards-defined program without changing calls or arguments:
#include <stdio.h>
int transform(int *p, int n)
{
static int calls = 1;
int total = 0;
for (int i = 0; i < n; ++i) {
p[i] += calls + i;
total += p[i];
}
++calls;
return total;
}
int main(void)
{
int a[3] = {2, 4, 6};
int x = transform(a, 3);
int y = transform(a + 1, 2);
printf("%d %d %d %d %d\n", x, y, a[0], a[1], a[2]);
return 0;
}Initially, a = {2, 4, 6} and static calls = 1 is initialised once. Each call gets fresh total and i. The pointer aliases caller elements, while only calls persists.
The first call accesses p[0] through p[2]. The second begins at a[1], with p[0] and p[1] aliasing a[1] and a[2]. Accesses are in bounds, and argument order is irrelevant.
5. Worked C output trace: solve both calls and lock the final line
For transform(a, 3), calls is 1:
i | Old | Added | New | Running |
|---|---|---|---|---|
0 | 2 | 1 | 3 | 3 |
1 | 4 | 2 | 6 | 9 |
2 | 6 | 3 | 9 | 18 |
After the call, a = {3, 6, 9}, calls = 2, and x = 18.
For transform(a + 1, 2), total starts again at 0, but calls remains 2:
i | Caller element | Old | Added | New | Running |
|---|---|---|---|---|---|
0 |
| 6 | 2 | 8 | 8 |
1 |
| 9 | 3 | 12 | 20 |
The function leaves calls = 3, y = 20, and a = {3, 8, 12}. It prints:
18 20 3 8 12Do not reset static calls to 1 for the second call. Static storage preserves it.

6. C mixed-concept traps: know when there is no valid numeric answer
Check whether C defines an operation before calculating it.
Case | Classification | Reason or correction |
|---|---|---|
| Valid pointer, invalid dereference | One-past formation is valid, but |
Read an automatic | No dependable value |
|
Return | Invalid after return | The automatic object's lifetime ended. An address of a |
| Undefined behaviour | Its modifications lack sequencing. This is not a precedence error. |
In main, sizeof b / sizeof b[0] gives 3. Inside void f(int b[]), b is a pointer, so it cannot reveal the caller's length. Pass the count, as transform does.
7. C exam-style multi-topic questions: a four-pass solving method
IIT Guwahati's official GATE 2026 question-paper pattern names MCQ, MSQ and NAT. For their learner-facing distinction, read MCQ, MSQ or NAT? GATE Question Types Explained.
C practice may test defined traces, array-pointer aliases, automatic versus static state, integer conversion, bounds or lifetime errors, or undefined behaviour. The KnowledgeGate practice bank has about 20 questions that mix C topics this way.
Use four passes under time pressure:
Write types and starting values.
Draw pointer arrows and valid index bounds.
Execute one full expression at a time and record completed side effects.
Stop and classify the program if any lifetime, bounds or sequencing rule is violated.
For a subject-wide sequence, use GATE Guidance by Sanchit Sir.
Three rapid checks: with int v[] = {4, 9, 16}; int *q = v + 1;, q[-1] + q[1] is 4 + 16 = 20, since both name elements of v. With int n = 5; double d = n / 2;, integer division gives 2, then d stores 2.0. With static int s = 2; return s += 3;, consecutive calls return 5 and 8 because s persists.
8. C mixed-concept questions: the short version and next step
Keep this revision checklist:
Separate names from objects.
Mark static versus automatic lifetime.
Draw every alias.
Apply conversions before storing results.
Test bounds and sequencing before calculating output.
The first call changes {2, 4, 6} to {3, 6, 9}. The suffix call leaves {3, 8, 12} and prints 18 20 3 8 12.
Practise real past-paper traces before collecting more exercises. Why PYQs Beat Buying Another Question Bank explains why. For C concepts, MCQs and coding practice, continue with the C Language Course.
Transfer exercise: replace the second call with transform(a, 2) and predict. With calls = 2, a[0] changes from 3 to 5 and a[1] from 6 to 9. Thus y = 5 + 9 = 14, the array is {5, 9, 9}, and the output is 18 14 5 9 9.
Keep learning

Functions in C: Syntax, Parameters and Worked Examples
Learn how C declarations, calls, and definitions fit together. Compile two complete programs, follow their values, and trace composition and recursion.

Smart Pointers in C++: unique_ptr, shared_ptr and weak_ptr with Worked Examples
Learn who owns a C++ object, when it is destroyed, and how to choose among unique_ptr, shared_ptr, weak_ptr and a borrowed raw pointer.

Pointers in C: Addresses, Arrays and Functions with Worked Examples
Build a practical pointer model with runnable C programs for dereferencing, arrays, swapping, dynamic memory and common tracing questions.

Pointers and Arrays in C: Decay, Indexing and Worked Examples
Separate arrays from pointers with runnable traces covering indexing, one-past boundaries, function parameters, two-dimensional arrays and declaration traps.