C Programming: Practice Questions With Answers (Part - VII)

Leave a Comment

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