Free advertising

Free AdvertisingCoupon CodeDell CouponGap CouponTarget Coupon

C INTERVIEW QUESTIONS

1.What is C language?
A..The C programming language is a standardized programming language developed in the early 1970s by Ken Thompson and Dennis Ritchie for use on the UNIX operating system. It has since spread to many other operating systems, and is one of the most widely used programming languages. C is prized for its efficiency, and is the most popular programming language for writing system software, though it is also used for writing applications.

2.What does static variable mean?

A.there are 3 main uses for the static.
1. If you declare within a function:
It retains the value between function calls

2.If it is declared for a function name:
By default function is extern..so it will be visible from other files if the function declaration is as static..it is invisible for the outer files

3. Static for global variables:
By default we can use the global variables from outside files If it is static global..that variable is limited to with in the file

3.What are the different storage classes in C ?

A.C has three types of storage: automatic, static and allocated.

Variable having block scope and without static specifier have automatic storage duration.

Variables with block scope, and with static specifier have static scope. Global variables (i.e, file scope) with or without the the static specifier also have static scope.

Memory obtained from calls to malloc(), alloc() or realloc() belongs to allocated storage class.

4.What is hashing?

A.To hash means to grind up, and that’s essentially what hashing is all about. The heart of a hashing algorithm is a hash function that takes your nice, neat data and grinds it into some random-looking integer.

The idea behind hashing is that some data either has no inherent ordering (such as images) or is expensive to compare (such as images). If the data has no inherent ordering, you can’t perform comparison searches.

If the data is expensive to compare, the number of comparisons used even by a binary search might be too many. So instead of looking at the data themselves, you’ll condense (hash) the data to an integer (its hash value) and keep all the data with the same hash value in the same place. This task is carried out by using the hash value as an index into an array.

To search for an item, you simply hash it and look at all the data whose hash values match that of the data you’re looking for. This technique greatly lessens the number of items you have to look at. If the parameters are set up with care and enough storage is available for the hash table, the number of comparisons needed to find an item can be made arbitrarily close to one.

One aspect that affects the efficiency of a hashing implementation is the hash function itself. It should ideally distribute data randomly throughout the entire hash table, to reduce the likelihood of collisions. Collisions occur when two different keys have the same hash value.

There are two ways to resolve this problem. In open addressing, the collision is resolved by the choosing of another position in the hash table for the element inserted later. When the hash table is searched, if the entry is not found at its hashed position in the table, the search continues checking until either the element is found or an empty position in the table is found.

The second method of resolving a hash collision is called chaining. In this method, a bucket or linked list holds all the elements whose keys hash to the same value. When the hash table is searched, the list must be searched linearly.

5.Can static variables be declared in a header file?

A.You can’t declare a static variable without defining it as well (this is because the storage class modifiers static and extern are mutually exclusive). A static variable can be defined in a header file, but this would cause each source file that included the header file to have its own private copy of the variable, which is probably not what was intended.

6.Can a variable be both const and volatile?

A.Yes. The const modifier means that this code cannot change the value of the variable, but that does not mean that the value cannot be changed by means outside this code. For instance, in the example in FAQ 8, the timer structure was accessed through a volatile const pointer. The function itself did not change the value of the timer, so it was declared const. However, the value was changed by hardware on the computer, so it was declared volatile. If a variable is both const and volatile, the two modifiers can appear in either order.

7.Can include files be nested?

Answer Yes. Include files can be nested any number of times. As long as you use precautionary measures , you can avoid including the same file twice. In the past, nesting header files was seen as bad programming practice, because it complicates the dependency tracking function of the MAKE program and thus slows down compilation. Many of today’s popular compilers make up for this difficulty by implementing a concept called precompiled headers, in which all headers and associated dependencies are stored in a precompiled state.
Many programmers like to create a custom header file that has #include statements for every header needed for each module. This is perfectly acceptable and can help avoid potential problems relating to #include files, such as accidentally omitting an #include file in a module.

8.What is a null pointer?

A.There are times when it’s necessary to have a pointer that doesn’t point to anything. The macro NULL, defined in , has a value that’s guaranteed to be different from any valid pointer. NULL is a literal zero, possibly cast to void* or char*. Some people, notably C++ programmers, prefer to use 0 rather than NULL.
The null pointer is used in three ways:
1) To stop indirection in a recursive data structure
2) As an error value
3) As a sentinel value
9.printf() Function
What is the output of printf("%d")?

A.1. When we write printf("%d",x); this means compiler will print the value of x. But as here, there is nothing after %d so compiler will show in output window garbage value.

2. When we use %d the compiler internally uses it to access the argument in the stack (argument stack). Ideally compiler determines the offset of the data variable depending on the format specification string. Now when we write printf("%d",a) then compiler first accesses the top most element in the argument stack of the printf which is %d and depending on the format string it calculated to offset to the actual data variable in the memory which is to be printed. Now when only %d will be present in the printf then compiler will calculate the correct offset (which will be the offset to access the integer variable) but as the actual data object is to be printed is not present at that memory location so it will print what ever will be the contents of that memory location.

3. Some compilers check the format string and will generate an error without the proper number and type of arguments for things like printf(...) and scanf(...).
malloc()

10.What is the difference between "calloc(...)" and "malloc(...)"?

A.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.

11.printf() Function- What is the difference between "printf(...)" and "sprintf(...)"?

A.sprintf(...) writes data to the character array whereas printf(...) writes data to the standard output device.

12.Compilation How to reduce a final size of executable?

A.Size of the final executable can be reduced using dynamic linking for libraries.

13.Linked Lists -- Can you tell me how to check whether a linked list is circular?

A.Create two pointers, and set both to the start of the list. Update each as follows:
while (pointer1) {
pointer1 = pointer1->next;
pointer2 = pointer2->next;
if (pointer2) pointer2=pointer2->next;
if (pointer1 == pointer2) {
print ("circular");
}
}

If a list is circular, at some point pointer2 will wrap around and be either at the item just before pointer1, or the item before that. Either way, its either 1 or 2 jumps until they meet.

14."union" Data Type What is the output of the following program? Why?

#include
main() {
typedef union {
int a;
char b[10];
float c;
}
Union;

Union x,y = {100};
x.a = 50;
strcpy(x.b,"hello");
x.c = 21.50;
printf("Union x : %d %s %f n",x.a,x.b,x.c);
printf("Union y : %d %s %f n",y.a,y.b,y.c);
}

String Processing --- Write out a function that prints out all the permutations of a string. For example, abc would give you abc, acb, bac, bca, cab, cba.

void PrintPermu (char *sBegin, char* sRest) {
int iLoop;
char cTmp;
char cFLetter[1];
char *sNewBegin;
char *sCur;
int iLen;
static int iCount;

iLen = strlen(sRest);
if (iLen == 2) {
iCount++;
printf("%d: %s%s\n",iCount,sBegin,sRest);
iCount++;
printf("%d: %s%c%c\n",iCount,sBegin,sRest[1],sRest[0]);
return;
} else if (iLen == 1) {
iCount++;
printf("%d: %s%s\n", iCount, sBegin, sRest);
return;
} else {
// swap the first character of sRest with each of
// the remaining chars recursively call debug print
sCur = (char*)malloc(iLen);
sNewBegin = (char*)malloc(iLen);
for (iLoop = 0; iLoop < ctmp =" sCur[iLoop];" x="10;" x="10," y="15;" x =" x++;" y =" ++y;" a="0;" a="="0)" i="0;">>=1){
if (x & 0X1)
i++;
}
return i;
}

Answer: returns the number of ones in the input parameter X

What will happen in these three cases?
if(a=0){
//somecode
}
if (a==0){
//do something
}
if (a===0){
//do something
}

15.What are x, y, y, u
#define Atype int*
typedef int *p;
p x, z;
Atype y, u;

Answer: x and z are pointers to int. y is a pointer to int but u is just an integer variable

16.Advantages of a macro over a function?
A.Macro gets to see the Compilation environment, so it can expand __ __TIME__ __FILE__ #defines. It is expanded by the preprocessor.

For example, you can’t do this without macros
#define PRINT(EXPR) printf( #EXPR “=%d\n”, EXPR)

PRINT( 5+6*7 ) // expands into printf(”5+6*7=%d”, 5+6*7 );

You can define your mini language with macros:
#define strequal(A,B) (!strcmp(A,B))

Macros are a necessary evils of life. The purists don’t like them, but without it no real work gets done.

17.What is the difference between strings and character arrays?
A.A major difference is: string will have static storage duration, whereas as a character array will not, unless it is explicity specified by using the static keyword.

Actually, a string is a character array with following properties:

* the multibyte character sequence, to which we generally call string, is used to initialize an array of static storage duration. The size of this array is just sufficient to contain these characters plus the terminating NUL character.

* it not specified what happens if this array, i.e., string, is modified.

* Two strings of same value[1] may share same memory area. For example, in the following declarations:

char *s1 = “Calvin and Hobbes”;
char *s2 = “Calvin and Hobbes”;

the strings pointed by s1 and s2 may reside in the same memory location. But, it is not true for the following:

char ca1[] = “Calvin and Hobbes”;
char ca2[] = “Calvin and Hobbes”;

[1] The value of a string is the sequence of the values of the contained characters, in order.

18.Write down the equivalent pointer expression for referring the same element a[i][j][k][l]?
A.a[i] == *(a+i)
a[i][j] == *(*(a+i)+j)
a[i][j][k] == *(*(*(a+i)+j)+k)
a[i][j][k][l] == *(*(*(*(a+i)+j)+k)+l)

19.Which bit wise operator is suitable for checking whether a particular bit is on or off?
A.The bitwise AND operator. Here is an example:enum {
KBit0 = 1,
KBit1,

KBit31,
};

if ( some_int & KBit24 )
printf ( “Bit number 24 is ON\n” );
else
printf ( “Bit number 24 is OFF\n” );

20.Which bit wise operator is suitable for turning off a particular bit in a number?
A.The bitwise AND operator, again. In the following code snippet, the bit number 24 is reset to zero.
some_int = some_int & ~KBit24;

21.Which bit wise operator is suitable for putting on a particular bit in a number?
A.The bitwise OR operator. In the following code snippet, the bit number 24 is turned ON:
some_int = some_int | KBit24;

22.Does there exist any other function which can be used to convert an integer or a float to a string?
A.Some implementations provide a nonstandard function called itoa(), which converts an integer to string.

#include

char *itoa(int value, char *string, int radix);

DESCRIPTION
The itoa() function constructs a string representation of an integer.

PARAMETERS
value:
Is the integer to be converted to string representation.

string:
Points to the buffer that is to hold resulting string.
The resulting string may be as long as seventeen bytes.

radix:
Is the base of the number; must be in the range 2 - 36.

A portable solution exists. One can use sprintf():

char s[SOME_CONST];
int i = 10;
float f = 10.20;

sprintf ( s, “%d %f\n”, i, f );

23.Why does malloc(0) return valid memory address ? What's the use ?
A.malloc(0) does not return a non-NULL under every implementation.
An implementation is free to behave in a manner it finds
suitable, if the allocation size requested is zero. The
implmentation may choose any of the following actions:

* A null pointer is returned.

* The behavior is same as if a space of non-zero size
was requested. In this case, the usage of return
value yields to undefined-behavior.

Notice, however, that if the implementation returns a non-NULL
value for a request of a zero-length space, a pointer to object
of ZERO length is returned! Think, how an object of zero size
should be represented?

For implementations that return non-NULL values, a typical usage
is as follows:

void
func ( void )
{
int *p; /* p is a one-dimensional array,
whose size will vary during the
the lifetime of the program */
size_t c;

p = malloc(0); /* initial allocation */
if (!p)
{
perror (”FAILURE” );
return;
}

/* … */

while (1)
{
c = (size_t) … ; /* Calculate allocation size */
p = realloc ( p, c * sizeof *p );

/* use p, or break from the loop */
/* … */
}
return;
}

Notice that this program is not portable, since an implementation
is free to return NULL for a malloc(0) request, as the C Standard
does not support zero-sized objects.

23.Difference between const char* p and char

const* p
A.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 method defined in multiple base

classes with same name can be invoked from

derived class simultaneously
ex:

class x
{
public:
m1();

};

class y
{
public:
m1();

};

class z :public x, public y
{
public:
m1()
{
x::m1();
y::m1();
}

};

25.Write a program to interchange 2 variables

without using the third one.
A.a=7;
b=2;
a = a + b;
b = a - b;
a = a - b;

25.What is the result of using Option Explicit?
A.When writing your C program, you can

include files in two ways.
The first way is to surround the file you want

to include with the angled brackets <>.
This method of inclusion tells the preprocessor

to look for the file in the predefined default

location.
This predefined default location is often an

INCLUDE environment variable that denotes

the path to your include files.
For instance, given the INCLUDE variable
INCLUDE=C:\COMPILER\INCLUDE;S:\SO

URCE\HEADERS;
using the #include version of file inclusion, the

compiler first checks the
C:\COMPILER\INCLUDE
directory for the specified file. If the file is not

found there, the compiler then checks the
S:\SOURCE\HEADERS directory. If the file is

still not found, the preprocessor checks the

current directory.
The second way to include files is to surround

the file you want to include with double

quotation marks. This method of inclusion tells

the preprocessor to look for the file in the

current directory first, then look for it in the

predefined locations you have set up. Using the

#include file version of file inclusion and

applying it to the preceding example, the

preprocessor first checks the current directory

for the specified file. If the file is not found in

the current directory, the

C:COMPILERINCLUDE directory is

searched. If the file is still not found, the

preprocessor checks the S:SOURCEHEADERS

directory.
The #include method of file inclusion is often

used to include standard headers such as

stdio.h or
stdlib.h.
This is because these headers are rarely (if

ever) modified, and they should always be read

from your compiler’s standard include file

directory.
The #include file method of file inclusion is

often used to include nonstandard header files

that you have created for use in your program.

This is because these headers are often

modified in the current directory, and you will

want the preprocessor to use your newly

modified version of the header rather than the

older, unmodified version.

What is the benefit of using an enum rather

than a #define constant?
The use of an enumeration constant (enum) has

many advantages over using the traditional

symbolic constant style of #define. These

advantages include a lower maintenance

requirement, improved program readability,

and better debugging capability.
1) The first advantage is that enumerated

constants are generated automatically by the

compiler. Conversely, symbolic constants must

be manually assigned values by the

programmer.
For instance, if you had an enumerated

constant type for error codes that could occur

in your program, your enum definition could

look something like this:
enum Error_Code
{
OUT_OF_MEMORY,
INSUFFICIENT_DISK_SPACE,
LOGIC_ERROR,
FILE_NOT_FOUND
};
In the preceding example,

OUT_OF_MEMORY is automatically assigned

the value of 0 (zero) by the compiler because it

appears first in the definition. The compiler

then continues to automatically assign numbers

to the enumerated constants, making

INSUFFICIENT_DISK_SPACE equal to 1,

LOGIC_ERROR equal to 2, and

FILE_NOT_FOUND equal to 3, so on.
If you were to approach the same example by

using symbolic constants, your code would look

something like this:
#define OUT_OF_MEMORY 0
#define INSUFFICIENT_DISK_SPACE 1
#define LOGIC_ERROR 2
#define FILE_NOT_FOUND 3
values by the programmer. Each of the two

methods arrives at the same result: four

constants assigned numeric values to represent

error codes. Consider the maintenance

required, however, if you were to add two

constants to represent the error codes

DRIVE_NOT_READY and CORRUPT_FILE.

Using the enumeration constant method, you

simply would put these two constants anywhere

in the enum definition. The compiler would

generate two unique values for these constants.

Using the symbolic constant method, you would

have to manually assign two new numbers to

these constants. Additionally, you would want

to ensure that the numbers you assign to these

constants are unique.
2) Another advantage of using the enumeration

constant method is that your programs are

more readable and thus can be understood

better by others who might have to update your

program later.

3) A third advantage to using enumeration

constants is that some symbolic debuggers can

print the value of an enumeration constant.

Conversely, most symbolic debuggers cannot

print the value of a symbolic constant. This can

be an enormous help in debugging your

program, because if your program is stopped at

a line that uses an enum, you can simply

inspect that constant and instantly know its

value. On the other hand, because most

debuggers cannot print #define values, you

would most likely have to search for that value

by manually looking it up in a header file.

26.How can I open a file so that other

programs can update it at the same time?
Your C compiler library contains a low-level

file function called sopen() that can be used to

open a file in shared mode. Beginning with

DOS 3.0, files could be opened in shared mode

by loading a special program named

SHARE.EXE. Shared mode, as the name

implies, allows a file to be shared with other

programs as well as your own.
Using this function, you can allow other

programs that are running to update the same

file you are updating.
The sopen() function takes four parameters: a

pointer to the filename you want to open, the

operational mode you want to open the file in,

the file sharing mode to use, and, if you are

creating a file, the mode to create the file in.

The second parameter of the sopen() function,

usually referred to as the operation flag

parameter, can have the following values

assigned to it:
Constant Description O_APPEND Appends all

writes to the end of the file
O_BINARY Opens the file in binary

(untranslated) mode
O_CREAT If the file does not exist, it is

created
O_EXCL If the O_CREAT flag is used and the

file exists, returns an error
O_RDONLY Opens the file in read-only mode
O_RDWR Opens the file for reading and

writing
O_TEXT Opens the file in text (translated)

mode
O_TRUNC Opens an existing file and writes

over its contents
O_WRONLY Opens the file in write-only

mode
The third parameter of the sopen() function,

usually referred to as the sharing flag, can have

the following values assigned to it:
Constant Description
SH_COMPAT No other program can access

the file
SH_DENYRW No other program can read

from or write to the file
SH_DENYWR No other program can write to

the file
SH_DENYRD No other program can read

from the file
SH_DENYNO Any program can read from or

write to the file

If the sopen() function is successful, it returns a

non-negative number that is the file’s handle. If

an error occurs, 1 is returned, and the global

variable errno is set to one of the following

values:
Constant Description
ENOENT File or path not found
EMFILE No more file handles are available
EACCES Permission denied to access file
EINVACC Invalid access code
Constant Description
27.What is the quickest sorting method to use?
A.The answer depends on what you mean by

quickest. For most sorting problems, it just

doesn’t matter how quick the sort is because it

is done infrequently or other operations take

significantly more time anyway. Even in cases

in which sorting speed is of the essence, there is

no one answer. It depends on not only the size

and nature of the data, but also the likely

order. No algorithm is best in all cases.
There are three sorting methods in this

author’s toolbox that are all very fast and that

are useful in different situations. Those

methods are quick sort, merge sort, and radix

sort.
The Quick Sort
The quick sort algorithm is of the divide and

conquer type. That means it works by reducing

a sorting problem into several easier sorting

problems and solving each of them. A dividing

value is chosen from the input data, and the

data is partitioned into three sets: elements

that belong before the dividing value, the value

itself, and elements that come after the dividing

value. The partitioning is performed by

exchanging elements that are in the first set but

belong in the third with elements that are in the

third set but belong in the first Elements that

are equal to the dividing element can be put in

any of the three setsthe algorithm will still

work properly.
The Merge Sort
The merge sort is a divide and conquer sort as

well. It works by considering the data to be

sorted as a sequence of already-sorted lists (in

the worst case, each list is one element long).

Adjacent sorted lists are merged into larger

sorted lists until there is a single sorted list

containing all the elements. The merge sort is

good at sorting lists and other data structures

that are not in arrays, and it can be used to

sort things that don’t fit into memory. It also

can be implemented as a stable sort.
The Radix Sort
The radix sort takes a list of integers and puts

each element on a smaller list, depending on

the value of its least significant byte. Then the

small lists are concatenated, and the process is

repeated for each more significant byte until

the list is sorted. The radix sort is simpler to

implement on fixed-length data such as ints.

when should the volatile modifier be used?
The volatile modifier is a directive to the

compiler’s optimizer that operations involving

this variable should not be optimized in certain

ways. There are two special cases in which use

of the volatile modifier is desirable. The first

case involves memory-mapped hardware (a

device such as a graphics adaptor that appears

to the computer’s hardware as if it were part of

the computer’s memory), and the second

involves shared memory (memory used by two

or more programs running simultaneously).
Most computers have a set of registers that can

be accessed faster than the computer’s main

memory. A good compiler will perform a kind

of optimization called redundant load and

store removal. The compiler looks for places in

the code where it can either remove an

instruction to load data from memory because

the value is already in a register, or remove an

instruction to store data to memory because the

value can stay in a register until it is changed

again anyway.
If a variable is a pointer to something other

than normal memory, such as memory-mapped

ports on a peripheral, redundant load and

store optimizations might be detrimental. For

instance, here’s a piece of code that might be

used to time some operation:
time_t time_addition(volatile const struct timer

*t, int a)
{
int n;
int x;
time_t then;
x = 0;
then = t->value;
for (n = 0; n <>
{
x = x + a;
}
return t->value - then;
}

In this code, the variable t-> value is actually a

hardware counter that is being incremented as

time passes. The function adds the value of a to

x 1000 times, and it returns the amount the

timer was incremented by while the 1000

additions were being performed. Without the

volatile modifier, a clever optimizer might

assume that the value of t does not change

during the execution of the function, because

there is no statement that explicitly changes it.

In that case, there’s no need to read it from

memory a second time and subtract it, because

the answer will always be 0. The compiler

might therefore optimize the function by

making it always return 0.
If a variable points to data in shared memory,

you also don’t want the compiler to perform

redundant load and store optimizations.

Shared memory is normally used to enable two

programs to communicate with each other by

having one program store data in the shared

portion of memory and the other program read

the same portion of memory. If the compiler

optimizes away a load or store of shared

memory, communication between the two

programs will be affected.

28.When should the register modifier be used?

Does it really help?
A.The register modifier hints to the compiler

that the variable will be heavily used and

should be kept in the CPU’s registers, if

possible, so that it can be accessed faster.
There are several restrictions on the use of the

register modifier.
First, the variable must be of a type that can be

held in the CPU’s register. This usually means

a single value of a size less than or equal to the

size of an integer. Some machines have

registers that can hold floating-point numbers

as well.
Second, because the variable might not be

stored in memory, its address cannot be taken

with the unary & operator. An attempt to do so

is flagged as an error by the compiler. Some

additional rules affect how useful the register

modifier is. Because the number of registers is

limited, and because some registers can hold

only certain types of data (such as pointers or

floating-point numbers), the number and types

of register modifiers that will actually have any

effect are dependent on what machine the

program will run on. Any additional register

modifiers are silently ignored by the compiler.
Also, in some cases, it might actually be slower

to keep a variable in a register because that

register then becomes unavailable for other

purposes or because the variable isn’t used

enough to justify the overhead of loading and

storing it.
So when should the register modifier be used?

The answer is never, with most modern

compilers. Early C compilers did not keep any

variables in registers unless directed to do so,

and the register modifier was a valuable

addition to the language. C compiler design has

advanced to the point, however, where the

compiler will usually make better decisions

than the programmer about which variables

should be stored in registers.
In fact, many compilers actually ignore the

register modifier, which is perfectly legal,

because it is only a hint and not a directive.

29.How can you determine the size of an

allocated portion of memory?
A.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.

0 comments:

Design by Blogger Templates