C Faq1
C Faq1
C Faq1
(The question numbers within each section are not always continuous,
because they are aligned with the aforementioned book-length version,
which contains even more questions.)
www.freshersparadise.com
size (usually the only good reason for doing so is when
attempting to conform to some externally-imposed storage layout,
but see question 20.5), be sure to encapsulate the choice behind
an appropriate typedef.
References: K&R1 Sec. 2.2 p. 34; K&R2 Sec. 2.2 p. 36, Sec. A4.2
pp. 195-6, Sec. B11 p. 257; ISO Sec. 5.2.4.2.1, Sec. 6.1.2.5;
H&S Secs. 5.1,5.2 pp. 110-114.
1.4: What should the 64-bit type on a machine that can support it?
1.7: What's the best way to declare and define global variables
and functions?
DEFINE(int, i);
need only be entered once in one header file, and turned into a
definition or a declaration depending on the setting of some
macro, but it's not clear if this is worth the trouble.
www.freshersparadise.com
declarations for you. In particular, never place a prototype
for an external function in a .c file: it wouldn't generally be
checked for consistency with the definition, and an incompatible
prototype is worse than useless.
References: K&R1 Sec. 4.5 pp. 76-7; K&R2 Sec. 4.4 pp. 80-1; ISO
Sec. 6.1.2.2, Sec. 6.7, Sec. 6.7.2, Sec. G.5.11; Rationale
Sec. 3.1.2.2; H&S Sec. 4.8 pp. 101-104, Sec. 9.2.3 p. 267; CT&P
Sec. 4.2 pp. 54-56.
and
int f();
References: K&R1 Sec. A8.1 p. 193; ISO Sec. 6.1.2.4, Sec. 6.5.1;
H&S Sec. 4.3 p. 75, Sec. 4.3.1 p. 76.
typedef struct {
char *item;
NODEPTR next;
} *NODEPTR;
struct node {
char *item;
struct node *next;
};
www.freshersparadise.com
and there are at least three other equivalently correct ways of
arranging it.
References: K&R1 Sec. 6.5 p. 101; K&R2 Sec. 6.5 p. 139; ISO
Sec. 6.5.2, Sec. 6.5.2.3; H&S Sec. 5.6.1 pp. 132-3.
1. char *(*(*a[N])())();
3. Use the cdecl program, which turns English into C and vice
versa:
www.freshersparadise.com
a generic function pointer, with some judicious casts to adjust
the types as the pointers are passed around; or have it return a
structure containing only a pointer to a function returning that
structure.
References: K&R1 Sec. 4.2 p. 70; K&R2 Sec. 4.2 p. 72; ISO
Sec. 6.3.2.2; H&S Sec. 4.7 p. 101.
References: K&R1 Sec. 4.9 pp. 82-4; K&R2 Sec. 4.9 pp. 85-86; ISO
Sec. 6.5.7, Sec. 7.10.3.1, Sec. 7.10.5.3; H&S Sec. 4.2.8 pp. 72-
3, Sec. 4.6 pp. 92-3, Sec. 4.6.2 pp. 94-5, Sec. 4.6.3 p. 96,
Sec. 16.1 p. 386.
www.freshersparadise.com
int f()
{
char a[] = "Hello, world!";
}
char *p = malloc(10);
References: K&R2 Sec. 5.5 p. 104; ISO Sec. 6.1.4, Sec. 6.5.7;
Rationale Sec. 3.1.4; H&S Sec. 2.7.4 pp. 31-2.
www.freshersparadise.com
An explicit declaration for the function is normally needed,
since implicit external function declaration does not happen in
this case (because the function name in the initialization is
not part of a function call).
struct x1 { ... };
typedef struct { ... } x2;
struct x { ... };
x thestruct;
work?
2.4: What's the best way of implementing opaque (abstract) data types
in C?
2.6: I came across some code that declared a structure like this:
struct name {
int namelen;
char namestr[1];
};
and then did some tricky allocation to make the namestr array
act like it had several elements. Is this legal or portable?
www.freshersparadise.com
Another possibility is to declare the variable-size element very
large, rather than very small; in the case of the above example:
...
char namestr[MAXSIZE];
A: What K&R1 said (though this was quite some time ago by now) was
that the restrictions on structure operations would be lifted
in a forthcoming version of the compiler, and in fact structure
assignment and passing were fully functional in Ritchie's
compiler even as K&R1 was being published. A few ancient C
compilers may have lacked these operations, but all modern
compilers support them, and they are part of the ANSI C
standard, so there should be no reluctance to use them.
References: K&R1 Sec. 6.2 p. 121; K&R2 Sec. 6.2 p. 129; ISO
Sec. 6.1.2.5, Sec. 6.2.2.1, Sec. 6.3.16; H&S Sec. 5.6.2 p. 133.
www.freshersparadise.com
A: As of this writing, C has no way of generating anonymous
structure values. You will have to use a temporary structure
variable or a little structure-building function.
2.13: Why does sizeof report a larger size than I expect for a
structure type, as if there were padding at the end?
www.freshersparadise.com
if necessary, to ensure that alignment properties will be
preserved when an array of contiguous structures is allocated.
Even when the structure is not part of an array, the end padding
remains, so that sizeof can always return a consistent size.
See also question 2.12 above.
offsetb = offsetof(struct a, b)
struct list {
char *item;
struct list *next;
}
main(argc, argv)
{ ... }
www.freshersparadise.com
References: CT&P Sec. 2.3 pp. 21-2.
References: K&R2 Sec. 6.8 pp. 148-9; ISO Sec. 6.5.7; C9X
Sec. 6.5.8; H&S Sec. 4.6.7 p. 100.
Section 3. Expressions
a[i] = i++;
work?
References: K&R1 Sec. 2.12; K&R2 Sec. 2.12; ISO Sec. 6.3; H&S
www.freshersparadise.com
Sec. 7.12 pp. 227-9.
int i = 7;
printf("%d\n", i++ * i++);
References: K&R1 Sec. 2.12 p. 50; K&R2 Sec. 2.12 p. 54; ISO
Sec. 6.3; H&S Sec. 7.12 pp. 227-9; CT&P Sec. 3.7 p. 47; PCS
Sec. 9.5 pp. 120-1.
int i = 3;
i = i++;
a ^= b ^= a ^= b
www.freshersparadise.com
twice between sequence points, so its behavior is undefined.
For example, it has been reported that when given the code
A: Not in general.
References: K&R1 Sec. 2.6 p. 38, Secs. A7.11-12 pp. 190-1; K&R2
Sec. 2.6 p. 41, Secs. A7.14-15 pp. 207-8; ISO Sec. 6.3.13,
Sec. 6.3.14, Sec. 6.3.15; H&S Sec. 7.7 pp. 217-8, Sec. 7.8 pp.
218-20, Sec. 7.12.1 p. 229; CT&P Sec. 3.7 pp. 46-7.
www.freshersparadise.com
most once by the evaluation of an expression.
Furthermore, the prior value shall be accessed
only to determine the value to be stored.
3.9: So given
a[i] = i++;
we don't know which cell of a[] gets written to, but i does get
incremented by one, right?
3.12: If I'm not using the value of the expression, should I use i++
or ++i to increment a variable?
A: Since the two forms differ only in the value yielded, they are
entirely equivalent when only their side effect is needed.
(However, the prefix form is preferred in C++.) See also
question 3.3.
References: K&R1 Sec. 2.8 p. 43; K&R2 Sec. 2.8 p. 47; ISO
Sec. 6.3.2.4, Sec. 6.3.3.1; H&S Sec. 7.4.4 pp. 192-3, Sec. 7.5.8
pp. 199-200.
work?
Note that (long int)(a * b) would *not* have the desired effect.
A similar problem can arise when two integers are divided, with
the result assigned to a floating-point variable; the solution
is similar, too.
References: K&R1 Sec. 2.7 p. 41; K&R2 Sec. 2.7 p. 44; ISO
www.freshersparadise.com
Sec. 6.2.1.5; H&S Sec. 6.3.4 p. 176; CT&P Sec. 3.9 pp. 49-50.
((condition) ? a : b) = complicated_expression;
Section 4. Pointers
4.2: I'm trying to declare a pointer and allocate some space for it,
but it's not working. What's wrong with this code?
char *p;
*p = malloc(10);
p = malloc(10);
It's when you're manipulating the pointed-to memory that you use
* as an indirection operator:
*p = 'H';
References: K&R1 Sec. 5.1 p. 91; K&R2 Sec. 5.1 p. 95; ISO
Sec. 6.3.2, Sec. 6.3.3; H&S Sec. 7.4.4 pp. 192-3, Sec. 7.5 p.
193, Secs. 7.5.7,7.5.8 pp. 199-200.
4.5: I have a char * pointer that happens to point to some ints, and
I want to step it over them. Why doesn't
((int *)p)++;
work?
www.freshersparadise.com
A: In C, a cast operator does not mean "pretend these bits have a
different type, and treat them accordingly"; it is a conversion
operator, and by definition it yields an rvalue, which cannot be
assigned to, or incremented with ++. (It is either an accident
or a delibrate but nonstandard extension if a particular
compiler accepts expressions such as the above.) Say what you
mean: use
p += sizeof(int);
int *ip;
f(ip);
A: Are you sure the function initialized what you thought it did?
Remember that arguments in C are passed by value. The called
function altered only the passed copy of the pointer. You'll
either want to pass the address of the pointer (the function
will end up accepting a pointer-to-a-pointer), or have the
function return the pointer.
www.freshersparadise.com
extern int f(int *);
f(&5);
int five = 5;
f(&five);
References: K&R1 Sec. 1.8 pp. 24-5, Sec. 5.2 pp. 91-3; K&R2
Sec. 1.8 pp. 27-8, Sec. 5.2 pp. 95-7; ISO Sec. 6.3.2.2; H&S
Sec. 9.5 pp. 273-4.
4.12: I've seen different methods used for calling functions via
pointers. What's the story?
r = fp();
www.freshersparadise.com
References: K&R1 Sec. 5.12 p. 116; K&R2 Sec. 5.11 p. 120; ISO
Sec. 6.3.2.2; Rationale Sec. 3.3.2.2; H&S Sec. 5.8 p. 147,
Sec. 7.4.3 p. 190.
A: The language definition states that for each pointer type, there
is a special value -- the "null pointer" -- which is
distinguishable from all other pointer values and which is
"guaranteed to compare unequal to a pointer to any object or
function." That is, the address-of operator & will never yield
a null pointer, nor will a successful call to malloc().
(malloc() does return a null pointer when it fails, and this is
a typical use of null pointers: as a "special" pointer value
with some other meaning, usually "not allocated" or "not
pointing anywhere yet.")
References: K&R1 Sec. 5.4 pp. 97-8; K&R2 Sec. 5.4 p. 102; ISO
Sec. 6.2.2.3; Rationale Sec. 3.2.2.3; H&S Sec. 5.3.2 pp. 121-3.
char *p = 0;
if(p != 0)
www.freshersparadise.com
execl("/bin/sh", "sh", "-c", "date", (char *)0);
Summary:
function call,
prototype in scope,
fixed argument
if(expr)
if((expr) != 0)
www.freshersparadise.com
for both constructs. The internal representation of a null
pointer does *not* matter.
References: K&R1 Sec. 5.4 pp. 97-8; K&R2 Sec. 5.4 p. 102; ISO
Sec. 7.1.6, Sec. 6.2.2.3; Rationale Sec. 4.1.5; H&S Sec. 5.3.2
p. 122, Sec. 11.1 p. 292.
5.5: How should NULL be defined on a machine which uses a nonzero bit
pattern as the internal representation of a null pointer?
www.freshersparadise.com
References: ISO Sec. 7.1.6; Rationale Sec. 4.1.5.
could fail.
if you must.
www.freshersparadise.com
References: K&R1 Sec. 5.4 pp. 97-8; K&R2 Sec. 5.4 p. 102.
5.10: But wouldn't it be better to use NULL (rather than 0), in case
the value of NULL changes, perhaps on a machine with nonzero
internal null pointers?
A: No. (Using NULL may be preferable, but not for this reason.)
Although symbolic constants are often used in place of numbers
because the numbers might change, this is *not* the reason that
NULL is used in place of 0. Once again, the language guarantees
that source-code 0's (in pointer contexts) generate null
pointers. NULL is used only as a stylistic convention. See
questions 5.5 and 9.2.
5. The ASCII null character (NUL), which does have all bits
zero, but has no necessary relation to the null pointer
except in name; and...
This article uses the phrase "null pointer" (in lower case) for
sense 1, the character "0" or the phrase "null pointer constant"
for sense 3, and the capitalized word "NULL" for sense 4.
www.freshersparadise.com
5.14: Why is there so much confusion surrounding null pointers? Why
do these questions come up so often?
5.15: I'm confused. I just can't understand all this null pointer
stuff.
www.freshersparadise.com
of the internal representation, whether zero or nonzero.
Assuming that null pointers are internally zero does not make
any code easier to write (except for a certain ill-advised usage
of calloc(); see question 7.31). Known-zero internal pointers
would not obviate casts in function calls, because the *size* of
the pointer might still be different from that of an int. (If
"nil" were used to request null pointers, as mentioned in
question 5.14 above, the urge to assume an internal zero
representation would not even arise.)
5.17: Seriously, have any actual machines really used nonzero null
pointers, or different representations for pointers to different
types?
A: The Prime 50 series used segment 07777, offset 0 for the null
pointer, at least for PL/I. Later models used segment 0, offset
0 for null pointers in C, necessitating new instructions such as
TCNP (Test C Null Pointer), evidently as a sop to all the extant
poorly-written C code which made incorrect assumptions. Older,
word-addressed Prime machines were also notorious for requiring
larger byte pointers (char *'s) than word pointers (int *'s).
www.freshersparadise.com
that you've written, via a null (perhaps because uninitialized)
pointer, to an invalid location (probably offset 0 in the
default data segment).
6.1: I had the definition char a[6] in one source file, and in
another I declared extern char *a. Why didn't it work?
References: ISO Sec. 6.5.4.2; CT&P Sec. 3.3 pp. 33-4, Sec. 4.5
pp. 64-5.
6.2: But I heard that char a[] was identical to char *a.
www.freshersparadise.com
three places past (the start of) the object *named* a, while
p[3] is three places past the object *pointed to* by p. In the
example above, both a[3] and p[3] happen to be the character
'l', but the compiler gets there differently. (The essential
difference is that the values of an array like a and a pointer
like p are computed differently *whenever* they appear in
expressions, whether or not they are being subscripted, as
explained further in the next question.)
References: K&R2 Sec. 5.5 p. 104; CT&P Sec. 4.5 pp. 64-5.
p = a;
References: K&R1 Sec. 5.3 pp. 93-6; K&R2 Sec. 5.3 p. 99; ISO
Sec. 6.2.2.1, Sec. 6.3.2.1, Sec. 6.3.6; H&S Sec. 5.4.1 p. 124.
www.freshersparadise.com
actually passed to a function. Allowing pointer parameters to
be declared as arrays is a simply a way of making it look as
though an array was being passed, perhaps because the parameter
will be used within the function as if it were an array.
Specifically, any parameter declarations which "look like"
arrays, e.g.
www.freshersparadise.com
*not* a pointer, as the discussion and pictures in question 6.2
should make clear. See also questions 6.3 and 6.8.
A: The type.
www.freshersparadise.com
A: The equivalence between arrays and pointers (see question 6.3)
allows a pointer to malloc'ed memory to simulate an array
quite effectively. After executing
#include <stdlib.h>
int *dynarray;
dynarray = malloc(10 * sizeof(int));
#include <stdlib.h>
www.freshersparadise.com
array with a single, dynamically-allocated one-dimensional
array:
but the syntax starts getting horrific and at most one dimension
may be specified at run time.
int realarray[10];
int *array = &realarray[-1];
References: K&R2 Sec. 5.3 p. 100, Sec. 5.4 pp. 102-3, Sec. A7.7
pp. 205-6; ISO Sec. 6.3.6; Rationale Sec. 3.2.2.3.
A: The rule (see question 6.3) by which arrays decay into pointers
is not applied recursively. An array of arrays (i.e. a two-
www.freshersparadise.com
dimensional array in C) decays into a pointer to an array, not a
pointer to a pointer. Pointers to arrays can be confusing, and
must be treated carefully; see also question 6.13.
int array[NROWS][NCOLUMNS];
f(array);
or
References: K&R1 Sec. 5.10 p. 110; K&R2 Sec. 5.9 p. 113; H&S
Sec. 5.4.3 p. 126.
This function could be called with the array from question 6.18
as
www.freshersparadise.com
accept C9X's extensions become widespread, this will probably
become the preferred solution. (gcc has supported variable-
sized arrays for some time.)
int array[NROWS][NCOLUMNS];
int **array1; /* ragged */
int **array2; /* contiguous */
int *array3; /* "flattened" */
int (*array4)[NCOLUMNS];
www.freshersparadise.com
equivalently, *array) to f2() is not strictly conforming; see
question 6.19.
If you can understand why all of the above calls work and are
written as they are, and if you understand why the combinations
that are not listed would not work, then you have a *very* good
understanding of arrays and pointers in C.
6.21: Why doesn't sizeof properly report the size of an array when the
array is a parameter to a function?
char *answer;
printf("Type something:\n");
gets(answer);
printf("You typed \"%s\"\n", answer);
#include <stdio.h>
#include <string.h>
www.freshersparadise.com
possible to use malloc() to allocate the answer buffer.
7.3: But the man page for strcat() says that it takes two char *'s as
arguments. How am I supposed to know to allocate things?
char *p;
strcpy(p, "abc");
www.freshersparadise.com
and it worked. How? Why didn't it crash?
char *p;
you (or, more properly, the compiler) have allocated only enough
memory to hold the pointer itself; that is, in this case you
have allocated sizeof(char *) bytes of memory. But you have
not yet allocated *any* memory for the pointer to point to.
See also questions 7.1 and 7.2.
char *itoa(int n)
{
char retbuf[20]; /* WRONG */
sprintf(retbuf, "%d", n);
return retbuf; /* WRONG */
}
www.freshersparadise.com
7.7: Why does some code carefully cast the values returned by malloc
to the pointer type being allocated?
7.14: I've heard that some operating systems don't actually allocate
malloc'ed memory until the program tries to use it. Is this
legal?
A: It's hard to say. The Standard doesn't say that systems can act
this way, but it doesn't explicitly say that they can't, either.
7.16: I'm allocating a large array for some numeric work, using the
line
A: Notice that 300 x 300 is 90,000, which will not fit in a 16-bit
int, even before you multiply it by sizeof(double). If you
need to allocate this much memory, you'll have to be careful.
If size_t (the type accepted by malloc()) is a 32-bit type on
your machine, but int is 16 bits, you might be able to get away
with writing 300 * (300 * sizeof(double)) (see question 3.14).
Otherwise, you'll have to break your data structure up into
smaller chunks, or use a 32-bit machine or compiler, or use
some nonstandard memory allocation functions. See also
www.freshersparadise.com
question 19.23.
7.17: I've got 8 meg of memory in my PC. Why can I only seem to
malloc 640K or so?
7.20: You can't use dynamically-allocated memory after you free it,
can you?
www.freshersparadise.com
A pointer value which has been freed is, strictly speaking,
invalid, and *any* use of it, even if is not dereferenced, can
theoretically lead to trouble, though as a quality of
implementation issue, most implementations will probably not go
out of their way to generate exceptions for innocuous uses of
invalid pointers.
7.25: I have a program which mallocs and later frees a lot of memory,
but I can see from the operating system that memory usage
doesn't actually go back down.
7.27: So can I query the malloc package to find out how big an
allocated block is?
www.freshersparadise.com
A: Unfortunately, there is no standard or portable way.
p = malloc(m * n);
memset(p, 0, m * n);
strcat(string, '!');
work?
www.freshersparadise.com
A: There is a very real difference between characters and strings,
and strcat() concatenates *strings*.
strcat(string, "!");
char *string;
...
if(string == "value") {
/* string matches "value" */
...
}
if(strcmp(string, "value") == 0) {
/* string matches "value" */
...
}
char a[14];
a = "Hello, world!";
A: Strings are arrays, and you can't assign arrays directly. Use
strcpy() instead:
8.6: How can I get the numeric (character set) value corresponding to
a character, or vice versa?
www.freshersparadise.com
A: In C, characters are represented by small integers corresponding
to their values (in the machine's character set), so you don't
need a conversion function: if you have the character, you have
its value.
9.1: What is the right type to use for Boolean values in C? Why
isn't it a standard type? Should I use #defines or enums for
the true and false values?
These don't buy anything (see question 9.2 below; see also
questions 5.12 and 10.2).
www.freshersparadise.com
but this applies only "on input", i.e. where a Boolean value is
expected. When a Boolean value is generated by a built-in
operator, it is guaranteed to be 1 or 0. Therefore, the test
if((a == b) == TRUE)
Although the use of macros like TRUE and FALSE (or YES
and NO) seems clearer, Boolean values and definitions can
be sufficiently confusing in C that some programmers feel
that TRUE and FALSE macros only compound the confusion, and
prefer to use raw 1 and 0 instead. (See also question 5.9.)
References: K&R1 Sec. 2.6 p. 39, Sec. 2.7 p. 41; K&R2 Sec. 2.6
p. 42, Sec. 2.7 p. 44, Sec. A7.4.7 p. 204, Sec. A7.9 p. 206; ISO
Sec. 6.3.3.3, Sec. 6.3.8, Sec. 6.3.9, Sec. 6.3.13, Sec. 6.3.14,
Sec. 6.3.15, Sec. 6.6.4.1, Sec. 6.6.5; H&S Sec. 7.5.4 pp. 196-7,
Sec. 7.6.4 pp. 207-8, Sec. 7.6.5 pp. 208-9, Sec. 7.7 pp. 217-8,
Sec. 7.8 pp. 218-9, Sec. 8.5 pp. 238-9, Sec. 8.6 pp. 241-4;
"What the Tortoise Said to Achilles".
#define begin {
#define end }
www.freshersparadise.com
use a temporary, since it does not know what type of temporary
it needs (and would have a hard time picking a name for it if
it did), and standard C does not provide a typeof operator.
References: H&S Sec. 3.3.2 p. 45; CT&P Sec. 6.3 pp. 82-3.
10.6: I'm splitting up a program into multiple source files for the
first time, and I'm wondering what to put in .c files and what
to put in .h files. (What does ".h" mean, anyway?)
www.freshersparadise.com
On the other hand, when a definition or declaration should
remain private to one .c file, it's fine to leave it there.
References: K&R2 Sec. 4.5 pp. 81-2; H&S Sec. 9.2.3 p. 267; CT&P
Sec. 4.6 pp. 66-7.
#ifndef HFILENAME_USED
#define HFILENAME_USED
...header file contents...
#endif
10.8a: What's the difference between #include <> and #include "" ?
10.8b: What are the complete rules for header file searching?
References: K&R2 Sec. A12.4 p. 231; ISO Sec. 6.8.2; H&S Sec. 3.4
www.freshersparadise.com
p. 55.
10.9: I'm getting strange syntax errors on the very first declaration
in a file, but it looks fine.
10.10b: I'm #including the right header file for the library function
I'm using, but the linker keeps saying it's undefined.
References: ISO Sec. 6.8.3, Sec. 6.8.3.4; H&S Sec. 3.2 pp. 40-1.
www.freshersparadise.com
A: Unfortunately, no. You may have to keep sets of preprocessor
macros (e.g. MY_TYPE_DEFINED) recording whether certain typedefs
have been declared. (See also question 10.13.)
10.18: I inherited some code which contains far too many #ifdef's for
my taste. How can I preprocess the code to leave only one
conditional compilation set, without running it through the
preprocessor and expanding all of the #include's and #define's
as well?
10.20: I have some old code that tries to construct identifiers with a
macro like
www.freshersparadise.com
Sec. 3.3.9 p. 52.
TRACE(count);
as
printf("TRACE: %d\count", count);
DEBUG("i = %d" _ i)
www.freshersparadise.com
C9X will introduce formal support for function-like macros with
variable-length argument lists. The notation ... will appear at
the end of the macro "prototype" (just as it does for varargs
functions), and the pseudomacro __VA_ARGS__ in the macro
definition will be replaced by the variable arguments during
invocation.
www.freshersparadise.com
A: Copies are available in the United States from
and
ISO Sales
Case Postale 56
CH-1211 Geneve 20
Switzerland
The last time I checked, the cost was $130.00 from ANSI or
$400.50 from Global. Copies of the original X3.159 (including
the Rationale) may still be available at $205.00 from ANSI or
$162.50 from Global. Note that ANSI derives revenues to support
its operations from the sale of printed standards, so electronic
copies are *not* available.
www.freshersparadise.com
Public review drafts of C9X are available from ISO/IEC
JTC1/SC22/WG14's web site, http://www.dkuug.dk/JTC1/SC22/WG14/ .
int func(x)
float x;
{ ...
References: K&R1 Sec. A7.1 p. 186; K&R2 Sec. A7.3.2 p. 202; ISO
Sec. 6.3.2.2, Sec. 6.5.4.3; Rationale Sec. 3.3.2.2,
Sec. 3.5.4.3; H&S Sec. 9.2 pp. 265-7, Sec. 9.4 pp. 272-3.
www.freshersparadise.com
(The old-style syntax is marked as obsolescent, so official
support for it may be removed some day.)
References: ISO Sec. 6.7.1, Sec. 6.9.5; H&S Sec. 9.2.2 pp. 265-
7, Sec. 9.2.5 pp. 269-70.
struct x;
const int n = 5;
int a[n];
A: "const char *p" (which can also be written "char const *p")
declares a pointer to a constant character (you can't change
the character); "char * const p" declares a constant pointer
to a (variable) character (i.e. you can't change the pointer).
www.freshersparadise.com
const char **?
You must use explicit casts (e.g. (const char **) in this case)
when assigning (or passing) pointers which have qualifier
mismatches at other than the first level of indirection.
11.14: I believe that declaring void main() can't fail, since I'm
calling exit() instead of returning, and anyway my operating
system ignores a program's exit/return status.
www.freshersparadise.com
A: It doesn't matter whether main() returns or not, or whether
anyone looks at the status; the problem is that when main() is
misdeclared, its caller (the runtime startup code) may not even
be able to *call* it correctly (due to the potential clash of
calling conventions; see question 11.12b).
11.15: The book I've been using, _C Programing for the Compleat Idiot_,
always uses void main().
A: Yes and no. The Standard says that they are equivalent.
However, a return from main() cannot be expected to work if
data local to main() might be needed during cleanup; see also
question 16.4. A few very old, nonconforming systems may once
have had problems with one or the other form. (Finally, the
two forms are obviously not equivalent in a recursive call to
main().)
#define Str(x) #x
#define Xstr(x) Str(x)
#define OP plus
char *opname = Xstr(OP);
www.freshersparadise.com
definitions like
TRACE(i, %d);
were expanded as
11.19: I'm getting strange syntax errors inside lines I've #ifdeffed
out.
References: ISO Sec. 5.1.1.2, Sec. 6.1; H&S Sec. 3.2 p. 40.
11.20: What are #pragmas and what are they good for?
11.21: What does "#pragma once" mean? I found it in some header files.
www.freshersparadise.com
A: It is legal in ANSI C (and perhaps in a few pre-ANSI systems),
though useful only in rare circumstances. It declares an array
of size three, initialized with the three characters 'a', 'b',
and 'c', *without* the usual terminating '\0' character. The
array is therefore not a true C string and cannot be used with
strcpy, printf %s, etc.
Most of the time, you should let the compiler count the
initializers when initializing arrays (in the case of the
initializer "abc", of course, the computed size will be 4).
References: ISO Sec. 6.1.2.5, Sec. 6.3.6; H&S Sec. 7.6.2 p. 204.
11.27: Why does the ANSI Standard not guarantee more than six case-
insensitive characters of external identifier significance?
www.freshersparadise.com
See also questions 1.31, 10.9, 11.30, and 16.1b.
11.32: Why won't the Frobozz Magic C Compiler, which claims to be ANSI
compliant, accept this code? I know that the code is ANSI,
because gcc accepts it.
www.freshersparadise.com
A: Briefly: implementation-defined means that an implementation
must choose some behavior and document it. Unspecified means
that an implementation should choose some behavior, but need not
document it. Undefined means that absolutely anything might
happen. In no case does the Standard impose requirements; in
the first two cases it occasionally suggests (and may require a
choice from among) a small set of likely behaviors.
11.34: I'm appalled that the ANSI Standard leaves so many issues
undefined. Isn't a Standard's whole job to standardize these
things?
www.freshersparadise.com
unspecified behavior), including doing what you expect. It's
unwise to depend on it, though. See also questions 11.32,
11.33, and 11.34.
char c;
while((c = getchar()) != EOF) ...
A: For one thing, the variable to hold getchar's return value must
be an int. getchar() can return all possible character values,
as well as EOF. By squeezing getchar's return value into a
char, either a normal character might be misinterpreted as EOF,
or the EOF might be altered (particularly if type char is
unsigned) and so never seen.
References: K&R1 Sec. 1.5 p. 14; K&R2 Sec. 1.5.1 p. 16; ISO
Sec. 6.1.2.5, Sec. 7.9.1, Sec. 7.9.7.5; H&S Sec. 5.1.3 p. 116,
Sec. 15.1, Sec. 15.6; CT&P Sec. 5.1 p. 70; PCS Sec. 11 p. 157.
while(!feof(infp)) {
fgets(buf, MAXLINE, infp);
fputs(buf, outfp);
}
References: K&R2 Sec. 7.6 p. 164; ISO Sec. 7.9.3, Sec. 7.9.7.1,
Sec. 7.9.10.2; H&S Sec. 15.14 p. 382.
12.5: How can I read one character at a time, without waiting for the
RETURN key?
www.freshersparadise.com
tried \%, but it didn't work.
References: K&R1 Sec. 7.3 p. 147; K&R2 Sec. 7.2 p. 154; ISO
Sec. 7.9.6.1.
12.9: Someone told me it was wrong to use %lf with printf(). How can
printf() use %f for type double, if scanf() requires %lf?
A: It's true that printf's %f specifier works with both float and
double arguments. Due to the "default argument promotions"
(which apply in variable-length argument lists such as
printf's, whether or not prototypes are in scope), values of
type float are promoted to double, and printf() therefore sees
only doubles. (printf() does accept %Lf, for long double.)
See also questions 12.13 and 15.2.
References: K&R1 Sec. 7.3 pp. 145-47, Sec. 7.4 pp. 147-50; K&R2
Sec. 7.2 pp. 153-44, Sec. 7.4 pp. 157-59; ISO Sec. 7.9.6.1,
Sec. 7.9.6.2; H&S Sec. 15.8 pp. 357-64, Sec. 15.11 pp. 366-78;
CT&P Sec. A.1 pp. 121-33.
12.9b: What printf format should I use for a typedef like size_t
when I don't know whether it's long or some other type?
References: K&R1 Sec. 7.3; K&R2 Sec. 7.2; ISO Sec. 7.9.6.1; H&S
Sec. 15.11.6; CT&P Sec. A.1.
12.11: How can I print numbers with commas separating the thousands?
What about currency formatted numbers?
www.freshersparadise.com
A: The arguments you pass to scanf() must always be pointers.
To fix the fragment above, change it to scanf("%d", &i) .
double d;
scanf("%f", &d);
work?
A: Unlike printf(), scanf() uses %lf for values of type double, and
%f for float. See also question 12.9.
12.17: When I read numbers from the keyboard with scanf "%d\n", it
seems to hang until I type one extra line of input.
References: K&R2 Sec. B1.3 pp. 245-6; ISO Sec. 7.9.6.2; H&S
Sec. 15.8 pp. 357-64.
12.18: I'm reading a number with scanf %d and then a string with
gets(), but the compiler seems to be skipping the call to
gets()!
www.freshersparadise.com
immediately reencounter the same `x'.
12.20: Why does everyone say not to use scanf()? What should I use
instead?
12.21: How can I tell how much destination buffer space I'll need for
an arbitrary sprintf call? How can I avoid overflowing the
destination buffer with sprintf()?
A: When the format string being used with sprintf() is known and
relatively simple, you can sometimes predict a buffer size in an
ad-hoc way. If the format consists of one or two %s's, you can
count the fixed characters in the format string yourself (or let
sizeof count them for you) and add in the result of calling
strlen() on the string(s) to be inserted. For integers, the
number of characters produced by %d is no more than
If there's any chance that the buffer might not be big enough,
you won't want to call sprintf() without some guarantee that the
www.freshersparadise.com
buffer will not overflow and overwrite some other part of
memory. If the format string is known, you can limit %s
expansion by using %.Ns for some N, or %.*s (see also question
12.10).
References: ISO Sec. 7.1.4, Sec. 7.9.10.3; CT&P Sec. 5.4 p. 73;
PCS Sec. 14 p. 254.
www.freshersparadise.com
represent the offsets. The type behind this typedef, if chosen
appropriately, can represent arbitrarily large offsets, so
fgetpos() and fsetpos() can be used with arbitrarily huge files.
fgetpos() and fsetpos() also record the state associated with
multibyte streams. See also question 1.4.
12.26: How can I flush pending input so that a user's typeahead isn't
read at the next prompt? Will fflush(stdin) work?
12.30: I'm trying to update a file in place, by using fopen mode "r+",
reading a certain string, and writing back a modified string,
but it's not working.
A: Be sure to call fseek before you write, both to seek back to the
beginning of the string you're trying to overwrite, and because
an fseek or fflush is always required between reading and
writing in the read/write "+" modes. Also, remember that you
can only overwrite characters with the same number of
replacement characters, and that overwriting in text mode may
truncate the file at that point. See also question 19.14.
12.34: Once I've used freopen(), how can I get the original stdout (or
stdin) back?
A: There isn't a good way. If you need to switch back, the best
solution is not to have used freopen() in the first place. Try
using your own explicit output (or input) stream variable, which
you can reassign at will, while leaving the original stdout (or
stdin) undisturbed.
www.freshersparadise.com
such as dup(), or copying or inspecting the contents of a FILE
structure, which is exceedingly nonportable and unreliable.
12.38: How can I read a binary data file properly? I'm occasionally
seeing 0x0a and 0x0d values getting garbled, and I seem to hit
EOF prematurely if the data contains the value 0x1a.
A: When you're reading a binary data file, you should specify "rb"
mode when calling fopen(), to make sure that text file
translations do not occur. Similarly, when writing binary data
files, use "wb".
Note that the text/binary distinction is made when you open the
file: once a file is open, it doesn't matter which I/O calls you
use on it. See also question 20.5.
13.2: Why does strncpy() not always place a '\0' terminator in the
destination string?
www.freshersparadise.com
upper-case letter?
Why does some code call islower() before toupper()?
References: ISO Sec. 7.3.2; H&S Sec. 12.9 pp. 320-1; PCS p. 182.
www.freshersparadise.com
char. Therefore, strcmp() can't be used directly. Write an
intermediate comparison function like this:
www.freshersparadise.com
list pointers based on the sorted array.
References: Knuth Sec. 5.2.1 pp. 80-102, Sec. 5.2.4 pp. 159-168;
Sedgewick Sec. 8 pp. 98-100, Sec. 12 pp. 163-175.
13.11: How can I sort more data than will fit in memory?
A: 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: see questions 19.27
and 19.30.
13.12: How can I get the current date or time of day in a C program?
#include <stdio.h>
#include <time.h>
int main()
{
time_t now;
time(&now);
printf("It's %.24s.\n", ctime(&now));
return 0;
}
References: K&R2 Sec. B10 pp. 255-7; ISO Sec. 7.12; H&S Sec. 18.
13.14: How can I add N days to a date? How can I find the difference
between two dates?
www.freshersparadise.com
normalized dates, so it is straightforward to take a filled-in
struct tm, add or subtract from the tm_mday field, and call
mktime() to normalize the year, month, and day fields (and
incidentally convert to a time_t value). difftime() computes
the difference, in seconds, between two time_t values; mktime()
can be used to compute time_t values for two dates to be
subtracted.
The tm_year field of struct tm holds the value of the year minus
1900; this field will therefore contain 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) will have no problems at the turn
of the millennium. Any code that uses 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
will have grave y2k problems indeed. See also question 20.32.
References: K&R2 Sec. B10 p. 255; ISO Sec. 7.12.1; H&S Sec. 18.4
p. 401.
www.freshersparadise.com
net: look for r250, RANLIB, and FSULTRA (see question 18.16).
rand() % N /* POOR */
(int)((double)rand() / ((double)RAND_MAX + 1) * N)
rand() / (RAND_MAX / N + 1)
13.17: Each time I run my program, I get the same sequence of numbers
back from rand().
www.freshersparadise.com
the low-order bits. Try using the higher-order bits: see
question 13.16.
#include <stdlib.h>
#include <math.h>
double gaussrand()
{
static double V1, V2, S;
static int phase = 0;
double X;
if(phase == 0) {
do {
double U1 = (double)rand() / RAND_MAX;
double U2 = (double)rand() / RAND_MAX;
V1 = 2 * U1 - 1;
V2 = 2 * U2 - 1;
S = V1 * V1 + V2 * V2;
} while(S >= 1 || S == 0);
phase = 1 - phase;
return X;
}
See the extended versions of this list (see question 20.40) for
other ideas.
www.freshersparadise.com
References: PCS Sec. 11.
A: Many linkers make one pass over the list of object files and
libraries you specify, and extract from libraries only those
modules which satisfy references which have so far come up as
undefined. Therefore, the order in which libraries are listed
with respect to object files (and each other) is significant;
usually, you want to search the libraries last. (For example,
under Unix, put any -l options towards the end of the command
line.) See also question 13.28.
13.28: What does it mean when the linker says that _end is undefined?
14.1: When I set a float variable to, say, 3.1, why is printf printing
it as 3.0999999?
14.2: I'm trying to take some square roots, but I'm getting crazy
numbers.
www.freshersparadise.com
14.3: I'm trying to do some simple trig, and I am #including <math.h>,
but I keep getting "undefined: sin" compilation errors.
A: Make sure you're actually linking with the math library. For
instance, under Unix, you usually need to use the -lm option, at
the *end* of the command line, when compiling/linking. See also
questions 13.25, 13.26, and 14.2.
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" (see also
question 11.34), otherwise a compiler for a machine without the
"right" model would have to do prohibitively expensive
emulations.
double a, b;
...
if(a == b) /* WRONG */
#include <math.h>
www.freshersparadise.com
for some suitably-chosen degree of closeness epsilon (as long as
a is nonzero!).
(int)(x + 0.5)
14.9: How do I test for IEEE NaN and other special values?
www.freshersparadise.com
14.11: What's a good way to implement complex numbers in C?
14.13: I'm having trouble with a Turbo C program which crashes and says
something like "floating point formats not linked."
15.2: How can %f be used for both float and double arguments in
printf()? Aren't they different types?
www.freshersparadise.com
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; see question 11.3.) Therefore, printf's %f format always
sees a double. (Similarly, %c always sees an int, as does %hd.)
See also questions 12.9 and 12.13.
References: ISO Sec. 6.3.2.2; H&S Sec. 6.3.5 p. 177, Sec. 9.4
pp. 272-3.
printf("%d", n);
if(first == NULL)
return NULL;
len = strlen(first);
va_start(argp, first);
va_end(argp);
www.freshersparadise.com
if(retbuf == NULL)
return NULL; /* error */
(void)strcpy(retbuf, first);
va_end(argp);
return retbuf;
}
Note the cast on the last argument; see questions 5.2 and 15.3.
(Also note that the caller must free the returned, malloc'ed
storage.)
References: K&R2 Sec. 7.3 p. 155, Sec. B7 p. 254; ISO Sec. 7.8;
Rationale Sec. 4.8; H&S Sec. 11.4 pp. 296-9; CT&P Sec. A.3 pp.
139-141; PCS Sec. 11 pp. 184-5, Sec. 13 p. 242.
15.5: 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?
#include <stdio.h>
#include <stdarg.h>
www.freshersparadise.com
A: C9X will support vscanf(), vfscanf(), and vsscanf().
(Until then, you may be on your own.)
References: H&S Sec. 11.4 pp. 296-9; CT&P Sec. A.2 pp. 134-139;
PCS Sec. 11 pp. 184-5, Sec. 13 p. 250.
15.8: How can I discover how many arguments a function was actually
called with?
int f(...)
{
}
va_arg(argp, float)
working?
www.freshersparadise.com
A: 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.) See also
questions 11.3 and 15.2.
15.13: How can I call a function with an argument list built up at run
time?
16.1b: I'm getting baffling syntax errors which make no sense at all,
and it seems like large chunks of my program aren't being
www.freshersparadise.com
compiled.
16.1c: Why isn't my procedure call working? The compiler seems to skip
right over it.
myprocedure;
myprocedure();
16.5: 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...
A: Lots of things could be going wrong; here are a few of the more
common things to check:
www.freshersparadise.com
"narrow" or variable arguments (see questions 1.25, 11.3,
14.2, and 15.1)
crash?
www.freshersparadise.com
question 7.19); and mismatched function arguments, especially
involving pointers; two possibilities are scanf() (see question
12.12) and fprintf() (make sure it receives its first FILE *
argument).
A: K&R, while providing the example most often copied, also supply
a good excuse for disregarding it:
The elusive quality of "good style" involves much more than mere
code layout details; don't spend time on formatting to the
exclusion of more substantive code quality issues.
17.3: Here's a neat trick for checking whether two strings are equal:
if(!strcmp(s1, s2))
if(x = 0)
www.freshersparadise.com
If you're in the habit of writing the constant before the ==,
the compiler will complain if you accidentally type
if(0 = x)
17.5: I came across some code that puts a (void) cast before each call
to printf(). Why?
17.9: Where can I get the "Indian Hill Style Guide" and other coding
standards?
ftp.cs.washington.edu pub/cstyle.tar.Z
(the updated Indian Hill guide)
ftp.cs.toronto.edu doc/programming
(including Henry Spencer's
"10 Commandments for C Programmers")
ftp.cs.umd.edu pub/style-guide
www.freshersparadise.com
17.10: Some people say that goto's are evil and that I should never use
them. Isn't that a bit extreme?
www.freshersparadise.com
Unix utility wc, and
somewhat better with
grep -c ";"
a "selective" C
preprocessor see question 10.18
www.freshersparadise.com
Final Exam Memory Advisor, from PLATINUM Technology
(formerly Sentinel from AIB Software), 1815 South Meyers
Rd., Oakbrook Terrace, IL 60181, USA, 630-620-5000,
800-442-6861, [email protected], www.platinum.com .
18.4: I just typed in this program, and it's acting strangely. Can
you see anything wrong with it?
A: See if you can run lint first (perhaps with the -a, -c, -h, -p
or other options). Many C compilers are really only half-
compilers, electing not to diagnose numerous source code
difficulties which would not actively preclude code generation.
18.5: How can I shut off the "warning: possible pointer alignment
www.freshersparadise.com
problem" message which lint gives me for each call to malloc()?
Gimpel Software
3207 Hogarth Lane
Collegeville, PA 19426 USA
(+1) 610 584 4261
[email protected]
A: No. First of all, prototypes work only if they are present and
correct; an inadvertently incorrect prototype is worse than
useless. Secondly, lint checks consistency across multiple
source files, and checks data declarations as well as functions.
Finally, an independent program like lint will probably always
be more scrupulous at enforcing compatible, portable coding
practices than will any particular, implementation-specific,
feature- and extension-laden compiler.
www.freshersparadise.com
"Notes for C programmers," by Christopher Sawtell, are
available from svr-ftp.eng.cam.ac.uk in misc/sawtell_C.shar and
garbo.uwasa.fi in /pc/c-lang/c-lesson.zip .
On some Unix machines you can try typing "learn c" at the shell
prompt (but the lessons may be quite dated).
A: There are far too many books on C to list here; it's impossible
to rate them all. Many people believe that the best one was
also the first: _The C Programming Language_, by Kernighan and
Ritchie ("K&R," now in its second edition). Opinions vary on
K&R's suitability as an initial programming text: many of us did
learn C from it, and learned it well; some, however, feel that
it is a bit too clinical as a first tutorial for those without
much programming background. Several sets of annotations and
errata are available on the net, see e.g.
http://www.csd.uwo.ca/~jamie/.Refs/.Footnotes/C-annotes.html,
http://www.eskimo.com/~scs/cclass/cclass.html, and
www.freshersparadise.com
http://www.lysator.liu.se/c/c-errata.html#main .
Though not suitable for learning C from scratch, this FAQ list
has been published in book form; see the Bibliography.
www.freshersparadise.com
18.15: Where can I get a BNF or YACC grammar for C?
References: K&R1 Sec. A18 pp. 214-219; K&R2 Sec. A13 pp. 234-
239; ISO Sec. B.2; H&S pp. 423-435 Appendix B.
A: Some popular packages are the "quad" functions within the BSD
Unix libc sources (ftp.uu.net, /systems/unix/bsd-sources/..../
/src/lib/libc/quad/*), the GNU MP library, the MIRACL package
(see http://indigo.ie/~mscott/ ), and the old Unix libmp.a.
See also questions 14.12 and 18.16.
18.16: Where and how can I get copies of all these freely distributable
programs?
www.freshersparadise.com
difficult to answer.
Those are some of the easy parts of the question to answer. The
hard part is in the details -- this article cannot begin to
track or list all of the available archive sites or all of the
various ways of accessing them. If you have access to the net
at all, you probably have access to more up-to-date information
about active sites and useful access methods than this FAQ list
does.
19.1: How can I read a single character from the keyboard without
waiting for the RETURN key? How can I stop characters from
being echoed on the screen as they're typed?
www.freshersparadise.com
At some level, interactive keyboard input is usually collected
and presented to the requesting program a line at a time. This
gives the operating system a chance to support input line
editing (backspace/delete/rubout, etc.) in a consistent way,
without requiring that it be built into every program. Only
when the user is satisfied and presses the RETURN key (or
equivalent) is the line made available to the calling program.
Even if the calling program appears to be reading input a
character at a time (with getchar() or the like), the first call
blocks until the user has typed an entire line, at which point
potentially many characters become available and many character
requests (e.g. getchar() calls) are satisfied in quick
succession.
www.freshersparadise.com
to ask for one character at a time. (It's also possible to set
character-at-a-time or "pass through" modes in the VMS terminal
driver.) Under other operating systems, you're on your own.
References: PCS Sec. 10 pp. 128-9, Sec. 10.1 pp. 130-1; POSIX
Sec. 7.
19.2: How can I find out if there are characters available for reading
(and if so, how many)? Alternatively, how can I do a read that
will not block if there are no characters available?
www.freshersparadise.com
resort, you could use system() (see question 19.27) to invoke
an operating system clear-screen command.
References: PCS Sec. 5.1.4 pp. 54-60, Sec. 5.1.5 pp. 60-62.
19.5: How do I read the arrow keys? What about function keys?
www.freshersparadise.com
fprintf(ofd, "\033[J");
A: Once upon a time, Unix had a fairly nice little set of device-
independent plot functions described in plot(3) and plot(5).
The GNU libplot package maintains the same spirit and supports
many modern plot devices;
see http://www.gnu.org/software/plotutils/plotutils.html .
19.11: How can I check whether a file exists? I want to warn the user
if a requested input file is missing.
19.12: How can I find out the size of a file, prior to reading it in?
Under Unix, the stat() call will give you an exact answer.
Several other systems supply a Unix-like stat() which will give
www.freshersparadise.com
an approximate answer. You can fseek() to the end and then use
ftell(), or maybe try fstat(), but these tend to have the same
sorts of problems: fstat() is not portable, and generally tells
you the same thing stat() tells you; ftell() is not guaranteed
to return a byte count except for binary files. Some systems
provide functions called filesize() or filelength(), but these
are obviously not portable, either.
Are you sure you have to determine the file's size in advance?
Since the most accurate way of determining the size of a file as
a C program will see it is to open the file and read it, perhaps
you can rearrange the code to learn the size as it reads.
19.12b: How can I find the modification date and time of a file?
19.14: How can I insert or delete a line (or record) in the middle of a
file?
19.15: How can I recover the file name given an open stream or file
descriptor?
www.freshersparadise.com
References: K&R2 Sec. B1.1 p. 242; ISO Sec. 7.9.4.1; H&S
Sec. 15.15 p. 382; PCS Sec. 12 pp. 208,220-221; POSIX
Sec. 5.5.1, Sec. 8.2.4.
19.17: Why can't I open a file by its explicit path? The call
fopen("c:\newdir\file.dat", "r")
is failing.
fopen("c:\\newdir\\file.dat", "r")
fopen("c:/newdir/file.dat", "r")
19.18: I'm getting an error, "Too many open files". How can I increase
the allowable number of simultaneously open files?
A: See if you can use the opendir() and readdir() functions, which
are part of the POSIX standard and are available on most Unix
variants. Implementations also exist for MS-DOS, VMS, and other
www.freshersparadise.com
systems. (MS-DOS also has FINDFIRST and FINDNEXT routines which
do essentially the same thing.) readdir() only returns file
names; if you need more information about the file, try calling
stat(). To match filenames to some wildcard pattern, see
question 13.7.
References: K&R2 Sec. 8.6 pp. 179-184; PCS Sec. 13 pp. 230-1;
POSIX Sec. 5.1; Schumacher, ed., _Software Solutions in C_
Sec. 8.
19.24: What does the error message "DGROUP data allocation exceeds 64K"
mean, and what can I do about it? I thought that using large
model meant that I could use more than 64K of data!
www.freshersparadise.com
A: Set a pointer, of the appropriate type, to the right number
(using an explicit cast to assure the compiler that you really
do intend this nonportable conversion):
References: K&R1 Sec. A14.4 p. 210; K&R2 Sec. A6.6 p. 199; ISO
Sec. 6.3.4; Rationale Sec. 3.3.4; H&S Sec. 6.2.7 pp. 171-2.
19.30: How can I invoke another program or command and trap its output?
If you can't use popen(), you may be able to use system(), with
the output going to a file which you then open and read.
If you're using Unix and popen() isn't sufficient, you can learn
about pipe(), dup(), fork(), and exec().
(One thing that probably would *not* work, by the way, would be
to use freopen().)
References: K&R1 Sec. 5.11 p. 111; K&R2 Sec. 5.10 p. 115; ISO
Sec. 5.1.2.2.1; H&S Sec. 20.1 p. 416.
www.freshersparadise.com
in the same directory as the executable?
A: It's hard; see also question 19.31 above. Even if you can
figure out a workable way to do it, you might want to consider
making the program's auxiliary (library) directory configurable,
perhaps with an environment variable. (It's especially
important to allow variable placement of a program's
configuration files when the program will be used by several
people, e.g. on a multiuser system.)
19.36: How can I read in an object file and jump to locations in it?
19.37: How can I implement a delay, or time a user's response, with sub-
second resolution?
www.freshersparadise.com
is a time-reporting function, you can implement a CPU-intensive
busy-wait, but this is only an option on a single-user, single-
tasking machine as it is terribly antisocial to any other
processes. Under a multitasking operating system, be sure to
use a call which puts your process to sleep for the duration,
such as sleep() or select(), or pause() in conjunction with
alarm() or setitimer().
long int i;
for(i = 0; i < 1000000; i++)
;
References: H&S Sec. 18.1 pp. 398-9; PCS Sec. 12 pp. 197-8,215-
6; POSIX Sec. 4.5.2.
#include <signal.h>
signal(SIGINT, SIG_IGN);
The test and extra call ensure that a keyboard interrupt typed
in the foreground won't inadvertently interrupt a program
running in the background (and it doesn't hurt to code calls to
signal() this way on any system).
www.freshersparadise.com
References: ISO Secs. 7.7,7.7.1; H&S Sec. 19.6 pp. 411-3; PCS
Sec. 12 pp. 210-2; POSIX Secs. 3.3.1,3.3.4.
A: All of these questions are outside of the scope of this list and
have much more to do with the networking facilities which you
have available than they do with C. Good books on the subject
are Douglas Comer's three-volume _Internetworking with TCP/IP_
and W. R. Stevens's _UNIX Network Programming_. (There is also
plenty of information out on the net itself, including the
"Unix Socket FAQ" at http://kipper.york.ac.uk/~vic/sock-faq/ .)
19.40b: How do I... Use BIOS calls? Write ISR's? Create TSR's?
www.freshersparadise.com
A: Either pass pointers to several locations which the function can
fill in, or have the function return a structure containing the
desired values, or (in a pinch) consider global variables. See
also questions 2.7, 4.8, and 7.5a.
References: K&R1 Sec. 5.11 pp. 110-114; K&R2 Sec. 5.10 pp. 114-
118; ISO Sec. 5.1.2.2.1; H&S Sec. 20.1 p. 416; PCS Sec. 5.6 pp.
81-2, Sec. 11 p. 159, pp. 339-40 Appendix F; Schumacher, ed.,
_Software Solutions in C_ Sec. 4 pp. 75-85.
20.5: How can I write data files which can be read on other machines
with different word size, byte order, or floating point formats?
Then, search the table for the name, and call via the associated
function pointer. See also questions 2.15, 18.14, and 19.36.
www.freshersparadise.com
#include <limits.h> /* for CHAR_BIT */
int x = 1;
if(*(char *)&x == 1)
printf("little-endian\n");
else printf("big-endian\n");
A: 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.
20.12: What is the most efficient way to count the number of bits which
are set in an integer?
www.freshersparadise.com
A: Many "bit-fiddling" problems like this one can be sped up and
streamlined using lookup tables (but see question 20.13 below).
20.14: Are pointers really faster than arrays? How much do function
calls slow things down? Is ++i faster than i = i + 1?
www.freshersparadise.com
pointers rather than array subscripts, but for some processors
the reverse is true.
20.15b: 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.
a ^= b;
b ^= a;
a ^= b;
int t = a;
a = b;
b = t;
References: K&R1 Sec. 3.4 p. 55; K&R2 Sec. 3.4 p. 58; ISO
Sec. 6.6.4.2; H&S Sec. 8.7 p. 248.
www.freshersparadise.com
simple for the compiler to translate, therefore case labels are
limited to single, constant, integral expressions. You *can*
attach several case labels to the same statement, which will let
you cover a small range if you don't mind listing all cases
explicitly.
References: K&R1 Sec. 3.4 p. 55; K&R2 Sec. 3.4 p. 58; ISO
Sec. 6.6.4.2; Rationale Sec. 3.6.4.2; H&S Sec. 8.7 p. 248.
A: Yes.
Long ago, in the early days of C, they were required, and just
enough people learned C then, and wrote code which is still in
circulation, that the notion that they might still be required
is widespread.
References: K&R1 Sec. A18.3 p. 218; ISO Sec. 6.3.3, Sec. 6.6.6;
H&S Sec. 8.9 p. 254.
References: K&R1 Sec. A2.1 p. 179; K&R2 Sec. A2.2 p. 192; ISO
Sec. 6.1.9, Annex F; Rationale Sec. 3.1.9; H&S Sec. 2.2 pp. 18-
9; PCS Sec. 10 p. 130.
www.freshersparadise.com
a ++ ++ + b
assert(p != NULL);
References: K&R2 Sec. B6 pp. 253-4; ISO Sec. 7.2; H&S Sec. 19.1
p. 406.
20.25: How can I call FORTRAN (C++, BASIC, Pascal, Ada, LISP) functions
from C? (And vice versa?)
www.freshersparadise.com
20.26: Does anyone know of a program for converting Pascal or FORTRAN
(or LISP, Ada, awk, "Old" C, ...) to C?
A: 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. In spite of the
differences, many C programs will compile correctly in a C++
environment, and many recent compilers offer both C and C++
compilation modes. See also questions 8.9 and 20.20.
www.freshersparadise.com
20.29: What is hashing?
References: K&R2 Sec. 6.6; Knuth Sec. 6.4 pp. 506-549 Volume 3;
Sedgewick Sec. 16 pp. 231-244.
20.31: How can I find the day of the week given the date?
A: Yes and no, respectively. The full expression for the present
Gregorian calendar is
20.34: Here's a good puzzle: how do you write a program which produces
its own source code as output?
char*s="char*s=%c%s%c;main(){printf(s,34,s,34);}";
main(){printf(s,34,s,34);}
www.freshersparadise.com
(This program, like many of the genre, neglects to #include
<stdio.h>, and assumes that the double-quote character " has the
value 34, as it does in ASCII.)
www.freshersparadise.com
References: K&R2 p. 259 Appendix C.
Are you an expert in this area? Share your knowledge and earn expert points by giving
answers or rating people's questions and answers! This section of FAQS.ORG is not
sanctioned in any way by FAQ authors or maintainers.
write a program in c language to merge the contents of two binary search tree into
one.... by dip (5/16/2004)
www.freshersparadise.com
1. How to insert the bmp or jpg files in c 2. How to connect the database in C, and
what... by thiyanesh (7/11/2003)
I am trying to find out how to pring some-thing like 5$$$$ ... by Tony
(4/27/2004)
write a program in assembly language that will ask for a number and print a list
of... by sandman444 (5/14/2004)
I have a project due that requires that requres that I use characters. I am having
trouble... by Tony (4/16/2004)
How to read/write from/into given memory locations using 'C' language?? TIA by
anu (12/26/2003)
i want to close the window client area in vc++ with some code via File menu(exit
command).... by yogen (4/26/2004)
www.freshersparadise.com
What is the difference between Java and C++....eg....speed...garbage
collection...etc by Baharuddin (2/23/2004)
what are the advantages and dis advantages of array? by ankita (11/1/2003)
I use c++ 5.02 everytime i learned for graphic the compiler said "error BGI
graphics... by gede (9/14/2003)
Can I add wave (sound) files to a "C" file? If yes, then how?I want to know in
detail. by Ava (12/22/2003)
Please give me the complete coding for creating a single linked list,deleting nodes
in... by kalyan singh (5/13/2004)
hi, i want to ask about top-down designing in C language. can i get a note about
it? by sarah (8/31/2003)
Hi ! I'm not a C programmer and I'd like to know how to calculate the day before
the... by Augusto (10/27/2003)
Having a difficult time running this small piece of code. Not sure what is going
on.... by briane (4/24/2004)
www.freshersparadise.com
isn't it that after making the program, you have to compile it. afterwards, you have
to... by valerie (12/29/2003)
Can we convert a C file to a screen saver file(*.scr).If possible please describe in...
by dubi (1/29/2004)
write a program in assembly language that will ask for a number and print a list
of... by sandman4444 (5/15/2004)
I'm trying to print out a table using ANSI C. What is the proper format in the... by
Jeff (2/24/2004)
what additional control structure is needed to replace a while loop with do-while
loop? by neetu (10/14/2003)
www.freshersparadise.com
why increment operator is faster than decrement operator? by ashwani
(11/27/2003)
main() { char s[10]="fun()"; ----- ----- } void fun() {------- -------- } Now... by
Balu (4/22/2004)
What is the difference between Microsoft C and Turbo C? Which is good for
what? by Gopinath.V. (12/6/2003)
I want to know the exact definitions,differences between those and example code
how it... by chrisme (5/18/2004)
I just want to know the differences in the pointer implementation in C & C++> by
Vijay Krishna Doddala (7/30/2003)
Hello is there any way to make a printf/cout updating??I mean with for
(i=10;i<0;i... by dager (4/21/2004)
www.freshersparadise.com
How to use Databases in C? How to connect to a Database? Please provide the
ways for... by gokul (1/19/2004)
Can I write an interactive program that print the input in words: user input 66
sixty... by neli (10/12/2003)
C is case sensitive but '\xCd' or '\xcd' are the sames (e.g in printf("\xCd");) by john
(4/6/2004)
how to input more than 127 characters? I've used gets but it only inputted 127
characters.... by ac (10/23/2003)
I am a totally new programming learner and there are some problems about the
coding of ... by yndrac (2/12/2004)
how the output of c program will produce source code of its own by suri
(9/11/2003)
Suppose i creating a linked list, the data structure is given below. struct _list { ...
by randal (4/7/2004)
How to store variable length bit arrays into a file using C ? by vinay (9/6/2003)
How can i write a code in c that will produce the code itself as out put by deb
(2/3/2004)
www.freshersparadise.com
How do I print \n to output, as opposed to using it for a new line? by trang
(12/4/2003)
Modifying a record in a text file without disturbing other record in the file.And i
should... by Bujjiprasad (7/4/2003)
I'd like to dynamically allocate memory in a subroutine, save values, and use them
in a... by DandyDon (5/25/2004)
i would like to create a program in which it will read in a sentence when I enter
a... by Aces (3/10/2004)
how do i know how to treat the sin function? what form does it support? by daf
(7/22/2003)
www.freshersparadise.com
I need the explanation of the following program and o/p main() { int a[2]=
{4,5}; ... by Arun (5/5/2004)
question 7.17 in "C how to program" has me pulling out my hair. How do you go
about... by gummybear (3/10/2004)
How can I use the content of a variable as an address for another operation? by T-
man (5/19/2004)
how to write programs by using user defined string functions by geetu (1/11/2004)
I have a problem in doing program in language C for the topic File Processing.
The problem... by umney (1/11/2004)
. when a multidimensional array is passed to a function why does C++ require all
but the... by vikka (3/2/2004)
1. What does the error 'Null Pointer Assignment' mean and what causes this
error? ... by papai (9/11/2003)
write a program to find out whether a given number is prime or not. by urvi
(1/1/2004)
write a program to print 'n' numbers of the fibonacci series. by urvi (1/1/2004)
www.freshersparadise.com
can you give me examples of the reserved words and data types in Turbo C? by
DYLANg-anghel (7/10/2003)
How can I write a function that will compare local time with file original date
stamp. I... by Harinen (8/18/2003)
q- Does mentioning the array name gives the base address in all the... by erika
(2/20/2004)
1. under what conditions the initialization part and the test part of the for... by
amrita maloo (11/1/2003)
How do u convert numbers into words... for example... 401.26 should be written
as Four... by guru (9/29/2003)
what will be the output of the following program #include<stdio.h> main() { ... by
sasmendra (2/25/2004)
write a program in 8086 assembly language that concatenates two given strings to
create a... by VNSreenivas (10/30/2003)
how do you give and take values from VB to C. that is how do you interface them.
by RMSJ (3/16/2004)
if we declare two global variables of same name it will not give any error on unix
machine... by bharathv (1/8/2004)
how many different versions of c language exist till date by manish sharma
(7/27/2003)
www.freshersparadise.com
Using C, evaluate an expression by using Queue (without use of stack) by
Simaran (4/20/2004)
www.freshersparadise.com