Interview QA5

Interview QA5



Ques 1. what is the use of voltile qualifier?

If the variable is declared as volatile , the variable may updated by external program or hardware.
The volatile variable is not optimized by the compiler.
The volatile always read from memory instead of from registers.


Ques 2. what is the use of const keyword?
If the variable is declared as const. then the value of the varible would not be changed by the program.
it is not updated by the user.

const int MAX = 78;
const char STR[10] = "welcome";



Ques 3. what is the use of static variables?

If the variable is declared as static globally, then it is accessible only inside the file where it is declared.
we could not access outside the file.

If the local varible is declared as static inside the function then it is accessible inside the function only.
The varible is initialised only in first call to function. In the next call of the function static variable hold
the previous value will not initialise .

The static variable stored in memory.
The life of the variable is till the program is running.



Ques 4. write a c program to validate the user name and password?

#include <stdio.h>
#include <stdlib.h>
int main()
{
    char username[4][20]={ "user1", "user2", "user3", "user4"};
    char password[4][20] = {"password123", "password456", "password678", "password567"};
    char usern[20], passwordn[20];
    int i=0, j=0, k=0, uname=0, passw=1;

    while(1)
    {
    printf("\n enter the username to login:");
        scanf("%s", usern);
    printf("\n enter the password to login:");
        scanf("%s", passwordn);

    for(i=0; i<4; i++)
    if(strcmp(username[i], usern) == 0)
    {
        uname=1;
            for(j=0; j<4; j++)
            if(strcmp(password[j], passwordn) == 0)
            {
                printf("\n both username and password correct.");
                passw=1;
                break;
            }

    }
    if(uname==0)
        printf("\n entered the wrong username");
    if(passw ==0)
        printf("\n entered the wrong password.");
    else
        break;
    k++;
    if(k==3)
    {
     printf("\n you are exceeded 3 chances to enter password and username.");
     break;
    }
    }
    return 0;
}
 


5. what is optimization in c program?

Optimization is the method of improving the code efficiency and quality.
c program can become less in size, occupies less memory space, speed execution is more. 

The methods of code optimization are:
1. Optimization in loops: 
1.1 unroll small loops: 
 	Instead of calculating and storeing the known constant values, we can directly calculate and initialise.

     factorial number calculation:

program1:
int main()
{
    int fct[6];
	int i;
        fct[0] =1;
	for(i=1; i<6; i++)
		{
		    fct[i] = fct[i-1] *i;		
		}
1, 2 6 24 120
    return 0;
}


program 2: modified program of program1
int main()
{
    int fct[6] = {1, 2, 6, 24, 120};

    return 0;
}

1.2. Avoid calculation in loops:
   we should avoid calculating the in loops which will give same value in all iterations.

example1:
int main()
{
    int x=3, y=4, z=6, m=4;
    int g[100], p;

    for(p=0; p<100; p++)
        g[p] = (x*y+z*m) * p;

    return 0;
}


optimized code of example1:
int main()
{
    int x=3, y=4, z=6, m=4;
    int g[100], p;

    int temp= (x*y+z*m);
    for(p=0; p<100; p++)
        g[p] =  temp* p;

    return 0;
}

1.3. Avoid pointer dereference in loop: 
   since it creates lots of work in memory to access the data each time, so dereference 
   before the loop using some temporary variable.

example1:
int main()
{
    int x=0, p;
    int *q=&x;

    for(p=0; p<100; p++)
        *q = *q+p;
    printf("\n %d ", *q);

    return 0;
}

optimized code of example1:

int main()
{
    int x=0, p;
    int *q=&x;
    int t=*q;

    for(p=0; p<100; p++)
        *q = *q+p;
    *q=t;
     printf("\n %d ", *q);

    return 0;
}

1.4. user register storage class for loop variables: it will increase the speed of accessing the variables.

example1:
int i, temp=0;
for(i=0; i<100; i++)
{
   temp= temp+i;
}

optimized code for example1:
int temp=0;
register int i=0;
for(i=0; i<100; i++)
{
   temp= temp+i;
}

2. Increasing Speed of mathemetical calculation:

2.1 avoid not required division operations, since division operation decreases the speed of execution.

	int x=2,y=3,z=4,m=5,n=6;
	x=y+z+(x/y/z/m)+n;

    we can make modify it as
        x = y+z+(x/(y*z*m)) + n ;  

2.2 Multiplication and Division by power of 2 : 
we can use << for multiplication by 2 and we can use >> for division by 2. 
These shift operations are faster than multiplication and division operation so we can 
use them. the compiler will optimize the code incase of complex expression code
it is advised to do bitshifting.

multiplying by 6 : m= (m<<1)+ (m<<2)
multiplying by 7: m= m<<3 - m
devide by 4      : m = m>>2

2.3 : simplying the complex code expression: 
by simplyfying the expression we can reduce the number of mathematical computations.

Ex:
     z=  a*b +a*b*c+ a*b*c*d 
     z= a*b*(c*(1+d))
here we reduced the 6 multiplication 3 addtion to 3 multiplication and 1 addition.

3 Optimizing the switch statements:

 In c switch statements if case labels are continuous then the compiler creates a jump table and it is faster.
 If it is not then it will creates a if else statements. Compiler will put the most frequent conditions first and
 rarely used at later. so keep the most used cases first and rarely used labels later.

 
ex1: 
 switch(exp)
{
case x:
        different expression
	break;
case y:
        different expression
	break;
case z:
	common statements1;
        different expression
	common statements2;
	break;
case m:
	common statements1;
        different expression
	common statements2;
	break;
case n:
        different expression
	break;
}

modified of example1 for code optimization:

 switch(exp)
{
case x:
        different expression
	break;
case y:
        different expression
	break;
case z:
case m:
common statements1;
switch(exp)
	{
        different expression
	break;
case m:
        different expression
	break;
}
	common statements2;
case n:
        different expression
	break;
}

4. prefer int instead of char or short:
 since the char are converted to int then do the calculation after doing the calculation
 it again converted to char.
 if it doing in a loop it affects lot on performance.

5. pre-increment is preferred than post -increment
  
In pre increment the value is just increment by 1 and copies the value to variable location. 
In post increment the value is copied to temporary variable then it inremented and then it copies the value to variable. 

6. order of expression evaluation:

   ex1 : A || B   Here if A is true then no need to check the B so first we have to keep the exprission most of the times evaluates to true.
   ex2 : A && B   Here if A is false then no need to check the B so first we have to keep the exprission most of the times evaluates to false.


6. can we pass structure be passed by value to a function?

yes, we can pass structure to function by value.

#inclue<stdio.h>
#include <stdlib.h >
struct s{
int d;
}s2;

fun(struct s s2)
{
printf("%d \n ", s2.d);
}

int main()
{
    s2.d=45;
fun(s2);
    return 0;
}


7. why cannot we pass arrays to function by value?
	since array have many elements so individual elements we can pass,
     but without the address we cannot access all the elements. so we cannot pass arrays by value to function.

8. difference between macro and inline funtion?

difference in evaluation:
  - the macro is replaced by it code during preprocessing
  - the inline function is parsed by the compiler.

 - In macro the expression passed as arguments are copied to the variables.
 - in inline the expression passed as arguments are evaluated then copied to variables.

#include

#define CUBE(M) M*M*M
inline int cube(int m)
{
	return m*m*m;
}

int main()
{
	printf(" %d",CUBE(1+2));
	printf(" %d",cube(1+2));
	return 0;
}

output:
7 27

for macro it become  1+2*1+2*1+2 = 1+2+2+2= 7
for inline function  3*3*3 = 27

- macro would not check the type of the arguments
- inline funtion check the type checking for arguments passed.

- macro always expanded by the preprocessor 
- inline function is depend on the compiler decesion to replace it by its code.



9. is the recursive function can be inline?

The compiler decides whether the declared function is inline or it can be treated as normal  function.
The recursive functions are treated as normal function by the compiler even though we declared it as inline.

#include <stdio.h>

int cnt=0;
inline int cube(int m)
{
    cnt++;
    if(cnt<=3)
        cube(m);
    else
    return m*m*m;
}

int main()
{
    int x;
    x=cube(2);
    printf("\n %d",x);
    return 0;
}


10. #define abc(x,y) x##y concatenates but abc( abc(x,y)) gives warning why?

abc(x,y) gives xy which substituted in the inside function .
For the outer function will get 1 argument instead of two , so it gives compiler error.



11. can we declare volatile variable?
 yes we can declare. the variable is constant for the program it is declared.
 but the external program or hardware can change it.