Reasoning exercises
Try the C Programming Quiz for a variety of multiple-choice questions on C (but also C++) concepts!
This page presents a series of short, focused problems designed to help you practice and reinforce your understanding of key C concepts. Try to solve each exercise before revealing the answer and explanation.
Tip: you can click on the exercise number to mark it as completed. This helps you keep track of which exercises you've already solved correctly.
Function callingβ
What does the following program print?
#include<iostream>
using namespace std;
int f2(int n) {
cout << n << " ";
return --n;
}
int f3(int n) {
cout << n << " ";
if (n % 2) {
return n - 1;
}
return f2(n - 1);
}
int f(int n) {
if (n == 0) {
return 0;
} else if (n < 4) {
cout << n << " ";
f(f3(n--));
} else if (n < 2) {
return f2(n - 1);
} else {
return f(n - 1);
}
return n;
}
int main() {
cout << f(5);
return 0;
}
Answer
f(5):n=5(β₯4) β returnsf(4)f(4):n=4(β₯4) β returnsf(3)f(3):n=3(<4)- prints
3 - calls
f3(3--):f3(3)prints3and sincen % 2is 1 (β 0, sotrue) returns2
- calls
f(2)
- prints
f(2):n=2(<4)- prints
2 - calls
f3(2--):f3(2)prints2, even β callsf2(1)f2(1)prints1, returns0
f3returns0
- calls
f(0)β returns0 f(2)returns2
- prints
f(3)returns3βf(4)returns3βf(5)returns3main'scout << f(5)prints3
Output:
3 3 2 2 1 3What does the following program print? (functions pointers)
#include <iostream>
using namespace std;
int f1(int p) { return (p * p); }
int f2(int p) { return (p * 2); }
void f(int (*fun1)(int), int (*fun2)(int), int *v, int n) {
for (int i = 0; i < n; i++)
if (i < 2)
v[i] = fun1(v[i] + 1);
else
v[i] = fun2(v[i] + v[i - 2]);
}
int main() {
int a[] = {0, 1, 1, 0};
f(f1, f2, a, 4);
for (int i = 0; i < 4; i++)
cout << a[i] << " ";
cout << endl;
return 0;
}
Answer
How the call works:
f(f1, f2, a, 4);passes two function pointers (f1andf2), the arraya, and its length4intof.- Inside
f, the parameterfun1refers tof1andfun2refers tof2. fthen applies these callbacks to array elements based on the index.
Element-by-element computation:
- i = 0 (<2): v[0] = fun1(0+1) = f1(1) = 1Γ1 = 1
- i = 1 (<2): v[1] = fun1(1+1) = f1(2) = 2Γ2 = 4
- i = 2 (β₯2): v[2] = fun2(1 + v[0]) = f2(1+1) = f2(2) = 2Γ2 = 4
- i = 3 (β₯2): v[3] = fun2(0 + v[1]) = f2(0+4) = f2(4) = 2Γ4 = 8
Output sequence:
1 4 4 8Complete the functions in XXX and YYY so the program prints 4 2 3 15 9
#include <iostream>
using namespace std;
int f1(int n) {
XXX
}
int f2(int n) {
YYY
}
int main() {
int a[] = {1, 4, 2, 3, 9};
for (int i = 0; i < 4; i++) {
if (i % 2)
a[i] = f1(i);
else
a[i] = f2(a[i]);
a[i] = a[i] | a[i + 1];
}
for (int i = 0; i < 5; i++)
cout << a[i] << " ";
}
Solution
The two missing lines are (multiple solutions):
- XXX:
return n * 2;and YYY:return n / 2; - XXX:
return n * 2;and YYY:return n - 1; - XXX:
return n << 1;and YYY:return 0;
With these definitions the program outputs:
4 2 3 15 9What does the following program print? (functions pointers)
#include <iostream>
using namespace std;
int f1(int n) {
return n - 1;
}
int f2(int n) {
return n - 2;
}
int f(int n, int (*fun)(int)) {
if (n < 0)
return n;
if (n % 2 == 0)
return f(fun(n), fun);
else
return f(fun(n), f2);
}
int main() {
cout << f(6, f2);
return 0;
}
Answer
What is fun?
The parameter fun in f(int n, int (*fun)(int)) is a pointer to a function that takes an int and returns an int. By passing in f1 or f2, you tell f which helper function to apply at each recursive call.
Step-by-step evaluation:
- f(6, f2): 6 β₯ 0 and even β f(f2(6)=4, f2)
- f(4, f2): even
β f(f2(4)=2, f2) - f(2, f2): even
β f(f2(2)=0, f2) - f(0, f2): even
β f(f2(0)=β2, f2) - f(β2, f2): n < 0 β returns β2
Final output:
-2Pointersβ
What does the following program print?
#include <stdio.h>
int main() {
int v[4] = {1, 2, 3, 4};
int *p = v + 1;
int i;
*(p + 2) = 6;
*p = (*p) + 2;
for (i = 0; i < 4; i++) printf("%d ", v[i]);
}
Answer
#include <iostream>
using namespace std;
int main() {
int v[4] = {1, 2, 3, 4};
int *p = v + 1; // p points to v[1] (the second element of v)
int i;
*(p + 2) = 6; // modifies v[3] to 6 (p points to v[1], so p+2 is v[3])
*p = (*p) + 2; // modifies v[1] to v[1] + 2 (so v[1] becomes 4)
for (i = 0; i < 4; i++) cout << v[i] << " ";
// Final array: {1, 4, 3, 6}
}
Notes:
The * operator has two distinct meanings in pointer-related code:
When declaring a pointer:
int *p;,*indicates thatpis a pointer to an integer. It tells the compiler thatpwill store the address of an integer variable.When dereferencing a pointer:
*p = 10;,*is the dereference operator. It accesses the value at the memory address the pointerpholds, allowing you to read and/or modify that value being pointed to.*(p + n)accesses the elementnpositions after the oneppoints to.
Extra note:
In C and C++, dereferencing a pointer with *(p + 2) yields an lvalue (referring to a memory location); when used in a context that requires a value (such as printing), this lvalue undergoes an lvalue-to-rvalue conversion to produce the stored value.
Output:
1 4 3 6What does the following program print?
#include <stdio.h>
void f(int *p, int **rp) {
int *tmp = p;
p = *rp;
*tmp = 10;
*p = 20;
*rp = p;
}
int main() {
int a = 10, b = 10;
int *ptr = &a;
int *prp = &b;
f(ptr, &prp);
printf("%d %d %d %d\n", a, *ptr, b, *prp);
}
Answer
#include <stdio.h>
void f(int *p, int **rp) {
int *tmp = p; // tmp points to a
p = *rp; // p now points to b
*tmp = 10; // sets a = 10
*p = 20; // sets b = 20
*rp = p; // prp still points to b
}
int main() {
int a = 10, b = 10;
int *ptr = &a; // ptr points to a
int *prp = &b; // prp points to b
f(ptr, &prp);
printf("%d %d %d %d\n", a, *ptr, b, *prp);
// Output: 10 10 20 20
}
Explanation:
When we call f(ptr, &prp), we're passing a pointer to a and a pointer to the pointer prp. Inside the function, tmp saves the pointer to a, then p is redirected to point to b. We set a to 10 (which doesn't change its value) and b to 20. The pointer prp continues to point to b. After the function call, a is 10, ptr still points to a so *ptr is 10, b is 20, and prp points to b so *prp is 20.
Output:
10 10 20 20What does the following program print?
#include <stdio.h>
#include <stdlib.h>
void f(int i, int *p, int *ri, int **rp) {
int *q = malloc(sizeof(int)); // or "int *q = new int" in C++
*q = 10;
i = 12;
*rp = q;
*p = (*q)--;
*ri = 19;
(*q)++;
}
int main() {
int a = 5, b = 3;
int *ptr;
ptr = &b;
int *prp;
prp = &a;
f(a, ptr, &b, &prp);
printf("%d %d %d %d\n", a, *ptr, b, *prp);
// Note: memory allocated for q is not freed and no return for simplicity.
}
Answer
#include <stdio.h>
#include <stdlib.h>
void f(int i, int *p, int *ri, int **rp) {
int *q = malloc(sizeof(int)); // Allocate memory for q
*q = 10; // Set q to point to value 10
i = 12; // Local variable change, doesn't affect main
*rp = q; // prp now points to q instead of a
*p = (*q)--; // b gets 10, q now points to 9
*ri = 19; // b is set to 19
(*q)++; // q now points to 10 again
}
int main() {
int a = 5, b = 3; // Initialize variables
int *ptr;
ptr = &b; // ptr points to b
int *prp;
prp = &a; // prp points to a
f(a, ptr, &b, &prp);
printf("%d %d %d %d\n", a, *ptr, b, *prp);
// Output: 5 19 19 10
}
Explanation: The function performs several operations:
aremains unchanged (5) in main becauseiis passed by valuebis set to 10 through*p = (*q)--but then changed to 19 through*ri = 19ptrpoints tob, so*ptris 19prpinitially points toabut is changed to point toqwhich has value 10
Output:
5 19 19 10What does the following program print?
#include <iostream>
using namespace std;
int main() {
int a[6] = {0, 3, 4, 6, 6, 5};
int *p = &a[2];
a[*p] = a[*(p - 1)];
a[3] = *a;
p = p - 2;
*p = 18;
*(p + 1) = *(p + 3);
for (int i = 0; i < 6; i++) {
cout << a[i] << " ";
}
}
Answer and explanation
At the start the array a is {0, 3, 4, 6, 6, 5} and the pointer p points to a[2] (value 4).
- The line
a[*p] = a[*(p-1)];means βtake*p(which is4) as the LHS index, and*(p-1)(which readsa[1] = 3) as the RHS index fora. So we assigna[4] = a[3], writing6intoa[4](it stays6). - Next,
a[3] = *a;setsa[3]to the first elementa[0], which is0. - After
p = p - 2;,ppoints back toa[0]. Then*p = 18;writes18intoa[0]. - Finally,
*(p+1) = *(p+3);takesa[3](now0) and stores it intoa[1], makinga[1] = 0.
At this point the array is:.
18 0 4 0 6 5