c

41
Dear visitor, 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> #define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0])) int array[] = {23,34,12,17,204,99,16};

Transcript of c

Page 1: c

Dear visitor,

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>

#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0])) int array[] = {23,34,12,17,204,99,16};

int main() { int d;

for(d=-1;d <= (TOTAL_ELEMENTS-2);d++) printf("%d\n",array[d+1]);

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(){

Page 2: c

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) {

Page 3: c

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.out12f(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?

Page 4: c

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;}

Page 5: c

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"); }

Page 6: c

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);

Page 7: c

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);

Page 8: 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'

Page 9: c

int getop(char[]); void push(double); double pop(void); int main() { int type; char s[MAX];

while((type = getop(s)) != EOF) { switch(type) { case NUMBER: push(atof(s)); break; case '+': push(pop() + pop()); break; case '*': push(pop() * pop()); break; case '-': push(pop() - pop()); break; case '/': push(pop() / pop()); break; /* ... * ... * ... */ } } }

The following is a simple program which implements a minimal version of banner command available on most *nix systems. Find out the logic used in the program. #include<stdio.h> #include<ctype.h>

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

Page 10: c

};

int main(int argc,char** argv) {

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; }

What is the output of the following program? #include <stdio.h> #include <stdlib.h>

#define SIZEOF(arr) (sizeof(arr)/sizeof(arr[0]))

#define PrintInt(expr) printf("%s:%d\n",#expr,(expr)) int main() { /* The powers of 10 */ int pot[] = { 0001, 0010, 0100, 1000 }; int i;

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;

Page 11: c

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>

Page 12: c

int main() { int n; printf("Enter a number:\n"); scanf("%d\n",n);

printf("You entered %d \n",n); return 0; }

The following is a simple C program which tries to multiply an integer by 5 using the bitwise operations. But it doesn't do so. Explain the reason for the wrong behaviour of the program. #include <stdio.h> #define PrintInt(expr) printf("%s : %d\n",#expr,(expr)) int FiveTimes(int a) { int t; t = a<<2 + a; return t; }

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; }

Page 13: c

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 --);

printf ("%d\n", a); return 0; }

What is the output of the following program? #include <stdio.h> int main() { int i = 6; if( ((++i < 7) && ( i++/6)) || (++i <= 9)) ; printf("%d\n",i); return 0; }

What is the bug in the following program? #include <stdlib.h> #include <stdio.h> #define SIZE 15 int main() { int *a, i;

a = malloc(SIZE*sizeof(int));

for (i=0; i<SIZE; i++) *(a + i) = i * i; for (i=0; i<SIZE; i++) printf("%d\n", *a++); free(a); return 0; }

Page 14: c

Is the following a valid C program? If so, what is the output of it? #include <stdio.h> int main() { int a=3, b = 5;

printf(&a["Ya!Hello! how is this? %s\n"], &b["junk/super"]); printf(&a["WHAT%c%c%c %c%c %c !\n"], 1["this"], 2["beauty"],0["tool"],0["is"],3["sensitive"],4["CCCCCC"]); return 0; }

What is the output of the following, if the input provided is:Life is beautiful #include <stdio.h> int main() { char dummy[80]; printf("Enter a string:\n"); scanf("%[^a]",dummy); printf("%s\n",dummy); return 0; }

Note : This question has more to do with Linker than C language We have three files a.c, b.c and main.c respectively as follows: a.c--- int a;

b.c--- int a = 10;

main.c------ extern int a;int main(){ printf("a = %d\n",a); return 0;}

Let's see what happens, when the files are compiled together: bash$ gcc a.c b.c main.cbash$ ./a.outa = 10

Hmm!! no compilation/linker error!!! Why is it so??

The following is the offset macros which is used many a times. Figure out what is it trying to do and what is the advantage of using it. #define offsetof(a,b) ((int)(&(((a*)(0))->b)))

The following is the macro implementation of the famous, Triple xor swap. #define SWAP(a,b) ((a) ^= (b) ^= (a) ^= (b))

What are the potential problems with the above macro?

What is the use of the following macro? #define DPRINTF(x) printf("%s:%d\n",#x,x)

Page 15: c

Let's say you were asked to code a function IAddOverFlow which takes three parameters, pointer to an integer where the result is to be stored, and the two integers which needs to be added. It returns 0 if there is an overflow and 1 otherwise: int IAddOverFlow(int* result,int a,int b) { /* ... */ }

So, how do you code the above function? (To put in a nutshell, what is the logic you use for overflow detection?)

What does the following macro do? #define ROUNDUP(x,n) ((x+n-1)&(~(n-1)))

Most of the C programming books, give the following example for the definition of macros. #define isupper(c) (((c) >= 'A') && ((c) <= 'Z'))

But there would be a serious problem with the above definition of macro, if it is used as follows (what is the problem??) char c; /* ... */ if(isupper(c++)) { /* ... */ }

But most of the libraries implement the isupper (declared in ctypes.h) as a macro (without any side effects). Find out how isupper() is implemented on your system.

I hope you know that ellipsis (...) is used to specify variable number of arguments to a function. (What is the function prototype declaration for printf?) What is wrong with the following delcaration? int VarArguments(...) { /*....*/ return 0; }

Write a C program to find the smallest of three integers, without using any of the comparision operators.

What does the format specifier %n of printf function do?

Write a C function which does the addition of two integers without using the '+' operator. You can use only the bitwise operators.(Remember the good old method of implementing the full-adder circuit using the or, and, xor gates....)

How do you print I can print % using the printf function? (Remember % is used as a format specifier!!!)

What's the difference between the following two C statements? const char *p; char* const p;

Page 16: c

What is the difference between memcpy and memmove?

What is the format specifiers for printf to print double and float values?

Write a small C program to determine whether a machine's type is little-endian or big-endian.

Write a C program which prints Hello World! without using a semicolon!!!

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);}

Solution for L1.Q1

L1.Q2 : Write the output of this program #include

#define calc(a, b) (a * b) / (a - b)

void main(){

int a = 20, b = 10;

printf("%d\n", calc(a + 4, b -2));}

Solution for L1.Q2

L1.Q3 : What will be output of the following program ? #include

void main()

Page 17: c

{int cnt = 5, a;

do {a /= cnt;

} while (cnt --);

printf ("%d\n", a);}

Solution for L1.Q3

L1.Q4 : Print the output of this program #include

void main(){

int a, b, c, abc = 0;

a = b = c = 40;

if (c) {int abc;

abc = a*b+c;}

printf ("c = %d, abc = %d\n", c, abc);}

Solution for L1.Q4

L1.Q5 : Print the output of this program #include

main(){

int k = 5;

if (++k < 5 && k++/5 || ++k <= 8);

printf("%d\n", k);}

Solution for L1.Q5

L1.Q6 : What is the output of this program ? #include

void fn(int, int);

Page 18: c

main(){

int a = 5;

printf("Main : %d %d\n", a++, ++a);

fn(a, a++);}

void fn(int a, int b){

printf("Fn : a = %d \t b = %d\n", a, b);}

Solution for L1.Q6

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 :

calc(20+4, 10 -2) is calculated as follows

(20+4 * 10-2) / (20+4 - 10-2)(20+40-2) / 1258 / 12 = 4.8

since it is printed in %d the ans is 4

L1.A3 Solution for L1.Q3 This problem will compile properly, but it will give runtime error. It will give divide-by-zero error. Look in tothe do loop portion

do { a /= cnt; } while (cnt --);

when the 'cnt' value is 1, it is decremented in 'while( cnt --)' and on next reference of 'cnt' it becomes zero.

a /= cnt; /* ie. a /= 0 */

Page 19: c

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 andit is false (Now k = 6). So, it checks the 3rd condition(or condition ++k <= 8) and (now k = 7) it is true. At thispoint k value is incremented by twice, hence the value of kbecomes 7.

L1.A6 Solution for L1.Q6 The solution depends on the implementation of stack.(Depends on OS) In some machines the arguments are passedfrom left to right to the stack. In this case the resultwill be

Main : 5 7 Fn : 7 7

Other machines the arguments may be passed from right toleft to the stack. In that case the result will be

Main : 6 6Fn : 8 7

Questions L2.Q1 : Write the output of this program #include

main(){

int *a, *s, i;

s = a = (int *) malloc( 4 * sizeof(int));

for (i=0; i<4; i++) *(a+i) = i * 10;

printf("%d\n", *s++);printf("%d\n", (*s)++);printf("%d\n", *s);

Page 20: c

printf("%d\n", *++s);printf("%d\n", ++*s);

}

Solution for L2.Q1

L2.Q2 : Checkout this program result #include

void fn(int);

static int val = 5;

main(){

while (val --) fn(val);printf("%d\n", val);

}

void fn(int val){

static int val = 0;

for (; val < 5; val ++) printf("%d\n", val);}

Solution for L2.Q2

L2.Q3 : Can you predict the output of this program ? #include

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;

printf ("Union X : %d %s %f\n", x.a, x.b, x.c);printf ("Union Y : %d %s %f\n", y.a, y.b, y.c);

}

Solution for L2.Q3

Page 21: c

L2.Q4 : Print the output of the program #include

main(){

struct Data {int a;int b;

} y[4] = { 1, 10, 3, 30, 2, 20, 4, 40};

struct Data *x = y;int i;

for(i=0; i<4; i++) {x->a = x->b, ++x++->b; printf("%d %d\t", y[i].a, y[i].b);

}}

Solution for L2.Q4

L2.Q5 : Write the output of this program #include

main(){

typedef struct {int a;int b;int c;char ch;int d;

}xyz;

typedef union {xyz X;char y[100];

}abc;

printf("sizeof xyz = %d sizeof abc = %d\n", sizeof(xyz), sizeof(abc));

}

Solution for L2.Q5

L2.Q6 : Find out the error in this code #include #include

#define Error(str) printf("Error : %s\n", str); exit(1);

main(){

Page 22: c

int fd;char str[20] = "Hello! Test me";

if ((fd = open("xx", O_CREAT | O_RDWR)) < 0) Error("open failed");

if (write(fd, str, strlen(str)) < 0)Error("Write failed");

if (read(fd, str, strlen(str)) < 0)Error("read failed");

printf("File read : %s\n", str);close(fd);

}

Solution for L2.Q6

L2.Q7 : What will be the output of this program ? #include

main(){

int *a, i;

a = (int *) malloc(10*sizeof(int));

for (i=0; i<10; i++) *(a + i) = i * i;

for (i=0; i<10; i++) printf("%d\t", *a++);

free(a);}

Solution for L2.Q7

L2.Q8 : Write a program to calculate number of 1's (bit) in a giveninteger number i.e) Number of 1's in the given integer'sequivalent binary representation.

Solution for L2.Q8

Answers

Page 23: c

L2.A1 Solution for L2.Q1 The output will be : 0 10 11 20 21

*s++ => *(s++)*++s => *(++s)++*s => ++(*s)

L2.A2 Solution for L2.Q2 Some compiler (ansi) may give warning message, but it will compile withouterrors.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 tostructures but it differs in some ways. Unions can beassigned only with one field at any time. In this case,unions x and y can be assigned with any of the one field aor b or c at one time. During initialisation of unions ittakes the value (whatever assigned ) only for the firstfield. So, The statement y = {100} intialises the union ywith field a = 100.

In this example, all fields of union x are assigned withsome values. But at any time only one of the union fieldcan be assigned. So, for the union x the field c isassigned as 21.50.

Thus, The output will be Union 2 : 22 22 21.50Union Y : 100 22 22( 22 refers unpredictable results )

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.

The output will be :10 11 30 31 20 21 40 41

L2.A5 Solution for L2.Q5 The output of this program is purely depends on theprocessor architecuture. If the sizeof integer is 4 bytesand the size of character is 1 byte (In some computers), theoutput will be

Page 24: c

sizeof xyz = 20 sizeof abc = 100

The output can be generalized to some extent as follows,

sizeof xyz = 4 * sizeof(int) + 1 * sizeof(char) + padding bytes

sizeof abc = 100 * sizeof(char) + padding bytes

To keep the structures/unions byte aligned, some paddingbytes are added in between the sturcture fields. In thisexample 3 bytes are padded between ' char ch' and 'int d'fields. The unused bytes are called holes. To understandmore about padding bytes (holes) try varing the field typesof the structures and see the output.

L2.A6 Solution for L2.Q6 Just try to execute this file as such. You can find outthat it will exit immediately. Do you know why?

With this hint, we can trace out the error. If you lookinto the macro 'Error', you can easily identify that thereare two separete statements without brases '{ ..}'. That isthe problem. So, it exits after the calling open(). Themacro should be put inside the brases like this.

#define Error(str) { printf("Error : %s\n", str); exit(1); }

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, thenexecute the program. It will run. It gives the resultscorrectly.

What causes 'free(a)' to generate fault?

Just trace the address location of pointer variable 'a'.The variable 'a' is incremented inside the 'for loop'. Outside the 'for loop' the variable 'a' will point to 'null'.When the free() call is made, it will free the data areafrom the base_address (which is passed as the argument ofthe free call) upto the length of the data allocatedpreviously. In this case, free() tries to free the lengthof 10 *sizeof(int) from the base pointer location passed asthe argument to the free call, which is 'null' in this case.Thus, it generates memory fault.

Page 25: c

L2.A8 Solution for L2.Q8 #include

main(argc, argv)int argc;char *argv[];{

int count = 0, i;int v = atoi(argv[1]);

for(i=0; i<8*sizeof(int); i++) if(v &(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.

Solution for L3.Q1

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 andarithmatic operators ( ie. *, /, +, - and math.h are notallowed)

Solution for L3.Q2

L3.Q3 : Write a program to swap two integers without using 3rdinteger (ie. Without using any temporary variable)

Solution for L3.Q3

L3.Q4 : Write a general swap macro in C :

- A macro which can swap any type of data (ie. int, char,float, struct, etc..)

Page 26: c

Solution for L3.Q4

L3.Q5 : Write a program to delete the entry from the doubly linkedlist without saving any of the entries of the list to thetemporary variable.

Solution for L3.Q5

L3.Q6 : What will be the output of this program ? #include

main(){

int *a, *savea, i;

savea = a = (int *) malloc(4 * sizeof(int));

for (i=0; i<4; i++) *a++ = 10 * i;

for (i=0; i<4; i++) {printf("%d\n", *savea);savea += sizeof(int);

}}

Solution for L3.Q6

LX.Q7 : Trace the program and print the output #include

typedef int abc(int a, char *b);

int func2(int a, char *b){

a *= 2;strcat(b, "func2 ");return a;

}

int func1(int a, char *b){

abc *fn = func2;

a *= a;strcat(b, "func1 ");return (fn(a, b));

Page 27: c

}

main(){

abc *f1, *f2;int res; static char str[50] = "hello! ";

f1 = func1;res = f1(10, str);f1 = func2;res = f1(res, str);

printf("res : %d str : %s\n", res, str);}

Solution for LX.Q7

LX.Q8 : Write a program to reverse a Linked list within the same list

Solution for LX.Q8

LX.Q9 : What will be the output of this program #include

main(){ int a=3, b = 5;

printf(&a["Ya!Hello! how is this? %s\n"], &b["junk/super"]); printf(&a["WHAT%c%c%c %c%c %c !\n"], 1["this"],

2["beauty"],0["tool"],0["is"],3["sensitive"],4["CCCCCC"]);}

Solution for LX.Q9

Answers L3.A1 Solution for L3.Q1 #include

char *rev_str(char *str){

char *s = str, *e = s + strlen(s) -1;

Page 28: c

char *t = "junk"; /* to be safe - conforming with ANSI C std */

while (s < e) { *t = *e; *e-- = *s; *s++ = *t; } return(str);

}

/* Another way of doing this */

char *str_rev(char *str){

int len = strlen(str),i=0,j=len/2;

len--;while(i < j) {

*(str+i)^=*(str+len)^=*(str+i)^=*(str+len);i++; len--;

}return(str);

}

main (int argc, char **argv){

printf("1st method : %s\n", rev_str(argv[1]));printf("2nd method : %s\n", str_rev(argv[1]));

}

L3.A2 Solution for L3.Q2 #include

void main(){

int i;

for(i=0; i< 10; i++)printf("%d\t", 2 << i);

}

L3.A3 Solution for L3.Q3 #include

main(){

int a, b;

printf("Enter two numbers A, B : ");scanf("%d %d", &a, &b);

a^=b^=a^=b; /* swap A and B */

printf("\nA = %d, B= %d\n", a, b);}

Page 29: c

L3.A4 Solution for L3.Q4 #include

/* Generic Swap macro*/#define swap(a, b, type) { type t = a; a = b; b = t; }

/* 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);

swap(x, y, char *);printf("%s %s\n", x, y);

swap(s1, s2, st);printf("S1: %d %s \tS2: %d %s\n", s1.a, s1.s, s2.a, s2.s);

ptr_swap();}

ptr_swap(){

int *a, *b;float *c, *d;

a = (int *) malloc(sizeof(int));b = (int *) malloc(sizeof(int));*a = 10; *b = 20;

swap(a, b, int *);printf("%d %d\n", *a, *b);

c = (float *) malloc(sizeof(float));d = (float *) malloc(sizeof(float));*c = 10.01; *d = 20.02;

swap(c, d, float *);printf("%f %f\n", *c, *d);

}

L3.A5 Solution for L3.Q5 #include

/* Solution */

typedef struct Link{

Page 30: c

int val;struct Link *next;struct Link *prev;

} Link;

void DL_delete(Link **, int);

void DL_delete(Link **head, int val){

Link **tail;

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;

}}

/* Supporting (Verification) routine */

Link *DL_build();void DL_print(Link *);

main(){

int val;Link *head;

head = DL_build();DL_print(head);

printf("Enter the value to be deleted from the list : ");scanf("%d", &val);

DL_delete(&head, val);DL_print(head);

}

Link *DL_build(){

int val;Link *head, *prev, *next;

head = prev = next = NULL;

while(1) {Link *new;

printf("Enter the value for the list element (0 for end) : ");

scanf("%d", &val);

if (val == 0) break;

Page 31: c

new = (Link *) malloc(sizeof(Link));new->val = val;new->prev = prev;new->next = next;

if (prev) prev->next = new;else head = new;

prev = new;}

return (head);}

void DL_print(Link *head){

Link *shead = head, *rhead;printf("\n****** Link List values ********\n\n");while(head) {

printf("%d\t", head->val);if (head->next == NULL) rhead = head;head = head->next;

}

printf("\n Reverse list \n");while(rhead){

printf("%d\t", rhead->val);rhead = rhead->prev;

}printf("\n\n");

}

L3.A6 Solution for L3.Q6 The first value will be 0, the rest of the three values willnot be predictable. Actually it prints the values of thefollowing location in each step

* savea* (savea + sizeof(int) * sizeof(int)) etc...

ie. savea += sizeof(int) => savea = savea + sizeof(savea_type) * sizeof(int)

( by pointer arithmatic) => save = savea + sizeof(int) * sizeof(int)

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++ thenthe values 0, 10, 20 and 30 will be printed. This behaviouris because of pointer arithmatic.

Page 32: c

LX.A7 Solution for LX.Q7 Two function pointers f1 and f2 are declared of the typeabc. whereas abc is a pointer to a function returns int.

func1() which is assigned to f1 is called first. Itmodifies the values of the parameter 'a' and 'b' to 100,"hello! func1 ". In func1(), func2() is called whichfurther modifies the value of 'a' and 'b' to 200, "hello!func1 func2 " and returns the value of 'a' which is 200 tothe main. Main calls f1() again after assigning func2() tof1. So, func2() is called and it returns the followingvalue which will be the output of this program.

res : 400 str : hello! func1 func2 func2

The output string shows the trace of the functions called :func1() and func2() then again func2().

LX.A8 Solution for LX.Q8 #include

typedef struct Link {int val;struct Link *next;

} Link;

/* Reverse List function */Link *SL_reverse(Link *head){

Link *revlist = (Link *)0;

while(head) {Link *tmp;

tmp = head;head = head->next;tmp->next = revlist;revlist = tmp;

}

return revlist;}

/* Supporting (Verification) routines */

Link *SL_build();

main(){

Link *head;

head = SL_build();head = SL_reverse(head);

printf("\nReversed List\n\n");

Page 33: c

while(head) { printf("%d\t", head->val);head = head->next;

}}

Link *SL_build(){

Link *head, *prev;

head = prev = (Link *)0;

while(1) {Link *new;int val;

printf("Enter List element [ 0 for end ] : ");scanf("%d", &val);if (val == 0) break;

new = (Link *) malloc(sizeof(Link));new->val = val;if (prev) prev->next = new;else head = new;prev = new;

}

prev->next = (Link *)0;return head;

}

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 representedin 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 theoutput as follows

Hello! how is this? superThat is C