Monday, 23 July 2018

C Interview Questions Set-1

1. What is the difference between declaration and definition of a variable/function

Ans: 
Most of the time, when you declare a variable, you are also providing the definition. What does it mean to define a variable, exactly? It means you are telling the compiler where to create the storage for that variable. For example, if you write:
int x;
int main()
{
    x = 3;
}

The line int x; both declares and defines the variable; it effectively says, "create a variable named x, of type int. Also, the storage for the variable is that it is a global variable defined in the object file associated with this source file." That's kind of weird, isn't it? What is going on is that someone else could actually write a second source file that has this code:

extern int x;
int func()
{
    x = 3;
}

Now the use of extern is creating a declaration of a variable but NOT defining it; it is saying that the storage for the variable is somewhere else. Technically, you could even write code like this:

extern int x;
int func()
{
    x = 3;
}

int x;
And now you have a declaration of x at the top of the program and a definition at the bottom. But usually extern is used when you want to access a global variable declared in another source file, as I showed above, and then link the two resulting object files together after compilation. Using extern to declare a global variable is pretty much the same thing as using a function declaration to declare a function in a header file. (In fact, you'd generally put extern in a header file rather than putting it in a source file.)
In fact, if you put a variable into a header file and do not use extern, you will run into the inverse problem of an undefined symbol; you will have a symbol with multiple definitions, with an error like "redefinition of 'foo'". This will happen when the linker goes to link together multiple object files.

2. What are different storage class specifiers in C?

Ans: 
There are four storage classes in C they are as follows:
  1. Automatic Storage Class
  2. Register Storage Class
  3. Static Storage Class
  4. External Storage Class
Now, let us discuss these storage classes one by one.

1. Automatic Storage Class

A variable defined within a function or block with auto specifier belongs to automatic storage class. All variables defined within a function or block by default belong to automatic storage class if no storage class is mentioned. Variables having automatic storage class are local to the block which they are defined in, and get destroyed on exit from the block.
The following C program demonstrates the visibility level of auto variables.
#include <stdio.h>
int main( )
{
  auto int i = 1;
  {
    auto int i = 2;
    {
      auto int i = 3;
      printf ( "\n%d ", i);
    }
    printf ( "%d ", i);
  }
  printf( "%d\n", i);
}
 
OUTPUT
======
3 2 1

In above example program you see three definitions for variable i. Here, you may be thinking if there could be more than one variable with the same name. Yes, there could be if these variables are defined in different blocks. So, there will be no error here and the program will compile and execute successfully. The printf in the inner most block will print 3 and the variable i defined in the inner most block gets destroyed as soon as control exits from the block. Now control comes to the second outer block and prints 2 then comes to the outer block and prints 1. Here, note that automatic variables must always be initialized properly, otherwise you are likely to get unexpected results because automatic variables are not given any initial value by the compiler.

2. Register Storage Class

The register specifier declares a variable of register storage class. Variables belonging to register storage class are local to the block which they are defined in, and get destroyed on exit from the block. A registerdeclaration is equivalent to an auto declaration, but hints that the declared variable will be accessed frequently; therefore they are placed in CPU registers, not in memory. Only a few variables are actually placed into registers, and only certain types are eligible; the restrictions are implementation-dependent. However, if a variable is declared register, the unary & (address of) operator may not be applied to it, explicitly or implicitly. Register variables are also given no initial value by the compiler.
The following piece of code is trying to get the address of variable i into pointer variable p but it won't succeed because i is declared register; therefore following piece of code won't compile and exit with error "error: address of register variable requested".
#include <stdio.h>
 
int main()
{
  register int i = 10;
  int *p = &i; //error: address of register variable requested
 
  printf("Value of i: %d", *p);
  printf("Address of i: %u", p);
 
}

3. Static Storage Class

The static specifier gives the declared variable static storage class. Static variables can be used within function or file.Unlike global variables, static variables are not visible outside their function or file, but they maintain their values between calls. The static specifier has different effects upon local and global variables. See the following flavours of static specifier.
  • When static specifier is applied to a local variable inside a function or block, the compiler creates permanent storage for it, much as it creates storage for a global variable but static local variable remains visible only to the function or block in which it is defined. In simple terms, a static local variable is a local variable that retains its value between function calls. For example, the following program code defines static variable i at two places in two blocks inside function staticDemo(). Function staticDemo() is called twice within from main function. During second call static variables retain their old values and they are not initialized again in second call of staticDemo().
  • #include <stdio.h>
     
    void staticDemo()
    {
      static int i;
      {
        static int i = 1;
        printf("%d ", i);
        i++;
      }
      printf("%d\n", i);
      i++;
    }
     
    int main()
    {
      staticDemo();
      staticDemo();
    }
    OUTPUT
    ======
    1 0
    2 1
  • When static specifier is applied to a global variable or a function then compiler makes that variable or function known only to the file in which it is defined. A static global variable has internal linkage that means even though the variable is global; routines in other files have no knowledge of it and cannot access and alter its contents directly. The following C program defines one static global variable gInt and a static function staticDemo(), for the variable and function are defined static they cannot be used outside the file (translation unit) staticdemo.c..
  • /* staticdemo.c */
    #include <stdio.h>
    static int gInt = 1;
    static void staticDemo()
    {
      static int i;
      printf("%d ", i);
      i++;
      printf("%d\n", gInt);
      gInt++;
    }
     
    int main()
    {
      staticDemo();
      staticDemo();
    }
    OUTPUT
    ======
    0 1
    1 2


Static variables have default initial value zero and initialized only once in their lifetime.

4. External Storage Class

The extern specifier gives the declared variable external storage class. The principal use of extern is to specify that a variable is declared with external linkageelsewhere in the program. To understand why this is important, it is necessary to understand the difference between a declaration and a definition. A declaration declares the name and type of a variable or function. A definition causes storage to be allocated for the variable or the body of the function to be defined. The same variable or function may have many declarations, but there can be only one definition for that variable or function.
When extern specifier is used with a variable declaration then no storage is allocated to that variable and it is assumed that the variable has already been defined elsewhere in the program. When we use extern specifier the variable cannot be initialized because with extern specifier variable is declared, not defined.
In the following sample C program if you remove extern int x; you will get an error "Undeclared identifier 'x'" because variable x is defined later than it has been used in printf. In this example, the extern specifier tells the compiler that variable x has already been defined and it is declared here for compiler's information.
#include <stdio.h>
 
extern int x;
 
int main()
{
  printf("x: %d\n", x);
}
 
int x = 10;
Also, if you change the statement extern int x; to extern int x = 50; you will again get an error "Redefinition of 'x'" because with extern specifier the variable cannot be initialized, if it is defined elsewhere. If not then extern declaration becomes a definition.
Note that extern can also be applied to a function declaration, but doing so is redundant because all function declarations are implicitly extern.

3. What is scope of a variable? How are variables are scoped in C?


A scope is a region of a program. Variable Scope is a region in a program where a variable is declared and used. So, we can have three types of scopes depending on the region where these are declared and used – 

  1. Local variables are defined inside a function or a block
  2. Global variables are outside all functions
  3. Formal parameters are defined in function parameters

Local Variables


Variables that are declared inside a function or a block are called local variables and are said to have local scope. These local variables can only be used within the function or block in which these are declared. We can use (or access) a local variable only in the block or function in which it is declared. It is invalid outside it.
Local variables are created when the control reaches the block or function containg the local variables and then they get destroyed after that.
#include <stdio.h>

void fun1()
{
    /*local variable of function fun1*/
    int x = 4;
    printf("%d\n",x);
}

int main()
{
    /*local variable of function main*/
    int x = 10;
    {
        /*local variable of this block*/
        int x = 5;
        printf("%d\n",x);
    }
    printf("%d\n",x);
    fun1();
}
Output
5
10
4
The value of the variable ‘x’ is 5 in the block of code ({ }) defined inside the function ‘main’ and the value of this variable ‘x’ in the ‘main’ function outside this block of code ({ }) is 10. The value of this variable ‘x’ is 4 in the function ‘fun1’.

Global Variables


Variables that are defined outside of all the functions and are accessible throughout the program are global variables and are said to have global scope. Once declared, these can be accessed and modified by any function in the program. We can have the same name for a local and a global variable but the local variable gets priority inside a function.
#include <stdio.h>

/*Global variable*/
int x = 10;

void fun1()
{
    /*local variable of same name*/
    int x = 5;
    printf("%d\n",x);
}

int main()
{
    printf("%d\n",x);
    fun1();
}
Output
10
5
You can see that the value of the local variable ‘x’ was given priority inside the function ‘fun1’ over the global variable have the same name ‘x’.

Formal Parameters


Formal Parameters are the parameters which are used inside the body of a function. Formal parameters are treated as local variables in that function and get a priority over the global variables.
#include <stdio.h>

/*Global variable*/
int x = 10;

void fun1(int x)
{
    /*x is a formal parameter*/
    printf("%d\n",x);
}

int main()
{
    fun1(5);
}
Output
5

4.How to print "Hello World" without semicolon?

int main(void)
{
    if (printf("Hello World")){}
}




No comments:

Post a Comment