C Programming

  Home  Computer Programming  C Programming


“C Programming Interview Questions and Answers will guide you that C is a general-purpose computer programming language developed in 1972 by Dennis Ritchie at the Bell Telephone Laboratories and C language is for use with the Unix operating system. If you are developer and need to update your software development knowledge regarding basic and advance C programming or need to prepare for a job interview? Check out this collection of basic and advance C programing Interview Questions and Answers.”



221 C Programming Questions And Answers

121⟩ Why does not C have an exponentiation operator?

One reason is probably that few processors have a built-in exponentiation instruction. C has a pow function (declared in <math.h>) for performing exponentiation, although explicit multiplication is usually better for small positive integral exponents. In other words, pow(x, 2.) is probably inferior to x * x. (If you're tempted to make a Square() macro, though, check

 178 views

122⟩ How do I round numbers?

The simplest and most straightforward way is with code like

(int)(x + 0.5)

C's floating to integer conversion truncates (discards) the fractional part, so adding 0.5 before truncating arranges that fractions >= 0.5 will be rounded up. (This technique won't work properly for negative numbers, though, for which you could use something like (int)(x < 0 ? x - 0.5 : x + 0.5), or play around with the floor and ceil functions.)

You can round to a certain precision by scaling:

(int)(x / precision + 0.5) * precision

Handling negative numbers, or implementing even/odd rounding, is slightly trickier.

Note that because truncation is otherwise the default, it's usually a good idea to use an explicit rounding step when converting floating-point numbers to integers. Unless you're careful, it's quite possible for a number which you thought was 8.0 to be represented internally as 7.999999 and to be truncated to 7.

 175 views

124⟩ My floating-point calculations are acting strangely and giving me different answers on different machines.

If the problem isn't that simple, recall that digital computers usually use floating-point formats which provide a close but by no means exact simulation of real number arithmetic. Among other things, the associative and distributive laws do not hold completely; that is, order of operation may be important, and repeated addition is not necessarily equivalent to multiplication. Underflow, cumulative precision loss, and other anomalies are often troublesome.

Don't assume that floating-point results will be exact, and especially don't assume that floating-point values can be compared for equality. (Don't throw haphazard ``fuzz factors'' in, either; Beware that some machines have more precision available in floating-point computation registers than in double values stored in memory, which can lead to floating-point inequalities when it would seem that two values just have to be equal.

These problems are no worse for C than they are for any other computer language. Certain aspects of floating-point are usually defined as ``however the processor does them'' , otherwise a compiler for a machine without the ``right'' model would have to do prohibitively expensive emulations.

This document cannot begin to list the pitfalls associated with, and workarounds appropriate for, floating-point work. A good numerical programming text should cover the basics; (Beware, though, that subtle problems can occupy numerical analysts for years.)

 186 views

126⟩ When I set a float variable to, say, 3.1, why is printf printing it as 3.0999999?

Most computers use base 2 for floating-point numbers as well as for integers, and just as for base 10, not all fractions are representable exactly in base 2. It's well-known that in base 10, a fraction like 1/3 = 0.333333... repeats infinitely. It turns out that in base 2, one tenth is also an infinitely-repeating fraction (0.0001100110011...), so exact decimal fractions such as 3.1 cannot be represented exactly in binary. Depending on how carefully your compiler's binary/decimal conversion routines (such as those used by printf) have been written, you may see discrepancies when numbers not exactly representable in base 2 are assigned or read in and then printed (i.e. converted from base 10 to base 2 and back again).

 172 views

128⟩ What is the difference between memcpy and memmove?

memmove offers guaranteed behavior if the memory regions pointed to by the source and destination arguments overlap. memcpy makes no such guarantee, and may therefore be more efficiently implementable. When in doubt, it's safer to use memmove.

It seems simple enough to implement memmove; the overlap guarantee apparently requires only an additional test:

void *memmove(void *dest, void const *src, size_t n)

{

register char *dp = dest;

register char const *sp = src;

if(dp < sp) {

while(n-- > 0)

*dp++ = *sp++;

} else {

dp += n;

sp += n;

while(n-- >> 0)

*--dp = *--sp;

}

return dest;

}

The problem with this code is in that additional test: the comparison (dp < sp) is not quite portable (it compares two pointers which do not necessarily point within the same object) and may not be as cheap as it looks. On some machines (particularly segmented architectures), it may be tricky and significantly less efficient to implement.

 155 views

129⟩ How can I generate floating-point random numbers?

drand48 is a Unix System V routine which returns floating point random numbers (presumably with 48 bits of precision) in the half-open interval [0, 1). (Its companion seed routine is srand48; neither is in the C Standard.) It's easy to write a low-precision replacement:

#include <stdlib.h>

double drand48()

{

return rand() / (RAND_MAX + 1.); }

To more accurately simulate drand48's semantics, you can try to give it closer to 48 bits worth of precision:

#define PRECISION 2.82e14 /* 2**48, rounded up */

double drand48()

{

double x = 0;

double denom = RAND_MAX + 1.;

double need;

for(need = PRECISION; need > 1;

need /= (RAND_MAX + 1.)) {

x += rand() / denom;

denom *= RAND_MAX + 1.;

}

return x;

}

Before using code like this, though, beware that it is numerically suspect, particularly if (as is usually the case) the period of rand is on the order of RAND_MAX. (If you have a longer-period random number generator available, such as BSD random, definitely use it when simulating drand48.)

 194 views

130⟩ How can I retHow can I return a sequence of random numbers which dont repeat at all?

What you're looking for is often called a ``random permutation'' or ``shuffle.'' One way is to initialize an array with the values to be shuffled, then randomly interchange each of the cells with another one later in the array:

int a[10], i, nvalues = 10;

for(i = 0; i < nvalues; i++)

a[i] = i + 1;

for(i = 0; i < nvalues-1; i++) {

int c = randrange(nvalues-i);

int t = a[i]; a[i] = a[i+c]; a[i+c] = t; /* swap */

}

where randrange(N) is rand() / (RAND_MAX/(N) + 1)

 172 views

131⟩ How can I get random integers in a certain range?

The obvious way,

rand() % N /* POOR */

(which tries to return numbers from 0 to N-1) is poor, because the low-order bits of many random number generators are distressingly non-random.

A better method is something like

(int)((double)rand() / ((double)RAND_MAX + 1) * N)

If you'd rather not use floating point, another method is

rand() / (RAND_MAX / N + 1)

If you just need to do something with probability 1/N, you could use

if(rand() < (RAND_MAX+1u) / N)

All these methods obviously require knowing RAND_MAX (which ANSI #defines in <stdlib.h>), and assume that N is much less than RAND_MAX.

When N is close to RAND_MAX, and if the range of the random number generator is not a multiple of N (i.e. if (RAND_MAX+1) % N != 0), all of these methods break down: some outputs occur more often than others. (Using floating point does not help; the problem is that rand returns RAND_MAX+1 distinct values, which cannot always be evenly divvied up into N buckets.) If this is a problem, about the only thing you can do is to call rand multiple times, discarding certain values:

unsigned int x = (RAND_MAX + 1u) / N;

unsigned int y = x * N;

unsigned int r;

do {

r = rand();

} while(r >= y);

return r / x;

 174 views

132⟩ Did C have any Year 2000 problems?

No, although poorly-written C programs might have.

The tm_year field of struct tm holds the value of the year minus 1900; this field therefore contains the value 100 for the year 2000. Code that uses tm_year correctly (by adding or subtracting 1900 when converting to or from human-readable 4-digit year representations) has no problems at the turn of the millennium. Any code that used tm_year incorrectly, however, such as by using it directly as a human-readable 2-digit year, or setting it from a 4-digit year with code like

tm.tm_year = yyyy % 100; /* WRONG */

or printing it as an allegedly human-readable 4-digit year with code like

printf("19%d", tm.tm_year); /* WRONG */

would have had grave y2k problems indeed.

(The y2k problem is now mostly old history; all we have left to do is fix all the 32-bit time_t problems by 2038...)

 167 views

133⟩ How can I sort more data than will fit in memory?

You want an ``external sort,'' which you can read about in Knuth, Volume 3. The basic idea is to sort the data in chunks (as much as will fit in memory at one time), write each sorted chunk to a temporary file, and then merge the files. Your operating system may provide a general-purpose sort utility, and if so, you can try invoking it from within your program:

 174 views

134⟩ How can I sort a linked list?

Sometimes it's easier to keep the list in order as you build it (or perhaps to use a tree instead). Algorithms like insertion sort and merge sort lend themselves ideally to use with linked lists. If you want to use a standard library function, you can allocate a temporary array of pointers, fill it in with pointers to all your list nodes, call qsort, and finally rebuild the list pointers based on the sorted array.

 218 views

135⟩ How can I get the current date or time of day in a C program?

Just use the time, ctime, localtime and/or strftime functions. Here is a simple example:

#include <stdio.h>

#include <time.h>

int main()

{

time_t now;

time(&now);

printf("It's %s", ctime(&now));

return 0;

}

Calls to localtime and strftime look like this:

struct tm *tmp = localtime(&now);

char fmtbuf[30];

printf("It's %d:%02d:%02dn",

tmp->tm_hour, tmp->tm_min, tmp->tm_sec);

strftime(fmtbuf, sizeof fmtbuf, "%A, %B %d, %Y", tmp);

printf("on %sn", fmtbuf);

(Note that these functions take a pointer to the time_t variable, even when they will not be modifying it.

 188 views

136⟩ How can I split up a string into whitespace-separated fields?

How can I split up a string into whitespace-separated fields? How can I duplicate the process by which main() is handed argc and argv?

The only Standard function available for this kind of ``tokenizing'' is strtok, although it can be tricky to use and it may not do everything you want it to. (For instance, it does not handle quoting.) Here is a usage example, which simply prints each field as it's extracted:

#include <stdio.h>

#include <string.h>

char string[] = "this is a test"; /* not char *;

char *p;

for(p = strtok(string, " tn"); p != NULL;

p = strtok(NULL, " tn"))

printf(""%s"n", p);

As an alternative, here is a routine I use for building an argv all at once:

#include <ctype.h>

int makeargv(char *string, char *argv[], int argvsize)

{

char *p = string;

int i;

int argc = 0;

for(i = 0; i < argvsize; i++) {

/* skip leading whitespace */

while(isspace(*p))

p++;

if(*p != '')

argv[argc++] = p;

else {

argv[argc] = 0;

break;

}

/* scan over arg */

while(*p != '' && !isspace(*p))

p++;

/* terminate arg: */

if(*p != '' && i < argvsize-1)

*p++ = '';

}

return argc;

}

Calling makeargv is straightforward:

char *av[10];

int i, ac = makeargv(string, av, 10);

for(i = 0; i < ac; i++)

printf(""%s"n", av[i]);

 169 views

137⟩ Why do some versions of toupper act strangely if given an upper-case letter?

Why do some versions of toupper act strangely if given an upper-case letter? Why does some code call islower before toupper?

In earlier times, toupper was a function-like preprocessor macro and was defined to work only on lower-case letters; it misbehaved if applied to digits, punctuation, or letters which were already upper-case. Similarly, tolower worked only on upper-case letters. Therefore, old code (or code written for wide portability) tends to call islower before toupper, and isupper before tolower.

The C Standard, however, says that toupper and tolower must work correctly on all characters, i.e. characters which don't need changing are left alone.

 163 views

138⟩ How do I convert a string to all upper or lower case?

Some libraries have routines strupr and strlwr or strupper and strlower, but these are not Standard or portable. It's a straightforward exercise to write upper/lower-case functions in terms of the toupper and tolower macros in <ctype.h>;(The only tricky part is that the function will either have to modify the string in-place or deal with the problem of returning a new string;

(Note also that converting characters and strings to upper or lower case is vastly more complicated when multinational character sets are being used.)

 170 views

139⟩ why isnt it being handled properly?

I'm reading strings typed by the user into an array, and then printing them out later. When the user types a sequence like n, why isn't it being handled properly?

Character sequences like n are interpreted at compile time. When a backslash and an adjacent n appear in a character constant or string literal, they are translated immediately into a single newline character. (Analogous translations occur, of course, for the other character escape sequences.) When you're reading strings from the user or a file, however, no interpretation like this is performed: a backslash is read and printed just like any other character, with no particular interpretation.

(Some interpretation of the newline character may be done during run-time I/O, but for a completely different reason;

 166 views

140⟩ How can I read/write structures from/to data files?

It is relatively straightforward to write a structure out using fwrite:

fwrite(&somestruct, sizeof somestruct, 1, fp);

and a corresponding fread invocation can read it back in. What happens here is that fwrite receives a pointer to the structure, and writes (or fread correspondingly reads) the memory image of the structure as a stream of bytes. The sizeof operator determines how many bytes the structure occupies.

(The call to fwrite above is correct under an ANSI compiler as long as a prototype for fwrite is in scope, usually because <stdio.h> is #included.

However, data files written as memory images in this way will not be portable, particularly if they contain floating-point fields or pointers. The memory layout of structures is machine and compiler dependent. Different compilers may use different amounts of padding , and the sizes and byte orders of fundamental types vary across machines. Therefore, structures written as memory images cannot necessarily be read back in by programs running on other machines (or even compiled by other compilers), and this is an important concern if the data files you're writing will ever be interchanged between machines.

Also, if the structure contains any pointers (char * strings, or pointers to other data structures), only the pointer values will be written, and they are most unlikely to be valid when read back in.

 172 views