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

101⟩ Why does this code crash?

Why does this code:

char *p = "hello, world!";

p[0] = 'H';

crash?

String constants are in fact constant. The compiler may place them in nonwritable storage, and it is therefore not safe to modify them. When you need writable strings, you must allocate writable memory for them, either by declaring an array, or by calling malloc. Try

char a[] = "hello, world!";

By the same argument, a typical invocation of the old Unix mktemp routine

char *tmpfile = mktemp("/tmp/tmpXXXXXX");

is nonportable; the proper usage is

char tmpfile[] = "/tmp/tmpXXXXXX";

mktemp(tmpfile);

 177 views

102⟩ This program runs perfectly on one machine ...

This program runs perfectly on one machine, but I get weird results on another. Stranger still, adding or removing a debugging printout changes the symptoms.

Lots of things could be going wrong; here are a few of the more common things to check:

* uninitialized local variables

integer overflow, especially on 16-bit machines, especially of an intermediate result when doing things like a * b / c

* undefined evaluation order

* omitted declaration of external functions, especially those which return something other than int, or have ``narrow'' or variable arguments

* dereferenced null pointers

* improper malloc/free use: assuming malloc'ed memory contains 0, assuming freed storage persists, freeing something twice, corrupting the malloc arena

* pointer problems in general

* mismatch between printf format and arguments, especially trying to print long ints using %d

* trying to allocate more memory than an unsigned int can count, especially on machines with limited memory

* array bounds problems, especially of small, temporary buffers, perhaps used for constructing strings with sprintf

* invalid assumptions about the mapping of typedefs, especially size_t

* floating point problems

* anything you thought was a clever exploitation of the way you believe code is generated for your specific system

Proper use of function prototypes can catch several of these problems; lint would catch several more.

 170 views

103⟩ I have a program that seems to run correctly

I have a program that seems to run correctly, but it crashes as it's exiting, after the last statement in main(). What could be causing this?

There are at least three things to look for:

1. If a semicolon in a previous declaration is missing, main might be inadvertently declared as returning a structure, conflicting with the run-time startup code's expectations.

2. If setbuf or setvbuf is called, and if the supplied buffer is an automatic, local variable of main (or any function), the buffer may not exist any more by the time the stdio library tries to perform its final cleanup.

3. A cleanup function registered by atexit may have an error. Perhaps it is trying to reference data local to main or to some other function which no longer exists.

 177 views

104⟩ This program crashes before it even runs!

This program crashes before it even runs! (When single-stepping with a debugger, it dies before the first statement in main.)

You probably have one or more very large (kilobyte or more) local arrays. Many systems have fixed-size stacks, and even those which perform dynamic stack allocation automatically (e.g. Unix) can be confused when the stack tries to grow by a huge chunk all at once. It is often better to declare large arrays with static duration (unless of course you need a fresh set with each recursive call, in which case you could dynamically allocate them with malloc;

Other possibilities are that your program has been linked incorrectly (combining object modules compiled with different compilation options, or using improper dynamic libraries), or that run-time dynamic library linking is failing for some reason, or that you have somehow misdeclared main.

 170 views

106⟩ I am getting baffling syntax errors which make no sense at all

I'm getting baffling syntax errors which make no sense at all, and it seems like large chunks of my program aren't being compiled.

Check for unclosed comments, mismatched #if/#ifdef/#ifndef/#else/#endif directives, and perhaps unclosed quotes; remember to check header files, too.

 175 views

107⟩ Why is this loop always executing once?

Why is this loop always executing once?

for(i = start; i < end; i++);

{

printf("%dn", i);

}

The accidental extra semicolon hiding at the end of the line containing the for constitutes a null statement which is, as far as the compiler is concerned, the loop body. The following brace-enclosed block, which you thought (and the indentation suggests) was a loop body, is actually the next statement, and it is traversed exactly once, regardless of the number of loop iterations.

 172 views

108⟩ How can I call a function with an argument list built up at run time?

There is no guaranteed or portable way to do this.

Instead of an actual argument list, you might consider passing an array of generic (void *) pointers. The called function can then step through the array, much like main() might step through argv. (Obviously this works only if you have control over all the called functions.)

 173 views

109⟩ I cant get va_arg to pull in an argument of type pointer-to-function.

Try using a typedef for the function pointer type.

The type-rewriting games which the va_arg macro typically plays are stymied by overly-complicated types such as pointer-to-function. To illustrate, a simplified implementation of va_arg is

#define va_arg(argp, type)

(*(type *)(((argp) += sizeof(type)) - sizeof(type)))

where argp's type (va_list) is char *. When you attempt to invoke

va_arg(argp, int (*)())

the expansion is

(*(int (*)() *)(((argp) += sizeof(int (*)())) - sizeof(int (*)())))

which is a syntax error (the first cast (int (*)() *) is meaningless).

If you use a typedef for the function pointer type, however, all will be well. Given

typedef int (*funcptr)();

the expansion of

va_arg(argp, funcptr)

is

(*(funcptr *)(((argp) += sizeof(funcptr)) - sizeof(funcptr)))

which works correctly.

 179 views

110⟩ I have a varargs function which accepts a float parameter

I have a varargs function which accepts a float parameter. Why isn't

va_arg(argp, float)

working?

In the variable-length part of variable-length argument lists, the old ``default argument promotions'' apply: arguments of type float are always promoted (widened) to type double, and types char and short int are promoted to int. Therefore, it is never correct to invoke va_arg(argp, float); instead you should always use va_arg(argp, double). Similarly, use va_arg(argp, int) to retrieve arguments which were originally char, short, or int. (For analogous reasons, the last ``fixed'' argument, as handed to va_start, should not be widenable, either.)

 194 views

111⟩ My compiler isnt letting me declare a function

My compiler isn't letting me declare a function

int f(...)

{

}

i.e. accepting a variable number of arguments, but with no fixed arguments at all.

A: Standard C requires at least one fixed argument, in part so that you can hand it to va_start. (In any case, you often need a fixed argument to determine the number, and perhaps the types, of the variable arguments.)

 167 views

112⟩ How can I discover how many arguments a function was actually called with?

This information is not available to a portable program. Some old systems provided a nonstandard nargs function, but its use was always questionable, since it typically returned the number of words passed, not the number of arguments. (Structures, long ints, and floating point values are usually passed as several words.)

Any function which takes a variable number of arguments must be able to determine from the arguments themselves how many of them there are. printf-like functions do this by looking for formatting specifiers (%d and the like) in the format string (which is why these functions fail badly if the format string does not match the argument list). Another common technique, applicable when the arguments are all of the same type, is to use a sentinel value (often 0, -1, or an appropriately-cast null pointer) at the end of the list . Finally, if the types are predictable, you can pass an explicit count of the number of variable arguments (although it's usually a nuisance for the caller to supply).

 176 views

113⟩ How can I write a function analogous to scanf

How can I write a function analogous to scanf, i.e. that accepts similar arguments, and calls scanf to do most of the work?

C99 (but not any earlier C Standard) supports vscanf, vfscanf, and vsscanf.

 203 views

114⟩ How can I write a function that takes a format string and a variable number of arguments

How can I write a function that takes a format string and a variable number of arguments, like printf, and passes them to printf to do most of the work?

Use vprintf, vfprintf, or vsprintf. These routines are like their counterparts printf, fprintf, and sprintf, except that instead of a variable-length argument list, they accept a single va_list pointer.

As an example, here is an error function which prints an error message, preceded by the string ``error: '' and terminated with a newline:

#include <stdio.h>

#include <stdarg.h>

void error(const char *fmt, ...)

{

va_list argp;

fprintf(stderr, "error: ");

va_start(argp, fmt);

vfprintf(stderr, fmt, argp);

va_end(argp);

fprintf(stderr, "n"); }

 219 views

115⟩ I had a frustrating problem which turned out to be caused by the line

I had a frustrating problem which turned out to be caused by the line

printf("%d", n);

where n was actually a long int. I thought that ANSI function prototypes were supposed to guard against argument type mismatches like this.

When a function accepts a variable number of arguments, its prototype does not (and cannot) provide any information about the number and types of those variable arguments. Therefore, the usual protections do not apply in the variable-length part of variable-length argument lists: the compiler cannot perform implicit conversions or (in general) warn about mismatches. The programmer must make sure that arguments match, or must manually insert explicit casts.

In the case of printf-like functions, some compilers (including gcc) and some versions of lint are able to check the actual arguments against the format string, as long as the format string is an immediate string literal.

 174 views

116⟩ How can f be used for both float and double arguments in printf? Are not they different types?

In the variable-length part of a variable-length argument list, the ``default argument promotions'' apply: types char and short int are promoted to int, and float is promoted to double. (These are the same promotions that apply to function calls without a prototype in scope, also known as ``old style'' function calls. Therefore, printf's %f format always sees a double. (Similarly, %c always sees an int, as does %hd.)

 197 views

117⟩ I heard that you have to include stdio.h before calling printf. Why?

So that a proper prototype for printf will be in scope.

A compiler may use a different calling sequence for functions which accept variable-length argument lists. (It might do so if calls using variable-length argument lists were less efficient than those using fixed-length.) Therefore, a prototype (indicating, using the ellipsis notation ``...'', that the argument list is of variable length) must be in scope whenever a varargs function is called, so that the compiler knows to use the varargs calling mechanism.

 184 views

118⟩ I am having trouble with a Turbo C program which crashes

I'm having trouble with a Turbo C program which crashes and says something like ``floating point formats not linked.''

Some compilers for small machines, including Turbo C (and Ritchie's original PDP-11 compiler), leave out certain floating point support if it looks like it will not be needed. In particular, the non-floating-point versions of printf and scanf save space by not including code to handle %e, %f, and %g. It happens that Borland's heuristics for determining whether the program uses floating point are insufficient, and the programmer must sometimes insert a dummy call to a floating-point library function (such as sqrt; any will do) to force loading of floating-point support.

A partially-related problem, resulting in a similar error message (perhaps ``floating point not loaded'') can apparently occur under some MS-DOS compilers when an incorrect variant of the floating-point library is linked. Check your compiler manual's description of the various floating-point libraries.

 205 views

119⟩ What is a good way to implement complex numbers in C?

It is straightforward to define a simple structure and some arithmetic functions to manipulate them. C99 supports complex as a standard type. Here is a tiny example, to give you a feel for it:

typedef struct {

double real;

double imag;

} complex;

#define Real(c) (c).real

#define Imag(c) (c).imag

complex cpx_make(double real, double imag)

{

complex ret;

ret.real = real;

ret.imag = imag;

return ret;

}

complex cpx_add(complex a, complex b)

{

return cpx_make(Real(a) + Real(b), Imag(a) + Imag(b));

}

You can use these routines with code like

complex a = cpx_make(1, 2);

complex b = cpx_make(3, 4);

complex c = cpx_add(a, b);

or, even more simply,

complex c = cpx_add(cpx_make(1, 2), cpx_make(3, 4));

 230 views

120⟩ The predefined constant M_PI seems to be missing from my machines copy of math.h.

That constant (which is apparently supposed to be the value of pi, accurate to the machine's precision), is not standard; in fact a standard-conforming copy of should not #define a symbol M_PI. If you need pi, you'll have to define it yourself, or compute it with 4*atan(1.0) or acos(-1.0). (You could use a construction like

#ifndef M_PI

#define M_PI 3.1415926535897932385

#endif

to provide your own #definition only if some system header file has not.)

 181 views