Pages

Friday, December 19, 2008

About printf Part 2




1.
main() {
const int i=4;
float j;
j = ++i;
printf("%d %f", i,++j);
}

Answer:
Compiler error

Explanation:
i is a constant. You cannot change the value of constant.

2.
int i=10;
main() {
extern int i; {
int i=20;{
const volatile unsigned i=30;
printf("%d",i);
}
printf("%d",i);
}
printf("%d",i);
}

Answer:
30,20,10

Explanation:
'{' introduces new block and thus new scope. In the innermost block i is declared as, const volatile unsigned which is a valid declaration. i is assumed of type int. So printf prints 30. In the next block, i has value 20 and so printf prints 20. In the outermost block, i is declared as extern, so no storage space is allocated for it. After compilation is over the linker resolves it to global variable i (since it is the only variable visible there). So it prints i's value as 10.

3.
aaa() {
printf("hi");
}

bbb(){
printf("hello");
}

ccc(){
printf("bye");
}

main(){

int (*ptr[3])();
ptr[0]=aaa;
ptr[1]=bbb;
ptr[2]=ccc;
ptr[2]();
}

Answer:
bye

Explanation:
ptr is array of pointers to functions of return type int.ptr[0] is assigned to address of the function aaa. Similarly ptr[1] and ptr[2] for bbb and ccc respectively. ptr[2]() is in effect of writing ccc(), since ptr[2] points to ccc.

4.
main(){
FILE *ptr;
char i;
ptr=fopen("zzz.c","r");
while((i=fgetc(ptr))!=EOF)
printf("%c",i);
}

Answer:
Contents of zzz.c.

5.
void main(){
void *v;
int integer=2;
int *i=&integer;
v=i;
printf("%d",(int*)*v);
}

Answer:
Compiler Error. We cannot apply indirection on type void*.

Explanation:
Void pointer is a generic pointer type. No pointer arithmetic can be done on it. Void pointers are normally used for,

1>
Passing generic pointers to functions and returning such pointers.
2>
As a intermediate pointer type.
3>
Used when the exact pointer type will be known at a later point of time.

6.
void main(){
while(1){
if(printf("%d",printf("%d")))
break;
else
continue;
}
}

Answer:
Garbage values.

Explanation:
The inner printf executes first to print some garbage value. The printf returns no of characters printed and this value also cannot be predicted. Still the outer printf prints something and so returns a non-zero value. So it encounters the break statement and comes out of the while statement.

7.
main(){
unsigned int i=10;
while(i-->=0)
printf("%u ",i);
}

Answer:
9 8 7 6 5 4 3 2 1 0 65535 65534…..

Explanation:
Since i is an unsigned integer it can never become negative. So the expression i-- >=0 will always be true, leading to an infinite loop.

8.
main(){
int a[10];
printf("%d",*a+1-*a+3);
}

Answer:
4

Explanation:
*a and -*a cancels out. The result is as simple as 1 + 3 = 4 !

9.
main(){
unsigned int i=65000;
while(i++!=0);
printf("%d",i);
}

Answer:
1

Explanation:
Note the semicolon after the while statement. When the value of i becomes 0 it comes out of while loop. Due to post-increment on i the value of i while printing is 1.

10.
void pascal f(int i,int j,int k){
printf(“%d %d %d”,i, j, k);
}

void cdecl f(int i,int j,int k){
printf(“%d %d %d”,i, j, k);
}

main(){
int i=10;
f(i++,i++,i++);
printf(" %d\n",i);
i=10;
f(i++,i++,i++);
printf(" %d",i);
}

Answer:
10 11 12 13

12 11 10 13

Explanation:
Pascal argument passing mechanism forces the arguments to be called from left to right. cdecl is the normal C argument passing mechanism where the arguments are passed from right to left.

11.
What is the output of the program given below:

main(){
signed char i=0;
for(;i>=0;i++) ;
printf("%d\n",i);
}

Answer:
-128

Explanation:
Notice the semicolon at the end of the for loop. THe initial value of the i is set to 0. The inner loop executes to increment the value from 0 to 127 (the positive range of char) and then it rotates to the negative value of -128. The condition in the for loop fails and so comes out of the for loop. It prints the current value of i that is -128.

12.
main(){
unsigned char i=0;
for(;i>=0;i++) ;
printf("%d\n",i);

}

Answer:
infinite loop.

Explanation:
The difference between the previous question and this one is that the char is declared to be unsigned. So the i++ can never yield negative value and i>=0 never becomes false so that it can come out of the for loop.

13.
main(){

char i=0;
for(;i>=0;i++) ;
printf("%d\n",i);
}

Answer:
Behavior is implementation dependent.

Explanation:
The detail if the char is signed/unsigned by default is implementation dependent. If the implementation treats the char to be signed by default the program will print –128 and terminate. On the other hand if it considers char to be unsigned by default, it goes to infinite loop.

Rule:

You can write programs that have implementation dependent behavior. But dont write programs that depend on such behavior.


That's it for today...
Thanks for reading.

About printf Part 1




1.
void main(){
int const * p=5;
printf("%d",++(*p));
}

Answer:
Compiler error: Cannot modify a constant value.
Explanation:
p is a pointer to a "constant integer". But we tried to change the value of the "constant integer".

2.
main(){
float me = 1.1;
double you = 1.1;
if(me==you)
printf("I love U");
else
printf("I hate U");
}

Answer:
I hate U

Explanation:
For floating point numbers (float, double, long double) the values cannot be predicted exactly. Depending on the number of bytes, the precision with of the value represented varies. Float takes 4 bytes and long double takes 10 bytes. So float stores 0.9 with less precision than long double.

Rule of Thumb:
Never compare or at-least be cautious when using floating point numbers with relational operators (== , >, <, <=, >=,!= ) .

3.
main(){
extern int i;
i=20;
printf("%d",i);
}

Answer:
Linker Error : Undefined symbol '_i'

Explanation:
extern storage class in the following declaration,
extern int i;
specifies to the compiler that the memory for i is allocated in some other program and that address will be given to the current program at the time of linking. But linker finds that no other variable of name i is available in any other program with memory space allocated for it. Hence a linker error has occurred .

4.
main(){
char *p;
printf("%d %d ",sizeof(*p),sizeof(p));
}

Answer:
1 2

Explanation:
The sizeof() operator gives the number of bytes taken by its operand. P is a character pointer, which needs one byte for storing its value (a character). Hence sizeof(*p) gives a value of 1. Since it needs two bytes to store the address of the character pointer sizeof(p) gives 2.

5.
main(){
int i=3;
switch(i) {
default:printf("zero");
case 1: printf("one");
break;
case 2:printf("two");
break;
case 3: printf("three");
break;
}

}

Answer :
three

Explanation :
The default case can be placed anywhere inside the loop. It is executed only when all other cases doesn't match.

6.
main(){
char string[]="Hello World";
display(string);
}

void display(char *string){
printf("%s",string);
}

Answer:
Compiler Error : Type mismatch in redeclaration of function display

Explanation :
In third line, when the function display is encountered, the compiler doesn't know anything about the function display. It assumes the arguments and return types to be integers, (which is the default type). When it sees the actual function display, the arguments and type contradicts with what it has assumed previously. Hence a compile time error occurs.

7.
main(){
int i;
printf("%d",scanf("%d",&i)); // value 10 is given as input here
}

Answer:
1

Explanation:
Scanf returns number of items successfully read.Here 10 is given as input which should have been scanned successfully. So number of items read is 1.

8.
main(){
extern int i;
i=20;
printf("%d",sizeof(i));
}

Answer:
Linker error: undefined symbol '_i'.

Explanation:
extern declaration specifies that the variable i is defined somewhere else. The compiler passes the external variable to be resolved by the linker. So compiler doesn't find an error. During linking the linker searches for the definition of i. Since it is not found the linker flags an error.

9.
main(){
printf("%d", out);
}
int out=100;

Answer:
Compiler error: undefined symbol out in function main.

Explanation:
The rule is that a variable is available for use from the point of declaration. Even though a is a global variable, it is not available for main. Hence an error.

10.
main(){
extern out;
printf("%d", out);
}
int out=100;

Answer:
100

Explanation:
This is the correct way of writing the previous program.

11.
int i,j;
for(i=0;i<=10;i++){ j+=5; assert(i<5); } Answer: Runtime error: Abnormal program termination. assert failed (i<5), ,

Explanation:
asserts are used during debugging to make sure that certain conditions are satisfied. If assertion fails, the program will terminate reporting the same. After debugging use,

#undef NDEBUG

and this will disable all the assertions from the source code. Assertion is a good debugging tool to make use of.

12.
main(){
char name[10],s[12];
scanf(" \"%[^\"]\"",s);
}

How scanf will execute?

Answer:

First it checks for the leading white space and discards it.Then it matches with a quotation mark and then it reads all character upto another quotation mark.

13.
What is the problem with the following code segment?

while ((fgets(receiving array,50,file_ptr)) != EOF) ;

Answer & Explanation:
fgets returns a pointer. So the correct end of file check is checking for != NULL.

That's it.