151.Is
there any difference between the two declarations,
152.int
foo(int *arr[]) and
153.int
foo(int *arr[2])
Answer:
No
Explanation:
Functions can only pass pointers and not arrays. The numbers that
are allowed inside the [] is just for more readability. So there is no
difference between the two declarations.
152.What
is the subtle error in the following code segment?
void
fun(int n, int arr[]){
int *p=0;
int i=0;
while(i++<n)
p = &arr[i];
*p = 0;
}
Answer
& Explanation:
If the body of the loop never executes p is assigned no address.
So p remains NULL where *p =0 may result in problem (may rise to runtime error
“NULL pointer assignment” and terminate the program).
153.What
is wrong with the following code?
int
*foo(){
int *s = malloc(sizeof(int)100);
assert(s != NULL);
return s;
}
Answer
& Explanation:
assert macro should be used for debugging and finding out bugs.
The check s != NULL is for error/exception handling and for that assert
shouldn’t be used. A plain if and the corresponding remedy statement has to be
given.
154.What
is the hidden bug with the following
statement?
assert(val++ != 0);
Answer
& Explanation:
Assert macro is used for debugging and removed in release version.
In assert, the experssion involves side-effects. So the behavior of the code
becomes different in case of debug version and the release version thus leading
to a subtle bug.
Rule
to Remember:
Don’t use expressions that have side-effects in assert
statements.
155.void
main(){
int *i = 0x400; // i points
to the address 400
*i = 0; //
set the value of memory location pointed by i;
}
Answer:
Undefined behavior
Explanation:
The second statement results in undefined behavior because it
points to some location whose value may not be available for modification. This type of pointer in which the
non-availability of the implementation of the referenced location is known as
'incomplete type'.
156.#define
assert(cond) if(!(cond)) \
(fprintf(stderr, "assertion failed: %s,
file %s, line %d \n",#cond,\
__FILE__,__LINE__), abort())
void
main(){
int i = 10;
if(i==0)
assert(i < 100);
else
printf("This statement becomes else for if in assert
macro");
}
Answer:
No output
Explanation:
The else part in which the printf is there becomes the else for if
in the assert macro. Hence nothing is printed.
The solution is to use conditional operator instead of if statement
#define
assert(cond) ((cond)?(0): (fprintf (stderr, "assertion failed: \ %s, file
%s, line %d \n",#cond, __FILE__,__LINE__), abort()))
Note:
However this problem of “matching with nearest else” cannot be
solved by the usual method of placing the if statement inside a block like
this,
#define assert(cond) { \
if(!(cond)) \
(fprintf(stderr,
"assertion failed: %s, file %s, line %d \n",#cond,\
__FILE__,__LINE__),
abort()) \
}
157.Is
the following code legal?
struct
a {
int x;
struct a b;
}
Answer:
No
Explanation:
Is it not legal for a structure to contain a member that is of the
same type as in this case. Because this will cause the structure declaration to
be recursive without end.
158.Is
the following code legal?
struct
a {
int x;
struct a *b;
}
Answer:
Yes.
Explanation:
*b is a pointer to type struct a and so is legal. The compiler
knows, the size of the pointer to a structure even before the size of the
structure is determined(as you know the pointer to any type is of same size).
This type of structures is known as ‘self-referencing’ structure.
159.Is
the following code legal?
typedef
struct a {
int x;
aType *b;
}aType;
Answer:
No
Explanation:
The typename aType is not known at the point of declaring the
structure (forward references are not made for typedefs).
160.Is
the following code legal?
typedef
struct a aType;
struct
a{
int x;
aType *b;
};
Answer:
Yes
Explanation:
The typename aType is known at the point of declaring the
structure, because it is already typedefined.
161.Is
the following code legal?
void
main(){
typedef struct a aType;
aType
someVariable;
struct a {
int x;
aType *b;
};
}
Answer:
No
Explanation:
When the declaration,typedef struct a aType; is encountered body
of struct a is not known. This is known as ‘incomplete types’.
162.void
main(){
printf(“sizeof (void *) = %d \n“, sizeof( void *));
printf(“sizeof (int *) = %d \n”, sizeof(int *));
printf(“sizeof (double
*) = %d \n”, sizeof(double *));
printf(“sizeof(struct unknown *) = %d
\n”, sizeof(struct unknown *));
}
Answer:
sizeof (void *) = 2
sizeof (int *) = 2
sizeof (double *) = 2
sizeof(struct unknown *) =
2
Explanation:
The pointer to any type is of same size.
163.char
inputString[100] = {0};
To
get string input from the keyboard which one of the following is better?
1) gets(inputString)
2) fgets(inputString,
sizeof(inputString), fp)
Answer
& Explanation:
The second one is better because gets(inputString) doesn't know
the size of the string passed and so, if a very big input (here, more than 100
chars) the charactes will be written past the input string. When fgets is used
with stdin performs the same operation as gets but is safe.
164.Which
version do you prefer of the following two,
1) printf(“%s”,str); //
or the more curt one
2) printf(str);
Answer
& Explanation:
Prefer the first one. If the str contains any format characters like %d then it will result
in a subtle bug.
165.void
main(){
int i=10, j=2;
int *ip= &i, *jp = &j;
int k = *ip/*jp;
printf(“%d”,k);
}
Answer:
Compiler Error: “Unexpected end of file in comment started in line
5”.
Explanation:
The programmer intended to divide two integers, but by the
“maximum munch” rule, the compiler treats the operator sequence / and * as /*
which happens to be the starting of comment. To force what is intended by the
programmer,
int k = *ip/ *jp;
// give space explicity separating / and *
//or
int k = *ip/(*jp);
// put braces to force the intention
will solve the problem.
166.void
main(){
char ch;
for(ch=0;ch<=127;ch++)
printf(“%c %d \n“, ch,
ch);
}
Answer:
Implementaion dependent
Explanation:
The char type may be signed or unsigned by default. If it is
signed then ch++ is executed after ch reaches 127 and rotates back to -128.
Thus ch is always smaller than 127.
167.Is
this code legal?
int
*ptr;
ptr
= (int *) 0x400;Answer:
Yes
Explanation:
The pointer ptr will point at the integer in the memory location
0x400.
168.main(){
char a[4]="HELLO";
printf("%s",;
}
Answer:
Compiler error: Too many initializers
Explanation:
The array a is of size 4 but the string constant requires 6 bytes
to get stored.
169.main(){
char a[4]="HELL";
printf("%s",;
}
Answer:
HELL%@!~@!@???@~~!
Explanation:
The character array has the memory just enough to hold the string
“HELL” and doesnt have enough space to store the terminating null character. So
it prints the HELL correctly and continues to print garbage values till it
accidentally comes across a NULL character.
170.main(){
int a=10,*j;
void *k;
j=k=&a;
j++;
k++;
printf("\n
%u %u ",j,k);
}
Answer:
Compiler error: Cannot increment a void pointer
Explanation:
Void pointers are generic pointers and they can be used only when
the type is not known and as an intermediate address storage type. No pointer
arithmetic can be done on it and you cannot apply indirection operator (*) on
void pointers.
171.Printf
can be implemented by using __________
list.
Answer:
Variable length argument lists
172. char
*someFun(){
char *temp = “string
constant";
return temp;
}
int main(){
puts(someFun());
}
Answer:
string constant
Explanation:
The program suffers
no problem and gives the output correctly because the character constants are
stored in code/data area and not allocated in stack, so this doesn’t lead to
dangling pointers.
173.char
*someFun1(){
char temp[ ] = “string";
return temp;
}
char *someFun2(){
char temp[ ] = {‘s’,
‘t’,’r’,’i’,’n’,’g’};
return temp;
}
int main(){
puts(someFun1());
puts(someFun2());
}
Answer:
Garbage values.
Explanation:
Both the functions suffer from the problem of dangling pointers.
In someFun1() temp is a character array and so the space for it is allocated in
heap and is initialized with character string “string”. This is created
dynamically as the function is called, so is also deleted dynamically on
exiting the function so the string data is not available in the calling
function main() leading to print some garbage values. The function someFun2()
also suffers from the same problem but the problem can be easily identified in
this case.
174.Explain
Internal linkage.
Internal linkage means that all declarations of the identifier
within one source file refer to a single entity but declarations of the same
identifier in other source files refer to different entities.
175.Can
the formal parameter to a function be declared static?
No, because arguments are always passed on the stack to support
recursion.
176.What
is an lvalue?
Something that can appear on the left side of the "="
sign, it identifies a place where the result can be stored. For example, in the
equation a=b+25, a is an lvalue.
In the equation b+25=a, b+25 cannot be used as an lvalue, because
it does not identify a specific place. Hence the above assignment is illegal.
177.Every
expression that is an lvalue, is also an rvalue. Is the reverse true?
No, lvalue denotes a place in the computer's memory. An rvalue
denotes a value, so it can only be used on the right hand side of an
assignment.
178.What
happens if indirection is performed on a NULL pointer?
On some machines the indirection accesses the memory location
zero. On other machines indirection on a NULL pointer cause a fault that
terminate the program. Hence the result is implementation dependent.
179.Is
the statement legal? d=10-*d.
Illegal because it specifies that an integer quantity (10-*d) be
stored in a pointer variable
180.What
does the below indicate?
int *func(void)
a. void
indicates that there aren't any arguments.
b. there
is one argument of type void.
Answer: a
181.What
are data type modifiers?
To extend the data handling power, C adds 4 modifiers which may
only be applied to char and int. They are namely signed, unsigned, long and
short. Although long may also be applied to double.
182.Interpret
the meaning of the following.
a. “ab”,”a+b”
b. “w+t”
Answer:
"ab","a+b"->open a binary file for
appending
"w+t" ->create a text file for reading and writing.
183.What
is NULL in the context of files?
In using files, if any error occurs, a NULL pointer is returned.
184.What
is Register storage class?
It concerns itself with storing data in the registers of the
microprocessor and not in memory. The value of the variable doesn't have to be
loaded freshly from memory every time. It's important to realize that this a
request to the compiler and not a directive. The compiler may not be able to do
it. Since the registers are normally of 16 bits long, we can use the register
storage class for ints and char's.
185.What
is an assertion statement?
They are actually macros. They test statements you pass to them
and if the statement is false, they halt the program and inform you that the
assertion failed. It is defined in the header file <assert.h>.
186.Parse
int *(*(*(*abc)())[6])();
abc is a pointer to a function returning a pointer to array of
pointer to functions returning pointer to integer.
0 comments:
Post a Comment