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

1⟩ Suggesting that there can be 62 seconds in a minute?

Q: Why can tm_sec in the tm structure range from 0 to 61, suggesting that there can be 62 seconds in a minute?

A: That's actually a buglet in the Standard. There can be 61 seconds in a minute during a leap second. It's possible for there to be two leap seconds in a year, but it turns out that it's guaranteed that they'll never both occur in the same day (let alone the same minute).

 116 views

2⟩ How can I find the day of the week given the date?

Here are three methods:

1. Use mktime or localtime # . Here is a code fragment which computes the day of the week for February 29, 2000:

#include <stdio.h>

#include <time.h>

char *wday[] = {"Sunday", "Monday", "Tuesday", "Wednesday",

"Thursday", "Friday", "Saturday"};

struct tm tm;

tm.tm_mon = 2 - 1;

tm.tm_mday = 29;

tm.tm_year = 2000 - 1900;

tm.tm_hour = tm.tm_min = tm.tm_sec = 0;

tm.tm_isdst = -1;

if(mktime(&tm) != -1)

printf("%sn", wday[tm.tm_wday]);

When using mktime like this, it's usually important to set tm_isdst to -1, as shown (especially if tm_hour is 0), otherwise a daylight saving time correction could push the time past midnight into another day. # Use Zeller's congruence, which says that if

J is the number of the century [i.e. the year / 100],

K the year within the century [i.e. the year % 100],

m the month,

q the day of the month,

h the day of the week [where 1 is Sunday];

 113 views

3⟩ Was 2000 a leap year?

Is (year % 4 == 0) an accurate test for leap years? (Was 2000 a leap year?)

No, it's not accurate (and yes, 2000 was a leap year). The actual rules for the present Gregorian calendar are that leap years occur every four years, but not every 100 years, except that they do occur every 400 years, after all. In C, these rules can be expressed as:

year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)

Actually, if the domain of interest is limited (perhaps by the range of a time_t) such that the only century year it encompasses is 2000, the expression

(year % 4 == 0) /* 1901-2099 only */

is accurate, if less than robust.

If you trust the implementor of the C library, you can use mktime to determine whether a given year is a leap year;

Note also that the transition from the Julian to the Gregorian calendar involved deleting several days to make up for accumulated errors. (The transition was first made in Catholic countries under Pope Gregory XIII in October, 1582, and involved deleting 10 days. In the British Empire, eleven days were deleted when the Gregorian calendar was adopted in September 1752. A few countries didn't switch until the 20th century.) Calendar code which has to work for historical dates must therefore be especially careful.

 109 views

4⟩ Here is a good puzzle how do you write a program which produces its own source code as output?

It is actually quite difficult to write a self-reproducing program that is truly portable, due particularly to quoting and character set difficulties.

Here is a classic example (which ought to be presented on one line, although it will fix itself the first time it's run):

char*s="char*s=%c%s%c;main(){printf(s,34,s,34);}";

main(){printf(s,34,s,34);}

(This program has a few deficiencies, among other things neglecting to #include <stdio.h>, and assuming that the double-quote character " has the value 34, as it does in ASCII.)

#define q(k)main(){return!puts(#k"nq("#k")");}

q(#define q(k)main(){return!puts(#k"nq("#k")");})

 107 views

5⟩ What is Duffs Device?

It's a devastatingly devious way of unrolling a loop, devised by Tom Duff while he was at Lucasfilm. In its ``classic'' form, it was used to copy bytes, and looked like this: register n = (count + 7) / 8; /* count > 0 assumed */ switch (count % 8) { case 0: do { *to = *from++; case 7: *to = *from++; case 6: *to = *from++; case 5: *to = *from++; case 4: *to = *from++; case 3: *to = *from++; case 2: *to = *from++; case 1: *to = *from++; } while (--n > 0); }

where count bytes are to be copied from the array pointed to by from to the memory location pointed to by to (which is a memory-mapped device output register, which is why to isn't incremented). It solves the problem of handling the leftover bytes (when count isn't a multiple of 8) by interleaving a switch statement with the loop which copies bytes 8 at a time. (Believe it or not, it is legal to have case labels buried within blocks nested in a switch statement like this. In his announcement of the technique to C's developers and the world, Duff noted that C's switch syntax, in particular its ``fall through'' behavior, had long been controversial, and that ``This code forms some sort of argument in that debate, but I'm not sure whether it's for or against.'')

 105 views

6⟩ What is C language?

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

 89 views

7⟩ I need a sort of an approximate strcmp routine ...

I need a sort of an ``approximate'' strcmp routine, for comparing two strings for close, but not necessarily exact, equality.

Some nice information and algorithms having to do with approximate string matching, as well as a useful bibliography, can be found in Sun Wu and Udi Manber's paper ``AGREP--A Fast Approximate Pattern-Matching Tool.''

Another approach involves the ``soundex'' algorithm, which maps similar-sounding words to the same codes. Soundex was designed for discovering similar-sounding names (for telephone directory assistance, as it happens), but it can be pressed into service for processing arbitrary words.

 103 views

8⟩ What is hashing in C?

Hashing is the process of mapping strings to integers, usually in a relatively small range. A ``hash function'' maps a string (or some other data structure) to a bounded number (the ``hash bucket'') which can more easily be used as an index in an array, or for performing repeated comparisons. (Obviously, a mapping from a potentially huge set of strings to a small set of integers will not be unique. Any algorithm using hashing therefore has to deal with the possibility of ``collisions.'')

Many hashing functions and related algorithms have been developed; a full treatment is beyond the scope of this list. An extremely simple hash function for strings is simply to add up the values of all the characters:

unsigned hash(char *str)

{

unsigned int h = 0;

while(*str != '')

h += *str++;

return h % NBUCKETS;

}

A somewhat better hash function is

unsigned hash(char *str)

{

unsigned int h = 0;

while(*str != '')

h = (256 * h + *str++) % NBUCKETS;

return h;

}

 101 views

9⟩ What is C Programing language?

Is C++ a superset of C? What are the differences between C and C++? Can I use a C++ compiler to compile C code?

C++ was derived from C, and is largely based on it, but there are some legal C constructs which are not legal C++. Conversely, ANSI C inherited several features from C++, including prototypes and const, so neither language is really a subset or superset of the other; the two also define the meaning of some common constructs differently.

The most important feature of C++ not found in C is of course the extended structure known as a class which along with operator overloading makes object-oriented programming convenient. There are several other differences and new features: variables may be declared anywhere in a block; const variables may be true compile-time constants; structure tags are implicitly typedeffed; an & in a parameter declaration requests pass by reference; and the new and delete operators, along with per-object constructors and destructors, simplify dynamic data structure management. There are a host of mechanisms tied up with classes and object-oriented programming: inheritance, friends, virtual functions, templates, etc. (This list of C++ features is not intended to be complete; C++ programmers will notice many omissions.)

 92 views

10⟩ How can I convert integers to binary or hexadecimal?

Make sure you really know what you're asking. Integers are stored internally in binary, although for most purposes it is not incorrect to think of them as being in octal, decimal, or hexadecimal, whichever is convenient. The base in which a number is expressed matters only when that number is read in from or written out to the outside world, either in the form of a source code constant or in the form of I/O performed by a program.

In source code, a non-decimal base is indicated by a leading 0 or 0x (for octal or hexadecimal, respectively). During I/O, the base of a formatted number is controlled in the printf and scanf family of functions by the choice of format specifier (%d, %o, %x, etc.) and in the strtol and strtoul functions by the third argument. During binary I/O, however, the base again becomes immaterial: if numbers are being read or written as individual bytes (typically with getc or putc), or as multi-byte words (typically with fread or fwrite), it is meaningless to ask what ``base'' they are in.

If what you need is formatted binary conversion, it's easy enough to do. Here is a little function for formatting a number in a requested base:

 103 views

12⟩ What is the most efficient way to count the number of bits which are set in an integer?

Many ``bit-fiddling'' problems like this one can be sped up and streamlined using lookup tables (but see question 20.13). Here is a little function which computes the number of bits in a value, 4 bits at a time:

static int bitcounts[] =

{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};

int bitcount(unsigned int u)

{

int n = 0;

for(; u != 0; u >>= 4)

n += bitcounts[u & 0x0f];

return n;

}

 107 views

13⟩ I have been replacing multiplications and divisions with shift operators, because shifting is more efficient.

This is an excellent example of a potentially risky and usually unnecessary optimization. Any compiler worthy of the name can replace a constant, power-of-two multiplication with a left shift, or a similar division of an unsigned quantity with a right shift. Furthermore, a compiler will make these optimizations only when they're correct; many programmers overlook the fact that shifting a negative value to the right is not equivalent to division. (Therefore, when you need to make sure that these optimizations are performed, you may have to declare relevant variables as unsigned.)

 101 views

14⟩ What is the best way of making my program efficient?

By picking good algorithms, implementing them carefully, and making sure that your program isn't doing any extra work. For example, the most microoptimized character-copying loop in the world will be beat by code which avoids having to copy characters at all.

When worrying about efficiency, it's important to keep several things in perspective. First of all, although efficiency is an enormously popular topic, it is not always as important as people tend to think it is. Most of the code in most programs is not time-critical. When code is not time-critical, it is usually more important that it be written clearly and portably than that it be written maximally efficiently. (Remember that computers are very, very fast, and that seemingly ``inefficient'' code may be quite efficiently compilable, and run without apparent delay.)

It is notoriously difficult to predict what the ``hot spots'' in a program will be. When efficiency is a concern, it is important to use profiling software to determine which parts of the program deserve attention. Often, actual computation time is swamped by peripheral tasks such as I/O and memory allocation, which can be sped up by using buffering and caching techniques.

 96 views

15⟩ Are pointers really faster than arrays?

Are pointers really faster than arrays? How much do function calls slow things down? Is ++i faster than i = i + 1?

Precise answers to these and many similar questions depend of course on the processor and compiler in use. If you simply must know, you'll have to time test programs carefully. (Often the differences are so slight that hundreds of thousands of iterations are required even to see them.

For conventional machines, it is usually faster to march through large arrays with pointers rather than array subscripts, but for some processors the reverse is true. (Better compilers should generate good code regardless of which notation you use, though it's arguably easier for a compiler to convert array indices to pointers than vice versa .)

Function calls, though obviously incrementally slower than in-line code, contribute so much to modularity and code clarity that there is rarely good reason to avoid them. (Actually, by reducing bulk, functions can improve performance.) Also, some compilers are able to expand small, critical-path functions in-line, either as an optimization or at the programmer's request.

Before rearranging expressions such as i = i + 1, remember that you are dealing with a compiler, not a keystroke-programmable calculator. Any decent compiler will generate identical code for ++i, i += 1, and i = i + 1. The reasons for using ++i or i += 1 over i = i + 1 have to do with style, not efficiency.

 98 views

16⟩ How can I determine whether a machines byte order is big-endian or little-endian?

The usual techniques are to use a pointer:

int x = 1;

if(*(char *)&x == 1)

printf("little-endiann");

else printf("big-endiann");

or a union:

union {

int i;

char c[sizeof(int)];

} x;

x.i = 1;

if(x.c[0] == 1)

printf("little-endiann");

else printf("big-endiann");

(Note that there are also byte order possibilities beyond simple big-endian and little-endian

 121 views

17⟩ How can I swap two values without using a temporary?

The standard hoary old assembly language programmer's trick is:

a ^= b;

b ^= a;

a ^= b;

But this sort of code has little place in modern, HLL programming. Temporary variables are essentially free, and the idiomatic code using three assignments, namely

int t = a;

a = b;

b = t;

is not only clearer to the human reader, it is more likely to be recognized by the compiler and turned into the most-efficient code (e.g. perhaps even using an EXCH instruction). The latter code is obviously also amenable to use with pointers and floating-point values, unlike the XOR trick.

 100 views

18⟩ People claim that optimizing compilers are good and that we no longer have to write things in assembler for speed

People claim that optimizing compilers are good and that we no longer have to write things in assembler for speed, but my compiler can't even replace i/=2 with a shift.

Was i signed or unsigned? If it was signed, a shift is not equivalent (hint: think about the result if i is negative and odd), so the compiler was correct not to use it.

 98 views

19⟩ Which is more efficient, a switch statement or an if else chain?

The differences, if any, are likely to be slight. The switch statement was designed to be efficiently implementable, though the compiler may choose to use the equivalent of an if/else chain (as opposed to a compact jump table) if the case labels are sparsely distributed.

Do use switch when you can: it's certainly cleaner, and perhaps more efficient (and certainly should never be any less efficient).

 109 views

20⟩ Is there a way to switch on strings?

Not directly. Sometimes, it's appropriate to use a separate function to map strings to integer codes, and then switch on those:

#define CODE_APPLE 1

#define CODE_ORANGE 2

#define CODE_NONE 0

switch(classifyfunc(string)) {

case CODE_APPLE:

...

case CODE_ORANGE:

...

case CODE_NONE:

...

}

where classifyfunc looks something like

static struct lookuptab {

char *string;

int code;

} tab[] = {

{"apple", CODE_APPLE},

{"orange", CODE_ORANGE},

};

classifyfunc(char *string)

{

int i;

for(i = 0; i < sizeof(tab) / sizeof(tab[0]); i++)

if(strcmp(tab[i].string, string) == 0)

return tab[i].code;

return CODE_NONE;

}

Otherwise, of course, you can fall back on a conventional if/else chain:

if(strcmp(string, "apple") == 0) {

...

} else if(strcmp(string, "orange") == 0) {

...

}

 94 views