Showing posts with label c++. Show all posts
Showing posts with label c++. Show all posts

Thursday, May 31, 2012

Some C Interview Questions


Some recent set of questions I found from web, found them unique and interesting. 

The sizeof( ) function doesn’t return the size of the block of memory pointed to by a pointer. Why?
Answer:The sizeof( ) operator does not know that malloc( ) has been used to allocate a pointer. sizeof( ) gives us the size of pointer itself. There is no handy way to find out the size of a block allocated by malloc( ).

How do I write a program to convert a string containing number in a hexadecimal form to its equivalent decimal?
Answer: The following program demonstrates this:
main( )
{
char str[] = "0AB" ;
int h, hex, i, n ;
n = 0 ; h = 1 ;
for ( i = 0 ; h == 1 ; i++ )
{
if ( str[i] >= '0' && str[i] <= '9' )
hex = str[i] - '0' ;
else
{
if ( str[i] >= 'a' && str[i] <= 'f' )
hex = str[i] - 'a' + 10 ;
else
if ( str[i] >= 'A' && str[i] <= 'F' )
hex = str[i] - 'A' + 10 ;
else
h = 0 ;
}
if ( h == 1 )
n = 16 * n + hex ;
}
printf ( "\nThe decimal equivalent of %s is %d",
str, n ) ;
}
The output of this program would be the decimal equivalent of 0AB is 171.

What will be the output of the following code?
void main ()
{ int i = 0 , a[3] ;
a[i] = i++;
printf (“%d",a[i]) ;
}
Answer: The output for the above code would be a garbage value. In the statement a[i] = i++; the value of the variable i would get assigned first to a[i] i.e. a[0] and then the value of i would get incremented by 1. Since a[i] i.e. a[1] has not been initialized, a[i] will have a garbage value.

How do I know how many elements an array can hold?
Answer: The amount of memory an array can consume depends on the data type of an array. In DOS environment, the amount of memory an array can consume depends on the current memory model (i.e. Tiny, Small, Large, Huge, etc.). In general an array cannot consume more than 64 kb. Consider following program, which shows the maximum number of elements an array of type int, float and char can have in case of Small memory model.
main( )
{
int i[32767] ;
float f[16383] ;
char s[65535] ;
}

Are the following two statements identical?
char str[6] = "Kicit" ;
char *str = "Kicit" ;
Answer: No! Arrays are not pointers. An array is a single, pre-allocated chunk of contiguous elements (all of the same type), fixed in size and location. A pointer on the other hand, is a reference to any data element (of a particular type) located anywhere. A pointer must be assigned to point to space allocated elsewhere, but it can be reassigned any time. The array declaration char str[6] ; requests that space for 6 characters be set aside, to be known by name str. In other words there is a location named str at which six characters are stored. The pointer declaration char *str ; on the other hand, requests a place that holds a pointer, to be known by the name str. This pointer can point almost anywhere to any char, to any contiguous array of chars, or nowhere.

Is the following code fragment correct?
const int x = 10 ;
int arr[x] ;
Answer: No! Here, the variable x is first declared as an int so memory is reserved for it. Then it is qualified by a const qualifier. Hence, const qualified object is not a constant fully. It is an object with read only attribute, and in C, an object associated with memory cannot be used in array dimensions.

How does free( ) know how many bytes to free?
Answer: The malloc( ) / free( ) implementation remembers the size of each block allocated and returned, so it is not necessary to remind it of the size when freeing.

What is a stack ?
Answer: The stack is a region of memory within which our programs temporarily store data as they execute. For example, when a program passes parameters to functions, C places the parameters on the stack. When the function completes, C removes the items from the stack. Similarly, when a function declares local variables, C stores the variable's values on the stack during the function's execution. Depending on the program's use of functions and parameters, the amount of stack space that a program requires will differ.

What's the difference between these two declarations?
struct str1 { ... } ;
typedef struct { ... } str2 ;
A : The first form declares a structure tag whereas the second declares a typedef. The main difference is that the second declaration is of a slightly more abstract type -- its users don't necessarily know that it is a structure, and the keyword struct is not used when declaring instances of it.

How does a C program come to know about command line arguments?
A: When we execute our C program, operating system loads the program into memory. In case of DOS, it first loads 256 bytes into memory, called program segment prefix. This contains file tables,environment segment, and command line information. When we compile the C program the compiler inserts additional code that parses the command, assigning it to the argv array, making the arguments easily accessible within our C program.

When we open a file, how does functions like fread( )/fwrite( ), etc. get to know from where to read or to write the data?
A: When we open a file for read/write operation using function like fopen( ), it returns a pointer to the structure of type FILE. This structure stores the file pointer called position pointer, which keeps track of current location within the file. On opening file for read/write operation, the file pointer is set to the start of the file. Each time we read/write a character, the position pointer advances one character. If we read one line of text at a step from the file, then file pointer advances to the start of the next line. If the file is opened in append mode, the file pointer is placed at the very end of the file. Using fseek( ) function we can set the file pointer to some other place within the file

Why doesn't the following code give the desired result? 
int x = 3000, y = 2000 ;
long int z = x * y ;
Answer: Here the multiplication is carried out between two ints x and y, and the result that would overflow would be truncated before being assigned to the variable z of type long int. However, to get the correct output, we should use an explicit cast to force long arithmetic as shown below: 
long int z = ( long int ) x * y ;
Note that ( long int )( x * y ) would not give the desired effect.

Why doesn't the following statement work?
char str[ ] = "Hello" ; 
strcat ( str, '!' ) ;
Answer: The string function strcat( ) concatenates strings and not a character. The basic difference between a string and a character is that a string is a collection of characters, represented by an array of characters whereas a character is a single character. To make the above statement work writes the statement as shown below:
strcat ( str, "!" ) ;

What is the difference between "calloc(...)" and "malloc(...)"?
Answer:
1. calloc(...) allocates a block of memory for an array of elements of a certain size. By default the block is initialized to 0. The total number of memory allocated will be (number_of_elements * size). 
malloc(...) takes in only a single argument which is the memory required in bytes. malloc(...) allocated bytes of memory and not blocks of memory like calloc(...).

2.malloc(...) allocates memory blocks and returns a void pointer to the allocated space, or NULL if there is insufficient memory available.
calloc(...) allocates an array in memory with elements initialized to 0 and returns a pointer to the allocated space. calloc(...) calls malloc(...) in order to use the C++ _set_new_mode function to set the new handler mode.

Difference between const char* p and char const* p?
Answer:In const char* p, the character pointed by ‘p’ is constant, so u cant change the value of character pointed by p but u can make ‘p’ refer to some other location. in char const* p, the ptr ‘p’ is constant not the character referenced by it, so u cant make ‘p’ to reference to any other location but u can change the value of the char pointed by ‘p’.

How can you determine the size of an allocated portion of memory?
Answer:You can’t, really. free() can , but there’s no way for your program to know the trick free() uses. Even if you disassemble the library and discover the trick, there’s no guarantee the trick won’t change with the next release of the compiler.

Can static variables be declared within a header file? 
A:you can not declare a static variable without defining it as well (this is really because the actual storage class modifiers static and also extern are mutually exclusive). A static variable could be defined in a header file, but this would cause each source file that included the header file to get its very own private copy from the variable, which is most likely not what was meant

Can a variable become both constant and volatile?
A:Yes. The const modifier implies that this particular program code cannot change the value of the actual variable, but that will not imply that the value can not be changed by means outside this code. For instance, within the example in frequently asked questions, the timer structure was accessed through a volatile const pointer.The function by itself did not change the value of the timer, so it had been declared const. However, the value had been changed by hardware on the computer, so it was declared volatile. If a variable is both equally const and volatile, the two modifiers can come in either order.

Tuesday, June 28, 2011

Finding Stack Direction for a Machine

How would you find out if a machine’s stack grows up or down in memory?

You need to call a function with one parameter, and create one more local variable, the parameters would be pushed on stack and also the local variables would be created on stack, hence, if your parameters address and locals address would give you the result.

Here is the code of subroutine for your reference.

void sub_routine(int a) { 
int b;
b = a;
if(&b < &a)
printf("Stack Grows Downward!");
else
printf("Stack Grows Upward!");
}

int main() {
sub_routine(10);
return 0;
}

Monday, June 20, 2011

Big Endian and Little Endian


  • What is the difference between big endian and little endin machines

The data ordering at the memory is different for them, in little endian higher address have the most significant byte and lower have the least signifincant byte. and otherway round in case of big endian machines.

  • How do u determine a processor to be little endian or big endian, write a small program for it.

int a = 1;
if( *((char *)&a) == 1) 
    printf("Little endian");
else
    printf("Big Endian");


This can also be done using an eum as shown below


enum
{ 
  int a;
  char c[4];
}

a = 1;
if(char[1] == 1) 
    printf("Little Endian");
else
    printf("Big Endian");

Thursday, June 9, 2011

Traverse a tree without recursion

The basic problem of traversing a tree requires recursion. If you dont have recursion then you should have a mechanism to save either side of the tree on to a temporary location, this can be done with a stack.
So the algorithm should be

1) traverse the node, if there is right push on to stack, and go to left node
2) if there is no left then pop from the stack and go to that node.
3) do this til all the nodes are exhausted. i.e. till your node pointer is null

Find the code here, for your reference. Push and Pop can be implemented as a simple stack methods.

/* Traverse a tree without recursion */
/* The basic idea is to use a stack for storing the other side of the tree when going in one direction */

void traverse_without_recursion(node *head) {
    node *next = head;
    while(next != NULL) {
        printf("%d", next->data);
        if(next->right)
            PUSH((int)(next->right));
        if(next->left)
            next = next->left;
        else next = (node *) POP();
    }
}

Write a program to find the max and second max


This is little tricky, but not difficult. easiest way to do this is to sort the array and then find the answer. But that not expected out of you.

The algorithm here is take thefirst element as the max and second max. Then loop through all elements

  1. If the number is larger than max then make it max, and make old max to second max.
  2. Else if it is more than second max then make it the second max.
  3. In all other cases drop that number
Here goes the code for your reference.

/*
** Write a program for finding the max and second max 
** of an array of given size */

#define SIZE 10

int main(void)
{
    int array[SIZE] = {10, 5, 16, 2, 1, 2, 3, 18, 21, 4};
    int i, max, sec_max;

    max  = sec_max = array[0];

    for(i=0; i< SIZE; i++)
    {
        if(array[i] > max) {
            sec_max = max;
            max = array[i];
        }
        else if(array[i] > sec_max)
            sec_max = array[i];
    }

    printf("max =  %d, sec max = %d", max, sec_max);
}

Saturday, December 11, 2010

Compile C/C++ code in eclipse using makefiles

In Linux, usually compilation is done using makefiles, run in command shell. I use to work on Linux kernel, and in such cases, I use to setup a Samba server for editing and source code browsing was done in windows. But then now I am using only one PC, which is a dual boot for windows and Ubuntu Linux, so I cannot have samba server. I was looking for a IDE in Linux, and found eclipse to be very useful.

I wasn't very familiar with the eclipse IDE and I was trying to setup the compilation using makefiles, initially I had some hiccups but could later configure it easily after generating an example C project from it and following similar methods to write the makefiles.

Here is the method to do it, so it might come handy to you in case if you are trying to use eclipse IDE for compiling C/C++ project using make files.

First create a empty C/C++ project, makefile project, and select the --other tool chain--. keep the project settings to default, as shown in the below figure. Click finish.


Once project is created, as a C file, and a 'makefile'. The makefile tells the make program about how the project should be built, I am giving here the sample make file for the simple HelloWorld.c, which you can further extend as per your use.

Monday, September 20, 2010

Single Linked List Example - Add/Delete

Here is the sample program, I have written to explain the singly linked list. This has three functions, one to insert to the list at the head, which is pretty easy by making the new item as the head, and other one to remove from the list when the data is found, 3rd one to insert to the tail of the list, in this case you need to traverse till the end of the list and then insert the item there.

#include <stdio.h>
#include <malloc.h>

typedef struct node_type {
    int data;
    struct node_type *next;
} node;

node *list_head = NULL;

void insert_list(node **plist_head, int data)
{
    node *item = (node *)malloc(sizeof(node));
    item->data = data;
    item->next = *plist_head;
    *plist_head = item;
}

void insert_list_tail(node **plist_head, int data)
{
    node **list_ptr = plist_head;
    node *item = (node *)malloc(sizeof(node));
    item->data = data;
    item->next = NULL;

    while(*list_ptr) 
        list_ptr = &(*list_ptr)->next;

    *list_ptr = item;
}

void show_list(node **list_head)
{
    node **list_ptr = list_head;
    while(*list_ptr)
    {    
        printf("%d\t", (*list_ptr)->data);
        list_ptr = &(*list_ptr)->next;
    } 
    printf("\n");
}

void remove_list(node **plist_head, int data)
{
    node **list_ptr = plist_head;
    while(*list_ptr)
    {
        if((*list_ptr)->data == data)
        {
            node *tmp = *list_ptr;
            *list_ptr = (*list_ptr)->next;
            free(tmp);
            break;
        }
        list_ptr = &(*list_ptr)->next;
    }
}

main()
{
    show_list(&list_head);
    insert_list(&list_head, 2);
    show_list(&list_head);
    insert_list(&list_head, 5);
    show_list(&list_head);
    insert_list(&list_head, 9);
    show_list(&list_head);
    insert_list(&list_head, 1);
    show_list(&list_head);
    remove_list(&list_head, 9);
    show_list(&list_head);
    remove_list(&list_head, 2);
    show_list(&list_head);
    insert_list_tail(&list_head, 8);
    insert_list_tail(&list_head, 12);
    show_list(&list_head);
}

Hope this will help someone who just has just started learning Linked list in C, let me know if something is not clear.

Thursday, September 16, 2010

Where is ZERO size array is used?

If you normally try to declare a zero size array, you would end of getting array, but if the same is used as the last element of a structure then it does not give any error. Infact its method or trick to use variable size array for the last element, this can be achived as shown in the below program.

#include <stdio.h>
#include <malloc.h>
#include <string.h>

typedef struct 
{
    int d;
    char name[0];
}s;

int main(void)
{
    char str[] = "prasad";
    int len;
    s *s1;
    len = strlen(str);
    s1 = (s *)malloc(sizeof(*s1) + len + 1);
    strcpy(s1->name, str);
    s1->d = 12345678;
    printf("d : %d  name : %s", s1->d, s1->name);
}

This kind of trick is normally not required, and you can program most of the things in this world with out using this, but still some people want to show that they can do something special than everybody, so they can do this trick, but when you do this you must be extra careful as you need to allocate right amount of memory for the variable size array, else you would end of corrupting others memory.

Monday, September 13, 2010

How to use Pointers for 2D Arrays

This is when, you want to have a two dimentional array and whos column size of fixed, but how many number of rows you need, you want to decide run time, in that case you may want to allocate memory for the whole 2D array dynamically. But the access to that array should be as simple as accessing it normally when declared using the standard syntax, i.e by using row and column numbers.

Remember that you cannot use, int **p for this purpose, or even int *p[4] for this purpose.

#include <stdio.h>
#include <malloc.h>

main()
{
    int i, j;
    int a[3][4];
    int (*p)[4];

    int size = 3;
    p = (int (*)[4])malloc(12*4);
    for(i=0; i<3; i++)
        for(j=0; j<4; j++)
        {
            p[i][j] = i+j;
            a[i][j] = p[i][j];
        }

    for(i=0; i<3; i++)
    {
        for(j=0; j<4; j++)
            printf("%d ", a[i][j]);
        printf("\n");
    }
}

Have a nice time, and enjoy programming.!

Thursday, August 5, 2010

Interview qeustions on C/C++

1. What is the size of the structure, assume int to be 4 bytes and float to be 4 bytes.

struct {
    enum  {
        integer,
        floating
    } type;
    union {
        int a;
        float b;
    };
} t1;

Answer: The enum would take one integer (4) and other union together will take one more space of larget between two (4), so total 8 bytes.

suppose the structure delcaration is changes as below, then what would be the size?

struct {
    enum type {
        integer,
        floating
    } ;
    union {
        int a;
        float b;
    };
} t1;

Answer: This would result in compilation error, as there is no member of 'type'

2. What doe the following function do? can it be given a better name?

DT* func(DT* a, const DT* b)
{
    DT *c = a;
    while(*a++ = *b++);
    return c;
}

Answer: Assuming that DT is an integer or char, the function would copy data from b to a, untill a zero in b is obtained, zero is also copied, so it can be renamed as string copy function.

3. Is the out put of line one and two inside the loop same, or different?

int a[100][100];
for(int i = 0; i<100; i++) {
    for(int j = 0; j<100; j++) {
        printf("%d", a[i][j]);
        printf("%d", a[j][i]);
    }
}

Answer: The output would be different as they refer to different row and colum, but at the end they out put all the data in the two dimentional array.

If one needs to be prefered over the other, which one will you prefer? and why?

Answer: The first one will be faster as it has less cache miss in case of a cache enabled system compared to the second one, so in a practical system the using first line would be faster, and so it should be prefered. Theoretically if memory access does not use cache, then both will be same in terms of time taken.

4. What is function overloading? how does compiler will know which function to call?

class{ 
    void func(int a);
    void func(int a, int b);
}

Answer: Having many function definitions for the same functions with different number of arguments is called function overloading, and the compiler will decide about the functions by seeing the type and number of params passed to the function call, and decide on which function to call at compile time.

Suppose if the function is defined below with a default argument and when calling if it is not passed then how would compiler decide about function?

class{ 
    void func(int a);
    void func(int a, int b = 0);
}

Answer: Then the compiler wont be able to decide, and it will throw a compile time error.

Wednesday, August 4, 2010

First bit set in an Integer

Write a C code which returns the position of the first bit set.fot eg. for number 104(1101000) output will be 4.

You need to right shift the number untill the number becomes zero and count the number of times right shifted, then you subtract it from the size of an interger (32 bit on a 32 bit machine), you will get the answer. Here is the code for your reference.

int fbs(unsigned int num)
{
    int pos = -1;
    while(num!=0)
    {
        num <<= 1;
        pos++;
    }
    return 32 - pos;
}

Mod 16 without using arithmatic

Write a function which takes an integer value as an argument and return its mod 16 value without using these (%,+,_,/) arithmetic operations

int mod16(int a)
{
    return a>>4;
}

The 4 bits left shift will give mod 16.

what is the difference between dynamic and static linking? which is better?

A dynamic-link library (DLL) is an executable file that acts as a shared library of functions. Dynamic linking provides a way for a process to call a function that is not part of its executable code. The executable code for the function is located in a DLL, which contains one or more functions that are compiled, linked, and stored separately from the processes that use them. DLLs also facilitate the sharing of data and resources. Multiple applications can simultaneously access the contents of a single copy of a DLL in memory.

Dynamic linking differs from static linking in that it allows an executable module (either a .dll or .exe file) to include only the information needed at run time to locate the executable code for a DLL function. In static linking, the linker gets all of the referenced functions from the static link library and places it with your code into your executable.

Using dynamic linking instead of static linking offers several advantages. DLLs save memory, reduce swapping, save disk space, upgrade easier, provide after-market support, provide a mechanism to extend the MFC library classes, support multilanguage programs, and ease the creation of international versions.

In case of free software licenses also, there are provisions with LGPL, using which you dont have to share the code which are linked dynamically.

Thursday, July 15, 2010

Wipro C/C++ Interview Questions

1. What is the main difference between the C++ class and the C structure?


Answer : Both in C++ class and C structure you can have member functions and member variables, but in C++ the member functions are inside the memory allocated for the object, but in C structures they will reside out the memory allocated for the structure.  C++ the member functions are passed with 'this' pointer which pointer to the objects and rest of the things are taken care by compiler with the help of 'this' pointer. This is done by compiler during compile time, and this remains the main difference and helps in achieving the object oriented nature of C++.

2. What is the difference between the two declarations below using volatile keyword.
volatile struct reg_map {
          int reg_r1;
          int reg_r2;
};

struct reg_map {
        volatile int reg_r1;
        volatile int reg_r2;
};

Answer : In the first case it is up to the compiler to make all the variables as volatile, but in second case the compiler will always make the members as volatile, so that the purpose is served. In first case we need to check if the compiler really makes all members volatile or not, and if it does not, then it does not serve the purpose.

3. I have a union declared as below    union  ex_union {
    int a;
    short int ar[2];
   }
 
if I assign the value 0x112233 to a, what would be the values of elements ar[0] and ar[1]

Answer: Considering it to be little endian machine, the value would be, 0x2233 and 0x0011 respectively, Because in Little endian end byte will be in little address and first byte will be in high address.

4. Assume you have a function with two params a and b, and you need to return an int after processing like below.

   int compare(int a, int b)
   {
       if a>b return 1
       if b>a return -1
       if a = b, return 0
   }
you need to write this function without using if else, switch and ternary operators, how do you do it?
Answer: The purpose of this question is, to reduce the pipe line flush during branch, since here there is 50% chance of branch, we need to avoid any branch instructions.
int compare(int a, int b)
{
    int x, m, s;
    x = a - b;             // find the difference
    m = x || 1;            // if magnitude not zero make it 1
    s = (x & (1 << 31));   // get the sign
    __asm sar s, 31        // extend the sign to make it -1
    return s | m;          // or sign and magnitude
}

This can also be written like below, but it will introduce branch in the generated x86 code, check it in visual studio.
int compare (int a, int b)
{
   int x  = 0;
   (a>b) && (x = 1) || (a<b) && (x = -1);
   return x;
}

Update:
In both the above cases, the compiler will generate the the branch instruction, which is same as the if, else and thus defeating the purpose, I have an solution for it, after the subtraction find the sign of the result using below function (code) and it wont generate the branch instruction.

int IntSign(int num)
{
    int sign = (num !=0) | -(int)((unsigned int)num >> (sizeof(int)*8 - 1));
    return sign;
}


The assembly code generate for the calculation is as below (visual studio for x86)

    int sign = (num !=0) | -(int)((unsigned int)num >> (sizeof(int)*8 - 1));
0041140E  xor         eax,eax 
00411410  cmp         dword ptr [num],0 
00411414  setne       al   
00411417  mov         ecx,dword ptr [num] 
0041141A  shr         ecx,1Fh 
0041141D  neg         ecx  
0041141F  or          eax,ecx 
00411421  mov         dword ptr [sign],eax 
    return sign;
00411424  mov         eax,dword ptr [sign] 

Friday, July 9, 2010

Embedded Systems Questions for Interview

Embedded Systems Questions for Interview
 
1) What is a 'volatile' variable?
 
Volatile is a keyword to specify the compiler that this variable value can change any time, so compiler should always read its value from it's address, and not to use temporary registers to store its value and use in later part of the code.
 
 
This is specially important to handle the memory mapped registers which are mapped as some variables or structures in embedded systems, such as hardward status registers etc, whose value can be changed anytime, depending on the hardware state.
 
Examples of volatile variables are,
 
  • Hardware registers in peripherals (for example, status registers)
  • Non-automatic variables referenced within an interrupt service routine
  • Variables shared by multiple tasks in a multi-threaded application
 
Can a volatile be constant? like
volatile const a;
 
Yes it can be, it means that, it can be changes by hardware state chage, but its read only register in hardware, so code should not try to modify it.
 
Can a pointer be volatile ? Explain.
Yes, although this is not very common. An example is when an interrupt service routine modifies a pointer to a buffer
 
What's wrong with the following function?
 
int square(volatile int *ptr)
{
    return *ptr * *ptr;
}
 
This one is wicked. The intent of the code is to return the square of the value pointed to by *ptr . However, since *ptr points to a volatile parameter, the compiler will generate code that looks something like this:
 
int square(volatile int *ptr)
{
    int a,b;
    a = *ptr;
    b = *ptr;
    return a * b;
}
Because it's possible for the value of *ptr to change unexpectedly, it is possible for a and b to be different. Consequently, this code could return a number that is not a square! The correct way to code this is:
 
long square(volatile int *ptr)
{
    int a;
    a = *ptr;
    return a * a;
}
 
2) What is a 'const' variable?
 
In simple terms 'const' means 'read only'. Its value is not changed by any part of the code executed. So compiler can optimize by taking this info, and also it will give warning when user try to change the value of this variable by mistake.
 
If the candidate gets the answer correct, I'll ask him these supplemental questions:
What do the following declarations mean?
 
const int a;
int const a;
const int *a;
int * const a;
int const * a const;
 
The first two mean the same thing, namely a is a const (read-only) integer. The third means a is a pointer to a const integer (that is, the integer isn't modifiable, but the pointer is). The fourth declares a to be a const pointer to an integer (that is, the integer pointed to by a is modifiable, but the pointer is not). The final declaration declares a to be a const pointer to a const integer (that is, neither the integer pointed to by a, nor the pointer itself may be modified). If the candidate correctly answers these questions, I'll be impressed.
 
Even thouugh any program can be written without this keyword, it's good to use this, since it will help the one who is reading the program to understand the code easily by the information that the variable's value wont get changed. So using const keyword will help reducing the bugs in the code.
 
 
3) Which is the best way to write Loops?
The best way is to write count down loops and compiler can generate better machine code for it than the count up loops. In count down at loop termination, it needs to generate one instructions (SUBS), which subtracts as well as check the zero flag, but in count up case it has to add and compare with a constant, which takes two instructions.
 
 
4) What is loop unrolling? 
 
Small loops can be unrolled for higher performance, with the disadvantage of increased codesize. When a loop is unrolled, a loop counter needs to be updated less often and fewer branches are executed. If the loop iterates only a few times, it can be fully unrolled, so that the loop overhead completely disappears.
 
int CountBitOne(uint n)
{     
  int bits = 0;
    while (n != 0)
    {
        if (n & 1) bits++;
        n >> = 1;
    }
  return bits;
}
 
int CountBitOne(uint n)
{
   int bits = 0;
    while (n != 0)
    {
    if (n & 1) bits++;
    if (n & 2) bits++;
    if (n & 4) bits++;
    if (n & 8) bits++;
    n >> = 4;
    }
  return bits;
}
5) How are local and Global variables are allocated by compiler.
 
Normally, cpu registers are allocated for local variables, but if the address of that local variable is used by some code, then it wont allocate register but access from memory, thus result in un-optimized code. Gobal variables always use memory, so access is slower, so always use global only when it is absolutely neccessary.
 
6) Which is better a char, short or int type for optimization?
 
Where possible, it is best to avoid using char and short as local variables. For the types char and short the compiler needs to reduce the size of the local variable to 8 or 16 bits after each assignment. This is called sign-extending for signed variables and zeroextending for unsigned variables. It is implemented by shifting the register left by 24 or 16 bits, followed by a signed or unsigned shift right by the same amount, taking two instructions (zero-extension of an unsigned char takes one instruction).
 
These shifts can be avoided by using int and unsigned int for local variables. This is particularly important for calculations which first load data into local variables and then process the data inside the local variables. Even if data is input and output as 8- or 16-bit quantities, it is worth considering processing them as 32bit quantities
 
7) How to reduce function call overhead in ARM based systems
 
  • Try to ensure that small functions take four or fewer arguments. These will not use the stack for argument passing. It will copied into registers.
 
  • If a function needs more than four arguments, try to ensure that it does a significant amount of work, so that the cost of passing the stacked arguments is outweighed.
 
  • Pass pointers to structures instead of passing the structure itself.
 
  • Put related arguments in a structure, and pass a pointer to the structure to functions. This will reduce the number of parameters and increase readability.
 
  • Minimize the number of long long parameters, as these take two argument words. This also applies to doubles if software floating-point is enabled.
 
  • Avoid functions with a parameter that is passed partially in a register and partially on the stack (split-argument). This is not handled efficiently by the current compilers: all register arguments are pushed on the stack.
 
  • Avoid functions with a variable number of parameters. Varargs functions 
 
8) What is a pure function in ARM terminology?
 
 
Pure functions are those which return a result which depends only on their arguments. They can be thought of as mathematical functions: they always return the same result if the arguments are the same. To tell the compiler that a function is pure, use the special declaration keyword __pure.

__pure int square(int x)
{
    return x * x;
}
9) What are inline functions?
 
The ARM compilers support inline functions with the keyword __inline. This results in each call to an inline function being substituted by its body, instead of a normal call. This results in faster code, but it adversely affects code size, particularly if the inline function is large and used often.
 
Preprocessor
 
10) Using the #define statement, how would you declare a manifest constant that returns the number of seconds in a year? Disregard leap years in your answer.
  
#define SECONDS_PER_YEAR
(60 * 60 * 24 * 365)UL
 
The purpose of this question is to test the following:
 
  1. Basic knowledge of the #define syntax (for example, no semi-colon at the end, the need to parenthesize, and so on)
     
  2. An understanding that the pre-processor will evaluate constant expressions for you. Thus, it is clearer, and penalty-free, to spell out how you are calculating the number of seconds in a year, rather than actually doing the calculation yourself
     
  3. A realization that the expression will overflow an integer argument on a 16-bit machinehence the need for the L, telling the compiler to treat the variable as a Long
     
  4. As a bonus, if you modified the expression with a UL (indicating unsigned long), then you are off to a great start. And remember, first impressions count!
 
11) Write the "standard" MIN macro-that is, a macro that takes two arguments and returns the smaller of the two arguments.
 
#define MIN(a,b) ((a)<(b)?(a):(b))
 
The purpose of this question is to test the following:
 
  1. Basic knowledge of the #define directive as used in macros. This is important because until the inline operator becomes part of standard C, macros are the only portable way of generating inline code. Inline code is often necessary in embedded systems in order to achieve the required performance level
     
  2. Knowledge of the ternary conditional operator. This operator exists in C because it allows the compiler to produce more optimal code than an if-then-else sequence. Given that performance is normally an issue in embedded systems, knowledge and use of this construct is important 
      
  3. Understanding of the need to very carefully parenthesize arguments to macros
 
I also use this question to start a discussion on the side effects of macros, for example,

what happens when you write code such as:

least = MIN(*p++, b);
 
In this case, the expression is replaced by,
 
 *ptr is compared with b, then ptr is incremented to point to next integer, suppose *ptr is small, then *ptr is assigned to least, and ptr is incremented again. 
 
So the result will be integer at (ptr + sizeof(int)). 
 
 
12) What is the purpose of the preprocessor directive #error?   
 
Answer to this question does not need to be known, this is normally explained in the appendices, only nerds normally look into the appendices to see the answers for such questions. Normal folks dont be knowing the answer to this unless they happend to see this somewhere else while doing some project.
 
13) Infinite loops often arise in embedded systems. How does you code an infinite loop in C?
 
There are several solutions to this question. One is,
while(1)
{
} 
Other is using for loop, but here things are not pretty clear as to what is going on.
for(;;)
{
}
Even though both serve the same perpose, its always better to know why you are using the first or second. So when you are asked about such questions you must answer with confidence that both are right, and just matter which way you wish to code it, anyways finally compiler would optimize and generate the same code for it. So dont ever say, I was taught to do it this way, and so never thought about the other ways.
 
There is another way of doing it, i.e. by using goto statement, goto is very basic keyword, which is more like an assembly jump instruction, if one finds more confortable with goto then possibly he works closely with assembly language, or with FORATN.
 
loop:
 ...
 ...
goto loop;
 
 
14) Data declarations
 
a) int a; 
An integer
 
b) int *a; 
A pointer to an integer
 
c) int **a; 
A pointer to a pointer to an integer
 
d) int a[10]; 
An array of 10 integers
 
e) int *a[10]; 
An array of 10 pointers to integers
 
f) int (*a)[10]; 
A pointer to an array of 10 integers
 
g) int (*a)(int); 
A pointer to a function a that takes an integer argument and returns an integer
 
h) int (*a[10])(int); 
An array of 10 pointers to functions that take an integer argument and return an integer
 
People often claim that a couple of these are the sorts of thing that one looks up in textbooks and I agree. While writing this article, I consulted textbooks to ensure the syntax was correct. However, I expect to be asked this question (or something close to it) when I'm being interviewed. Consequently, I make sure I know the answers, at least for the few hours of the interview. Candidates who don't know all the answers (or at least most of them) are simply unprepared for the interview. If they can't be prepared for the interview, what will they be prepared for? 
 
 
15) What are the uses of the keyword static?
 
This simple question is rarely answered completely. Static has three distinct uses in C:
 
  • A variable declared static within the body of a function maintains its value between function invocations

  • A variable declared static within a module, (but outside the body of a function) is accessible by all functions within that module. It is not accessible by functions within any other module. That is, it is a localized global.
      
  • Functions declared static within a module may only be called by other functions within that module. That is, the scope of the function is localized to the module within which it is declared
 
Most candidates get the first part correct. A reasonable number get the second part correct, while a pitiful number understand the third answer. This is a serious weakness in a candidate, since he obviously doesn't understand the importance and benefits of localizing the scope of both data and code.
 
 
16) Bit manipulation : Embedded systems always require the user to manipulate bits in registers or variables. Given an integer variable a, write two code fragments. The first should set bit 3 of a. The second should clear bit 3 of a. In both cases, the remaining bits should be unmodified.
 
These are the three basic responses to this question:
 
  1. No idea. The interviewee cannot have done any embedded systems work
     
  2. Use bit fields. Bit fields are right up there with trigraphs as the most brain-dead portion of C. Bit fields are inherently non-portable across compilers, and as such guarantee that your code is not reusable. The moral: never let a non-embedded person anywhere near a real piece of hardware
     
  3. Use #defines and bit masks. This is a highly portable method and is the one that should be used.
     
My optimal solution to this problem would be:
 
 
#define BIT3 (0x1 << 3)
static int a;
 
void set_bit3(void) {
    a |= BIT3;
}
 
void clear_bit3(void) {
    a &= ~BIT3;
}
 
Some people prefer to define a mask together with manifest constants for the set and clear values. This is also acceptable. The element that I'm looking for is the use of manifest constants, together with the |= and &= ~ constructs 
 
17) Accessing fixed memory locations
 
Embedded systems are often characterized by requiring the programmer to access a specific memory location. On a certain project it is required to set an integer variable at the absolute address 0x67a9 to the value 0xaa55. The compiler is a pure ANSI compiler. Write code to accomplish this task.
 
This problem tests whether you know that it is legal to typecast an integer to a pointer in order to access an absolute location. The exact syntax varies depending upon one's style. However, I would typically be looking for something like this:
 
int *ptr;
ptr = (int *)0x67a9;
*ptr = 0xaa55;
 
A more obscure approach is:
*(int * const)(0x67a9) = 0xaa55;
 
Even if your taste runs more to the second solution, I suggest the first solution when you are in an interview situation.
 
 
18) Interrupts and ISR
Interrupts are an important part of embedded systems. Consequently, many compiler vendors offer an extension to standard C to support interrupts. Typically, this new keyword is __interrupt. The following code uses __interrupt to define an interrupt service routine (ISR). Comment on the code.
 
__interrupt double compute_area (double radius)
{
    double area = PI * radius * radius;
    printf("\nArea = %f", area);
    return area;
}
 
This function has so much wrong with it, it's hard to know where to start:
 
  1. ISRs cannot return a value. If you don't understand this, you aren't hired
  2. ISRs cannot be passed parameters. See the first item for your employment prospects if you missed this
  3. On many processors/compilers, floating-point operations are not necessarily re-entrant. In some cases one needs to stack additional registers. In other cases, one simply cannot do floating point in an ISR. Furthermore, given that a general rule of thumb is that ISRs should be short and sweet, one wonders about the wisdom of doing floating-point math here
  4. In a vein similar to the third point, printf() often has problems with reentrancy and performance.
 
If you missed points three and four, I wouldn't be too hard on you. Needless to say, if you got these last two points, your employment prospects are looking better and better.
 
Code examples
19) What does the following code output and why?

void foo(void)
{
    unsigned int a = 6;
    int b = -20;
    (a+b > 6) ? puts("> 6") :puts("<= 6");
}

This question tests whether you understand the integer promotion rules in C-an area that I find is very poorly understood by many developers. Anyway, the answer is that this outputs "> 6." The reason for this is that expressions involving signed and unsigned types have all operands promoted to unsigned types. Thus comes a very large positive integer and the expression evaluates to greater than 6. This is a very important point in embedded systems where unsigned data types should be used frequently. If you get this one wrong, you are perilously close to not getting the job. 
 
 
20) Comment on the following code fragment.
unsigned int zero = 0;
unsigned int compzero = 0xFFFF;
/*1's complement of zero */

On machines where an int is not 16 bits, this will be incorrect.
 
It should be coded: unsigned int compzero = ~0;
 
This question really gets to whether the candidate understands the importance of word length on a computer. In my experience, good embedded programmers are critically aware of the underlying hardware and its limitations, whereas computer programmers tend to dismiss the hardware as a necessary annoyance.

By this stage, candidates are either completely demoralized-or they're on a roll and having a good time. If it's obvious that the candidate isn't very good, then the test is terminated at this point. However, if the candidate is doing well, then I throw in these supplemental questions.
These questions are hard, and I expect that only the very best candidates will do well on them. In posing these questions, I'm looking more at the way the candidate tackles the problems, rather than the answers. Anyway, have fun...
 

Dynamic memory allocation

21) Although not as common as in non-embedded computers, embedded systems do still dynamically allocate memory from the heap. What are the problems with dynamic memory allocation in embedded systems?
Here, I expect the user to mention memory fragmentation, problems with garbage collection, variable execution time, and so on. This topic has been covered extensively in ESP , mainly by P.J. Plauger. His explanations are far more insightful than anything I could offer here, so go and read those back issues! Having lulled the candidate into a sense of false security, I then offer up
this tidbit:
What does the following code fragment output and why?

char *ptr;
if ((ptr = (char *)malloc(0)) == NULL)
    puts("Got a valid pointer");
else
    puts("Got a null pointer");

This is a fun question. I stumbled across this only recently when a colleague of mine advertently passed a value of 0 to malloc and got back a valid pointer! That is, the above code will output "Got a valid pointer." I use this to start a discussion on whether the interviewee thinks this is the correct thing for the library routine to do. Getting the right answer here is not nearly as important as the way you approach the problem and the rationale for your decision.
 
 
22. Typedef is frequently used in C to declare synonyms for pre-existing data types. It is also possible to use the preprocessor to do something similar. For instance, consider the following code fragment:
#define dPS struct s *
typedef struct s * tPS;


The intent in both cases is to define dPS and tPS to be pointers to structure s. Which method, if any, is preferred and why?
 
This is a very subtle question, and anyone who gets it right (for the right reason) is to be congratulated or condemned ("get a life" springs to mind). The answer is the typedef is preferred. Consider the declarations:
dPS p1,p2;
tPS p3,p4;
The first expands to:
struct s * p1, p2;

which defines p1 to be a pointer to the structure and p2 to be an actual structure, which is probably not what you wanted. The second example correctly defines p3 and p4 to be pointers.

 
Obscure syntax
23. C allows some appalling constructs. Is this construct legal, and if so what does this code do?

int a = 5, b = 7, c;
c = a+++b;
This question is intended to be a lighthearted end to the quiz, as, believe it or not, this is perfectly legal syntax. The question is how does the compiler treat it? Those poor compiler writers actually debated this issue, and came up with the "maximum munch" rule, which stipulates that the compiler should bite off as big (and legal) a chunk as it can. Hence, this code is treated as:
c = a++ + b;
Thus, after this code is executed, a = 6, b = 7, and c = 12.
If you knew the answer, or guessed correctly, well done. If you didn't know the answer then I wouldn't consider this to be a problem. I find the greatest benefit of this question is that it is good for stimulating questions on coding styles, the value of code reviews, and the benefits of using lint.

Tuesday, May 11, 2010

Search two numbers from array to make a sum

You have a array of random numbers and you are given a number k. Find the 2 elements in the array which sum up to k.
e.g: If my array is {2,5,3,1,8,7,5,4} and k=6.
Then 2 numbers that sum up to 6 are 5 and 1.

step 1: sort the array //O(n.log(n))
arr=2,5,3,1,8,7,5,4 --> 1,2,3,4,5,5,7,8

//size=8

step 2:

i=0, j=7

if a[i]+a[j]==K //done
if a[i]+a[j] > K //j--
if a[i]+a[j] < K //i++

repeat step2, till it reaches mid point //O(n)

Monday, May 10, 2010

where is volatile variables stored in memory layout ?

The storage of a variable is not decided based on if it is volatile or not. It can be anywhere as is the case with normal variable. So the variable may be on stack,heap or in the data section of executable, depending on how it gets defined. The volatile qualifier just tells the compiler that this variable may change in ways that are not apparent to you, it can be changed at any point of time, for example is hardware registers (variables mapped to h/w registers). So compiler disables any optimizations such as caching on this variable.

Volatile is type qualifier not a storage class specifier.

Find binary of a Number

Write a function to print the binary value of the number passed to it, and function should not use any variables other than the parameter passed to it.

Answer : We need to use recursion for this, and here is my version of the C code for the same
#include <stdio.h>

void printBinary(int k)
{
if(k != 0)
{
printBinary(k/2);
}
printf("%d", k%2);
}
void main(void)
{
int k = 4561;
printBinary(k);
}

Array manuplation

Given a array of random integers, sort the odd elements in descending order and even numbers in ascending order. Optimize for time complexity.
e.g. for i/p (1,4,5,2,3,6,7) O/p = (7,5,3,1,2,4,6)

Answer :
We can solve this by doing a simple bubble sort, with the below logic
  1. if first number and second number are odd >> compare and exchange >> push lower odd to first
  2. if first is odd and second is even >> no exchange >> we want odd in the first
  3. if first is even and second is also even >> compare and exhange >> push higher even number to last
  4. if first is even and second is odd >> always exchange >> since we want odd numbers first
Here is the complete solution in C
#include <stdio.h>

int a[] = {1,4,5,2,3,6,7};
int len = 7;

void main(void)
{
    int i,j, temp;
    for(i = 0; i < len-1; i++)
    {
        for(j = 0; j< len-1; j++)
        {
         if( a[j] %2  != 0) 
         {     // first odd number
             if(a[j+1] % 2 != 0) 
             {   
                 // second odd number
                 if(a[j] < a[j+1]) 
                 {
                     temp = a[j+1];
                     a[j+1] = a[j];
                     a[j] = temp;
                 }
             }
             else 
             {     // second even number 
                 //do nothing
             }
         }
         else 
         {     // first even number
             if(a[j+1] % 2 != 0) 
             {   
                 // second odd number
                 // always interchange
                 temp = a[j+1];
                 a[j+1] = a[j];
                 a[j] = temp;
             }
             else
             {
                 // second even number
                 if(a[j] > a[j+1])
                 {
                     temp = a[j+1];
                     a[j+1] = a[j];
                     a[j] = temp;
                 }
             }
         }
        }
    }
    for(i=0; i<len; i++)
    printf("%d ", a[i]);
}

Sub Strings

write a code for which input is a string and set of characters acting as delimiters. Cut the given string where ever delimiters occur and return all the set of sub strings. For eg: given string abbcdeffghujsb and delimiter set:c,g,j hen output should be: abb, deff, u, sb
Answer goes as below
char delimiter[] = {'c', 'j' , 'f'};

void get_sub_str(const char *str, char *dl, int dn)
{
char temp[1024];
int i, j, len = 0;
int ssu = 0; // sub string update
for(i=0; str[i]!='\0'; i++)
{
for(j=0; j<dn; j++)
{
if( str[i] == dl[j])
ssu = 1;
}
if(ssu == 1)
{
temp[len] = '\0';
printf("%s\n", temp);
len = 0;
ssu = 0;
i++;
}
temp[len] = str[i];
len++;
}
}