C
C
Thanks for your interest in C programming. In this page, you will find a list of
interesting C programming questions/puzzles, These programs listed are the ones
which I have received as e-mail forwards from my friends, a few I read in some
books, a few from the internet, and a few from my coding experiences in C.
Most of the programs are meant to be compiled, run and to be explained for their
behaviour. The puzzles/questions can be broadly put into the following categories:
• General typo errors, which C programmers do often and are very difficult to
trace.
• Small programs which are extremely hard to understand at the first
examination. These questions make a good excercise of reading and
understanding effecient code written by others.
I have used Gnu/Linux/gcc for all of them. The order in which the programs appear
doesn't have any relation with the level of difficulty. Please feel free to contact me if
you need any help in solving the problems. My contact info. is available here And you
might be interested in a few references for C programming, which I personally found
very interesting.
Regards,
Gowri Kumar
C puzzles
The expected output of the following C program is to print the elements in the array.
But when actually run, it doesn't do so.
#include<stdio.h>
int main()
{
int d;
return 0;
}
Find out what's going wrong.
I thought the following program was a perfect C program. But on compiling, I found a
silly mistake. Can you find it out (without compiling the program :-) ?
#include<stdio.h>
void OS_Solaris_print()
{
printf("Solaris - Sun Microsystems\n");
}
void OS_Windows_print()
{
printf("Windows - Microsoft\n");
}
void OS_HP-UX_print()
{
printf("HP-UX - Hewlett Packard\n");
}
int main()
{
int num;
printf("Enter the number (1-3):\n");
scanf("%d",&num);
switch(num)
{
case 1:
OS_Solaris_print();
break;
case 2:
OS_Windows_print();
break;
case 3:
OS_HP-UX_print();
break;
default:
printf("Hmm! only 1-3 :-)\n");
break;
}
return 0;
}
What's the expected output for the following program and why?
enum {false,true};
int main()
{
int i=1;
do
{
printf("%d\n",i);
i++;
if(i < 15)
continue;
}while(false);
return 0;
}
The following program doesn't "seem" to print "hello-out". (Try executing it)
#include <stdio.h>
#include <unistd.h>
int main()
{
while(1)
{
fprintf(stdout,"hello-out");
fprintf(stderr,"hello-err");
sleep(1);
}
return 0;
}
What could be the reason?
#include <stdio.h>
#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)
int main()
{
printf("%s\n",h(f(1,2)));
printf("%s\n",g(f(1,2)));
return 0;
}
Just by looking at the program one "might" expect the output to be, the same for both
the printf statements. But on running the program you get it as:
bash$ ./a.out
12
f(1,2)
bash$
Why is it so?
#include<stdio.h>
int main()
{
int a=10;
switch(a)
{
case '1':
printf("ONE\n");
break;
case '2':
printf("TWO\n");
break;
defa1ut:
printf("NONE\n");
}
return 0;
}
If you expect the output of the above program to be NONE, I would request you to
check it out!!
The following C program seg faults of IA-64, but works fine on IA-32.
int main()
{
int* p;
p = (int*)malloc(sizeof(int));
*p = 10;
return 0;
}
Why does it happen so?
Here is a small piece of program(again just 14 lines of program) which counts the
number of bits set in a number.
Input Output
0 0(0000000)
5 2(0000101)
7 3(0000111)
int CountBits (unsigned int x )
{
static unsigned int mask[] = { 0x55555555,
0x33333333,
0x0F0F0F0F,
0x00FF00FF,
0x0000FFFF
} ;
int i ;
int shift ; /* Number of positions to shift to right*/
for ( i =0, shift =1; i < 5; i ++, shift *= 2)
x = (x & mask[i ])+ ( ( x >> shift) & mask[i]);
return x;
}
Find out the logic used in the above program.
What do you think would be the output of the following program and why? (If you are
about to say "f is 1.0", I would say check it out again)
#include <stdio.h>
int main()
{
float f=0.0f;
int i;
for(i=0;i<10;i++)
f = f + 0.1f;
if(f == 1.0f)
printf("f is 1.0 \n");
else
printf("f is NOT 1.0\n");
return 0;
}
I thought the following C program is perfectly valid (after reading about the comma
operator in C). But there is a mistake in the following program, can you identify it?
#include <stdio.h>
int main()
{
int a = 1,2;
printf("a : %d\n",a);
return 0;
}
What would be the output of the following C program? (Is it a valid C program?)
#include <stdio.h>
int main()
{
int i=43;
printf("%d\n",printf("%d",printf("%d",i)));
return 0;
}
void duff(register char *to, register char *from, register int
count)
{
register int n=(count+7)/8;
switch(count%8){
case 0: do{ *to++ = *from++;
case 7: *to++ = *from++;
case 6: *to++ = *from++;
case 5: *to++ = *from++;
case 4: *to++ = *from++;
case 3: *to++ = *from++;
case 2: *to++ = *from++;
case 1: *to++ = *from++;
}while( --n >0);
}
}
Is the above valid C code? If so, what is it trying to acheive and why would anyone do
something like the above?
Here is yet another implementation of CountBits. Verify whether it is correct (how do
you that???). If so, find out the logic used.
int CountBits(unsigned int x)
{
int count=0;
while(x)
{
count++;
x = x&(x-1);
}
return count;
}
Are the following two function prototypes same?
int foobar(void);
int foobar();
The following programs should be of some help in finding the answer: (Compile and
run both the programs and see what happens)
Program 1:
#include <stdio.h>
void foobar1(void)
{
printf("In foobar1\n");
}
void foobar2()
{
printf("In foobar2\n");
}
int main()
{
char ch = 'a';
foobar1();
foobar2(33, ch);
return 0;
}
Program 2:
#include <stdio.h>
void foobar1(void)
{
printf("In foobar1\n");
}
void foobar2()
{
printf("In foobar2\n");
}
int main()
{
char ch = 'a';
foobar1(33, ch);
foobar2();
return 0;
}
What's the output of the following program and why?
#include <stdio.h>
int main()
{
float a = 12.5;
printf("%d\n", a);
printf("%d\n", *(int *)&a);
return 0;
}
The following is a small C program split across files. What do you expect the output
to be, when both of them compiled together and run?
File1.c
int arr[80];
File2.c
extern int *arr;
int main()
{
arr[1] = 100;
return 0;
}
Explain the output of the following C program (No, the output is not 20).
#include<stdio.h>
int main()
{
int a=1;
switch(a)
{ int b=20;
case 1: printf("b is %d\n",b);
break;
default:printf("b is %d\n",b);
break;
}
return 0;
}
What is the output of the following program? (Again, it is not 40, (if the size of
integer is 4)).
#define SIZE 10
void size(int arr[SIZE])
{
printf("size of array is:%d\n",sizeof(arr));
}
int main()
{
int arr[SIZE];
size(arr);
return 0;
}
The following is a simple c program, in which there is a function called Error to
display errors. Can you see a potential problem with the way Error is defined?
#include <stdlib.h>
#include <stdio.h>
void Error(char* s)
{
printf(s);
return;
}
int main()
{
int *p;
p = malloc(sizeof(int));
if(p == NULL)
{
Error("Could not allocate the memory\n");
Error("Quitting....\n");
exit(1);
}
else
{
/*some stuff to use p*/
}
return 0;
}
What is the differnce between the following function calls to scanf?(Please notice the
space carefully in the second call. Try removing it and observe the behaviour of the
program)
#include <stdio.h>
int main()
{
char c;
scanf("%c",&c);
printf("%c\n",c);
scanf(" %c",&c);
printf("%c\n",c);
return 0;
}
What is the potential problem with the following C program?
#include <stdio.h>
int main()
{
char str[80];
printf("Enter the string:");
scanf("%s",str);
printf("You entered:%s\n",str);
return 0;
}
What is the output of the following program?
#include <stdio.h>
int main()
{
int i;
i = 10;
printf("i : %d\n",i);
printf("sizeof(i++) is: %d\n",sizeof(i++));
printf("i : %d\n",i);
return 0;
}
Why does the following program give a warning? (Please remember that sending a
normal pointer to a function requiring const pointer does not give any warning)
#include <stdio.h>
void foo(const char **p) { }
int main(int argc, char **argv)
{
foo(argv);
return 0;
}
What is the output of the following program?
#include <stdio.h>
int main()
{
int i;
i = 1,2,3;
printf("i:%d\n",i);
return 0;
}
The following is a piece of code which implements the reverse Polish Calculator.
There is a(are) serious(s) bug in the code. Find it(them) out!!! Assume that the
function getop returns the appropriate return values for operands, opcodes, EOF etc..
#include <stdio.h>
#include <stdlib.h>
#define MAX 80
#define NUMBER '0'
int getop(char[]);
void push(double);
double pop(void);
int main()
{
int type;
char s[MAX];
char t[]={
0,0,0,0,0,0,12,18,33,63,
33,33,62,32,62,33,33,62,30,33,
32,32,33,30,62,33,33,33,33,62,
63,32,62,32,32,63,63,32,62,32,
32,32,30,33,32,39,33,30,33,33,
63,33,33,33,4,4,4,4,4,4,
1,1,1,1,33,30,33,34,60,36,
34,33,32,32,32,32,32,63,33,51,
45,33,33,33,33,49,41,37,35,33,
30,33,33,33,33,30,62,33,33,62,
32,32,30,33,33,37,34,29,62,33,
33,62,34,33,30,32,30,1,33,30,
31,4,4,4,4,4,33,33,33,33,
33,30,33,33,33,33,18,12,33,33,
33,45,51,33,33,18,12,12,18,33,
17,10,4,4,4,4,63,2,4,8,
16,63
};
int r,pr;
for(r=0;r<6;++r)
{
char *p=argv[1];
while(pr&&*p)
{
int o=(toupper(*p++)-'A')*6+6+r;
o=(o<0||o>=sizeof(t))?0:o;
for(pr=5;pr>=-1;--pr)
{
printf("%c",( ( (pr>=0) && (t[o]&(1<<pr)))?'#':'
'));
}
}
printf("\n");
}
return 0;
}
for(i=0;i<SIZEOF(pot);i++)
PrintInt(pot[i]);
return 0;
}
The following is the implementation of the Euclid's algorithm for finding the
G.C.D(Greatest Common divisor) of two integers. Explain the logic for the below
implementation and think of any possible improvements on the current
implementation.
BTW, what does scanf function return?
#include <stdio.h>
int gcd(int u,int v)
{
int t;
while(v > 0)
{
if(u > v)
{
t = u;
u = v;
v = t;
}
v = v-u;
}
return u;
}
int main()
{
int x,y;
printf("Enter x y to find their gcd:");
while(scanf("%d%d",&x, &y) != EOF)
{
if(x >0 && y>0)
printf("%d %d %d\n",x,y,gcd(x,y));
printf("Enter x y to find their gcd:");
}
printf("\n");
return 0;
}
Also implement a C function similar to the above to find the GCD of 4 integers.
What's the output of the following program. (No, it's not 10!!!)
#include <stdio.h>
#define PrintInt(expr) printf("%s : %d\n",#expr,(expr))
int main()
{
int y = 100;
int *p;
p = malloc(sizeof(int));
*p = 10;
y = y/*p; /*dividing y by *p */;
PrintInt(y);
return 0;
}
The following is a simple C program to read a date and print the date. Run it and
explain the behaviour
#include <stdio.h>
int main()
{
int day,month,year;
printf("Enter the date (dd-mm-yyyy) format including -'s:");
scanf("%d-%d-%d",&day,&month,&year);
printf("The date you have entered is %d-%d-
%d\n",day,month,year);
return 0;
}
The following is a simple C program to read and print an integer. But it is not working
properly. What is(are) the mistake(s)?
#include <stdio.h>
int main()
{
int n;
printf("Enter a number:\n");
scanf("%d\n",n);
int main()
{
int a = 1, b = 2,c = 3;
PrintInt(FiveTimes(a));
PrintInt(FiveTimes(b));
PrintInt(FiveTimes(c));
return 0;
}
Is the following a valid C program?
#include <stdio.h>
#define PrintInt(expr) printf("%s : %d\n",#expr,(expr))
int max(int x, int y)
{
(x > y) ? return x : return y;
}
int main()
{
int a = 10, b = 20;
PrintInt(a);
PrintInt(b);
PrintInt(max(a,b));
}
The following is a piece of C code, whose intention was to print a minus sign 20
times. But you can notice that, it doesn't work.
#include <stdio.h>
int main()
{
int i;
int n = 20;
for( i = 0; i < n; i-- )
printf("-");
return 0;
}
Well fixing the above code is straight-forward. To make the problem interesting, you
have to fix the above code, by changing exactly one character. There are three known
solutions. See if you can get all those three.
What's the mistake in the following code?
#include <stdio.h>
int main()
{
int* ptr1,ptr2;
ptr1 = malloc(sizeof(int));
ptr2 = ptr1;
*ptr2 = 10;
return 0;
}
What is the output of the following program?
#include <stdio.h>
int main()
{
int cnt = 5, a;
do {
a /= cnt;
} while (cnt --);
a = malloc(SIZE*sizeof(int));
Questions
L1.Q1 : Write the output of the following program
#include
#define ABC 20
#define XYZ 10
#define XXX ABC - XYZ
void main()
{
int a;
a = XXX * 10;
printf("%d\n", a);
}
#define calc(a, b) (a * b) / (a - b)
void main()
{
int a = 20, b = 10;
void main()
{
int cnt = 5, a;
do {
a /= cnt;
} while (cnt --);
void main()
{
int a, b, c, abc = 0;
a = b = c = 40;
if (c) {
int abc;
abc = a*b+c;
}
main()
{
int k = 5;
printf("%d\n", k);
}
main()
{
int a = 5;
fn(a, a++);
}
Answers
L1.A1
Solution for L1.Q1
a = xxx * 10
which is => a = ABC - XYZ * 10
=> a = 20 - 10 * 10
=> a = 20 - 100
=> a = -80
L1.A2
Solution for L1.Q2
Actual substitution is like this :
L1.A3
Solution for L1.Q3
This problem will compile properly, but it will give run
time error. It will give divide-by-zero error. Look in to
the do loop portion
a /= cnt; /* ie. a /= 0 */
which leads to divide-by-zero error.
L1.A4
Solution for L1.Q4
the result will be c = 40 and abc = 0;
because the scope of the variable 'abc' inside if(c) {.. }
is not valid out side that if (.) { .. }.
L1.A5
Solution for L1.Q5
The answer is 7. The first condition ++k < 5 is checked and
it is false (Now k = 6). So, it checks the 3rd condition
(or condition ++k <= 8) and (now k = 7) it is true. At this
point k value is incremented by twice, hence the value of k
becomes 7.
L1.A6
Solution for L1.Q6
The solution depends on the implementation of stack.
(Depends on OS) In some machines the arguments are passed
from left to right to the stack. In this case the result
will be
Main : 5 7 Fn : 7 7
Main : 6 6
Fn : 8 7
Questions
L2.Q1 : Write the output of this program
#include
main()
{
int *a, *s, i;
printf("%d\n", *s++);
printf("%d\n", (*s)++);
printf("%d\n", *s);
printf("%d\n", *++s);
printf("%d\n", ++*s);
}
void fn(int);
main()
{
while (val --) fn(val);
printf("%d\n", val);
}
main()
{
typedef union {
int a;
char b[10];
float c;
} Union;
Union x, y = { 100 };
x.a = 50;
strcpy (x.b, "hello");
x.c = 21.50;
main()
{
struct Data {
int a;
int b;
} y[4] = { 1, 10, 3, 30, 2, 20, 4, 40};
struct Data *x = y;
int i;
main()
{
typedef struct {
int a;
int b;
int c;
char ch;
int d;
}xyz;
typedef union {
xyz X;
char y[100];
}abc;
main()
{
int fd;
char str[20] = "Hello! Test me";
main()
{
int *a, i;
a = (int *) malloc(10*sizeof(int));
free(a);
}
L2.Q8 :
Write a program to calculate number of 1's (bit) in a given
integer number i.e) Number of 1's in the given integer's
equivalent binary representation.
Answers
L2.A1
Solution for L2.Q1
The output will be : 0 10 11 20 21
L2.A2
Solution for L2.Q2
Some compiler (ansi) may give warning message, but it will
compile without errors.
The output will be : 0 1 2 3 4 and -1
L2.A3
Solution for L2.Q3
This is the problem about Unions. Unions are similar to
structures but it differs in some ways. Unions can be
assigned only with one field at any time. In this case,
unions x and y can be assigned with any of the one field a
or b or c at one time. During initialisation of unions it
takes the value (whatever assigned ) only for the first
field. So, The statement y = {100} intialises the union y
with field a = 100.
L2.A4
Solution for L2.Q4
The pointer x points to the same location where y is stored.
So, The changes in y reflects in x.
L2.A5
Solution for L2.Q5
The output of this program is purely depends on the
processor architecuture. If the sizeof integer is 4 bytes
and the size of character is 1 byte (In some computers), the
output will be
L2.A6
Solution for L2.Q6
Just try to execute this file as such. You can find out
that it will exit immediately. Do you know why?
With this hint, we can trace out the error. If you look
into the macro 'Error', you can easily identify that there
are two separete statements without brases '{ ..}'. That is
the problem. So, it exits after the calling open(). The
macro should be put inside the brases like this.
L2.A7
Solution for L2.Q7
This program will fault (Memory fault/segmentation fault).
Can you predict Why?
Remove the statment 'free(a);' from the program, then
execute the program. It will run. It gives the results
correctly.
L2.A8
Solution for L2.Q8
#include
main(argc, argv)
int argc;
char *argv[];
{
int count = 0, i;
int v = atoi(argv[1]);
L3.Q1 :
Write a function revstr() - which reverses the given string
in the same string buffer using pointers. (ie) Should not
use extra buffers for copying the reverse string.
L3.Q2 :
Write a program to print the series 2 power x, where x >= 0
( 1, 2, 4, 8, 16, .... ) without using C math library and
arithmatic operators ( ie. *, /, +, - and math.h are not
allowed)
L3.Q4 :
Write a general swap macro in C :
- A macro which can swap any type of data (ie. int, char,
float, struct, etc..)
L3.Q5 :
Write a program to delete the entry from the doubly linked
list without saving any of the entries of the list to the
temporary variable.
main()
{
int *a, *savea, i;
a *= a;
strcat(b, "func1 ");
return (fn(a, b));
}
main()
{
abc *f1, *f2;
int res;
static char str[50] = "hello! ";
f1 = func1;
res = f1(10, str);
f1 = func2;
res = f1(res, str);
LX.Q8 :
Write a program to reverse a Linked list within the same list
main()
{
int a=3, b = 5;
len--;
while(i < j) {
*(str+i)^=*(str+len)^=*(str+i)^=*(str+len);
i++; len--;
}
return(str);
}
L3.A2
Solution for L3.Q2
#include
void main()
{
int i;
L3.A3
Solution for L3.Q3
#include
main()
{
int a, b;
L3.A4
Solution for L3.Q4
#include
/* Verification routines */
main()
{
int a=10, b =20;
float e=10.0, f = 20.0;
char *x = "string1", *y = "string2";
typedef struct { int a; char s[20]; } st;
st s1 = {50, "struct1"}, s2 = {100, "struct2"};
swap(a, b, int);
printf("%d %d\n", a, b);
swap(e, f, float );
printf("%f %f\n", e, f);
ptr_swap();
}
ptr_swap()
{
int *a, *b;
float *c, *d;
a = (int *) malloc(sizeof(int));
b = (int *) malloc(sizeof(int));
*a = 10; *b = 20;
c = (float *) malloc(sizeof(float));
d = (float *) malloc(sizeof(float));
*c = 10.01; *d = 20.02;
/* Solution */
while ((*head)) {
if ((*head)->next == NULL) tail = head;
if ((*head)->val == val) {
*head = (*head)->next;
}
else head = &(*head)->next;
}
while((*tail)) {
if ((*tail)->val == val) {
*tail = (*tail)->prev;
}
else tail= &(*tail)->prev;
}
}
Link *DL_build();
void DL_print(Link *);
main()
{
int val;
Link *head;
head = DL_build();
DL_print(head);
DL_delete(&head, val);
DL_print(head);
}
Link *DL_build()
{
int val;
Link *head, *prev, *next;
if (val == 0) break;
prev = new;
}
return (head);
}
L3.A6
Solution for L3.Q6
The first value will be 0, the rest of the three values will
not be predictable. Actually it prints the values of the
following location in each step
* savea
* (savea + sizeof(int) * sizeof(int))
etc...
Note: You can verify the above by varing the type of 'savea'
variable to char, double, struct, etc.
Instead of statement 'savea += sizeof(int)' use savea++ then
the values 0, 10, 20 and 30 will be printed. This behaviour
is because of pointer arithmatic.
LX.A7
Solution for LX.Q7
Two function pointers f1 and f2 are declared of the type
abc. whereas abc is a pointer to a function returns int.
LX.A8
Solution for LX.Q8
#include
while(head) {
Link *tmp;
tmp = head;
head = head->next;
tmp->next = revlist;
revlist = tmp;
}
return revlist;
}
Link *SL_build();
main()
{
Link *head;
head = SL_build();
head = SL_reverse(head);
printf("\nReversed List\n\n");
while(head) {
printf("%d\t", head->val);
head = head->next;
}
}
Link *SL_build()
{
Link *head, *prev;
while(1) {
Link *new;
int val;
LX.A9
Solution for LX.Q9
In C we can index an array in two ways.
For example look in to the following lines
int a[3] = {10, 20, 30, 40};
In this example index=3 of array 'a' can be represented
in 2 ways.
1) a[3] and
2) 3[a]
i.e) a[3] = 3[a] = 40
Extend the same logic to this problem. You will get the
output as follows