- main(){
int i=10;
void pascal f(int,int,int);
f(i++,i++,i++);
printf(" %d",i);
}
void pascal f(integer
:i,integer:j,integer :k){
write(i,j,k);
}
Answer:
Compiler error: unknown type integer
Compiler error: undeclared function write
Explanation:
Pascal keyword doesn’t mean
that pascal code can be used. It means that the function follows Pascal
argument passing mechanism in calling the functions.
- 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.
- 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.
- 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.
- 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.
Is the following statement a
declaration/definition. Find what does it mean?
int (*x)[10];
Answer:
Definition. x is a pointer
to array of(size 10) integers.
Apply clock-wise rule to find the meaning of this definition.
- What is the output for the program given below?
typedef enum
errorType{warning, error, exception,}error;
main() {
error
g1;
g1=1;
printf("%d",g1);
}
Answer:
Compiler error: Multiple declaration for error
Explanation:
The name error is used in
the two meanings. One means that it is a enumerator constant with value 1. The
another use is that it is a type name (due to typedef) for enum errorType.
Given a situation the compiler cannot distinguish the meaning of error to know
in what sense the error is used:
error g1;
g1=error;
// which error it refers in each case?
When the compiler can
distinguish between usages then it will not issue error (in pure technical
terms, names can only be overloaded in different namespaces).
Note:
The extra comma in the
declaration,enum errorType{warning, error, exception,} is not an error. An extra comma is valid and is provided just for
programmer’s convenience.
- typedef struct error{int warning, error, exception;}error;
main(){
error g1;
g1.error =1;
printf("%d",g1.error);
}
Answer:
1
Explanation:
The three usages of name
errors can be distinguishable by the compiler at any instance, so valid (they
are in different namespaces).
Typedef struct error{int
warning, error, exception;}error;
This error can be used only
by preceding the error by struct kayword as in:
struct error someError;
typedef struct error{int
warning, error, exception;}error;
This can be used only after
. (dot) or -> (arrow) operator preceded by the variable name as in :
g1.error =1;
printf("%d",g1.error);
typedef
struct error{int warning, error, exception;}error;
This can be used to define
variables without using the preceding struct keyword as in:
error g1;
Since the compiler can
perfectly distinguish between these three usages, it is perfectly legal and
valid.
Note:
This code is given here to
just explain the concept behind. In real programming don’t use such overloading
of names. It reduces the readability of the code. Possible doesn’t mean that we
should use it!
- #ifdef something
int some=0;
#endif
main(){
int thing = 0;
printf("%d %d\n",
some ,thing);
}
Answer:
Compiler error : undefined
symbol some
Explanation:
This is a very simple
example for conditional compilation. The name something is not already known to
the compiler making the declaration
int some = 0;
effectively removed from the
source code.
- #if something == 0
int some=0;
#endif
main(){
int thing = 0;
printf("%d %d\n",
some ,thing);
}
Answer:
0 0
Explanation:
This code is to show that
preprocessor expressions are not the same as the ordinary expressions. If a
name is not known the preprocessor treats it to be equal to zero.
- What is the output for the following program?
main(){
int arr2D[3][3];
printf("%d\n",
((arr2D==* arr2D)&&(* arr2D == arr2D[0])) );
}
Answer:
1
Explanation:
This is due to the close
relation between the arrays and pointers. N dimensional arrays are made up of
(N-1) dimensional arrays. arr2D is made up of a 3 single arrays that contains 3
integers each .
The name arr2D refers to the
beginning of all the 3 arrays. *arr2D refers to the start of the first 1D array
(of 3 integers) that is the same address as arr2D. So the expression (arr2D ==
*arr2D) is true (1).
Similarly, *arr2D is nothing
but *(arr2D + 0), adding a zero doesn’t change the value/meaning. Again
arr2D[0] is the another way of telling *(arr2D + 0). So the expression (*(arr2D
+ 0) == arr2D[0]) is true (1).
Since both parts of the
expression evaluates to true the result is true(1) and the same is
printed.
No comments:
Post a Comment