Some recent set of questions I found from web, found them unique and interesting.
This is a blog dedicated to all those problems I faced while making some things work, I might have struggled a lot to get the information from the net, this is to make my life easy whenever next time I want to do the same, or for someone who is in need of help, this may make their life easy too. Thanks for visiting my blog, feel free to mail me in case you have any questions.
Thursday, May 31, 2012
Some C Interview Questions
Some recent set of questions I found from web, found them unique and interesting.
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
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
- If the number is larger than max then make it max, and make old max to second max.
- Else if it is more than second max then make it the second max.
- In all other cases drop that number
/*
** 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
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
#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?
#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
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++
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
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
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?
Thursday, July 15, 2010
Wipro C/C++ Interview Questions
Answer : Both in C++ class and C structure you can have member functions and member variables, but in
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];
}
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
}
{
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
}
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
- 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
- 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
- Basic knowledge of the #define syntax (for example, no semi-colon at the end, the need to parenthesize, and so on)
- 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
- 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
- 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!
- 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
- 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
- Understanding of the need to very carefully parenthesize arguments to macros
what happens when you write code such as:
least = MIN(*p++, b);
- 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
- No idea. The interviewee cannot have done any embedded systems work
- 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
- Use #defines and bit masks. This is a highly portable method and is the one that should be used.
- ISRs cannot return a value. If you don't understand this, you aren't hired
- ISRs cannot be passed parameters. See the first item for your employment prospects if you missed this
- 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
- In a vein similar to the third point, printf() often has problems with reentrancy and performance.
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.
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.
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.
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:
char *ptr;
if ((ptr = (char *)malloc(0)) == NULL)
else
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.
#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?
tPS p3,p4;
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.
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;
Tuesday, May 11, 2010
Search two numbers from array to make a sum
Monday, May 10, 2010
where is volatile variables stored in memory layout ?
Volatile is type qualifier not a storage class specifier.
Find binary of a Number
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
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
- if first number and second number are odd >> compare and exchange >> push lower odd to first
- if first is odd and second is even >> no exchange >> we want odd in the first
- if first is even and second is also even >> compare and exhange >> push higher even number to last
- if first is even and second is odd >> always exchange >> since we want odd numbers first
#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
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++;
}
}

