CQuestions
CQuestions
main()
{
char *p1="name";
char *p2;
p2=(char*)malloc(20);
memset (p2, 0, 20);
while(*p2++ = *p1++);
printf("%sn",p2);
}
Answer:empty string.
What will be printed as the result of the operation below:
main()
{
int x=20,y=35;
x=y++ + x++;
y= ++y + ++x;
printf("%d%dn",x,y);
}
Answer : 5794
What will be printed as the result of the operation below:
main()
{
int x=5;
printf("%d,%d,%dn",x,x< <2,x>>2);
}
Answer: 5,20,1
What will be printed as the result of the operation below:
#define swap(a,b) a=a+b;b=a-b;a=a-b;
void main()
{
int x=5, y=10;
swap (x,y);
printf("%d %dn",x,y);
swap2(x,y);
printf("%d %dn",x,y);
}
int swap2(int a, int b)
{
int temp;
temp=a;
b=a;
a=temp;
return 0;
}
Answer: 10, 5
10, 5
What will be printed as the result of the operation below:
main()
{
char *ptr = " Cisco Systems";
*ptr++;
printf("%sn",ptr);
ptr++;
printf("%sn",ptr);
}
Answer:Cisco Systems
isco systems
What will be printed as the result of the operation below:
main()
{
char s1[]="Cisco";
char s2[]= "systems";
printf("%s",s1);
}
Answer: Cisco
What will be printed as the result of the operation below:
main()
{
char *p1;
char *p2;
p1=(char *)malloc(25);
p2=(char *)malloc(25);
strcpy(p1,"Cisco");
strcpy(p2,"systems");
strcat(p1,p2);
printf("%s",p1);
}
Answer: Ciscosystems
The following variable is available in file1.c, who can access it?:
static int average;
Answer: all the functions in the file1.c can access the variable.
WHat will be the result of the following code?
#define TRUE 0
// somecode.
while(TRUE)
{
// somecode
}
int modifyvalue()
{
return(x+=10);
}
int changevalue(int x)
{
return(x+=1);
}
void main()
{
int x=10;
x++;
changevalue(x);
x++;
modifyvalue();
printf("First output:%dn",x);
x++;
changevalue(x);
printf("Second output:%dn",x);
modifyvalue();
printf("Third output:%dn",x);
}
Answer: 12 , 13 , 13
What will be printed as the result of the operation below:
main()
{
int x=10, y=15;
x = x++;
y = ++y;
printf("%d %dn",x,y);
}
Answer: 11, 16
What will be printed as the result of the operation below:
main()
{
int a=0;
if(a==0) printf("Cisco Systemsn");
printf("Cisco Systemsn");
}
void
reverseStringByWords(char* input)
{
char* start = input;
while (*start == ' ')
start++;
while (*start)
{
char* wordstart = start;
while (*start & ~' ')
start++;
reverseString(wordstart, start -
wordstart);
while (*start == ' ')
start++;
}
reverseString(input, start - input);
}
YK’S questions
Suppose a function f( ) has been defined in file 'file1.h'. If we #include this file
twice a redefinition of function would occur. How would you avoid it?
Suppose your executable (.EXE ) files have been deleted accidentally and if you
want to copy all executable files to the specified directory, you have to recompile
all the files. This process would be cumbersome. How would you compile all the
files in a single pass.
Suppose a file 'emp.dat' consists of 10 dates. Write a program to sort and print
the sorted dates on the screen.
8 1 6
3 5 7
4 9 2
The following is a procedure for constructing an n x n magic square for any odd
integer n.
Place initial number, say k, in the middle of the top row. Then after integer k has
been placed, move up one row and one column to the right to place the next
integer k + 1, unless one of the following occurs:
(a) If a move takes you above the top row in the j th column, move to the bottom
of the j th column and place the integer there.
(b) If a move takes you outside to the right of the square in the i th row, place the
integer in the i th row at the left side.
(c) If a move takes you to an already filled square, place k + 1 immediately below
k.
Write a program to construct a magic square for any odd integer n.
Accept two dates and the day of the first date from the keyboard. Write a
program to determine and print the day of the other date.
Write a program that converts the numeric figures into the words. For example,
123 should be printed as , One Hundred Twenty Three.
Pascal triangle's elements are the Binomial coefficients and can be calculated
from the formula:
n!/ ( ( n - r )! * r! ).
Write a program to print the pascal's triangle without using the formula or arrays.
Write a program to print the calendar, which is constrained to only 5 rows as:
January 2000
30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
Write a program to find the determinant value of any given square matrix using
recursion.
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.
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();
typedef struct {
char *item;
NODEPTR next;
} *NODEPTR;
struct node {
char *item;
struct node *next;
};
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:
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.
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.
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?
...
char namestr[MAXSIZE];
where MAXSIZE is larger than any name which will be stored.
However, it looks like this technique is disallowed by a strict
interpretation of the Standard as well. Furthermore, either of
these "chummy" structures must be used with care, since the
programmer knows more about their size than the compiler does.
(In particular, they can generally only be manipulated via
pointers.)
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.
2.13: Why does sizeof report a larger size than I expect for a
structure type, as if there were padding at the end?
offsetb = offsetof(struct a, b)
struct list {
char *item;
struct list *next;
}
main(argc, argv)
{ ... }
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.
2.22: What is the difference between an enumeration and a set of
preprocessor #defines?
Section 3. Expressions
a[i] = i++;
work?
References: K&R1 Sec. 2.12; K&R2 Sec. 2.12; ISO Sec. 6.3; H&S
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
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.
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
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?
p += sizeof(int);
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.
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();
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.
Section 5. Null Pointers
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)
Summary:
function call,
prototype in scope,
fixed argument
if(expr)
if((expr) != 0)
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?
could fail.
if you must.
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.
5.15: I'm confused. I just can't understand all this null pointer
stuff.
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).
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.
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.
A: The type.
#include <stdlib.h>
int *dynarray;
dynarray = malloc(10 * sizeof(int));
#include <stdlib.h>
but the syntax starts getting horrific and at most one dimension
may be specified at run time.
With all of these techniques, you may of course need to remember
to free the arrays (which may take several steps; see question
7.23) when they are no longer needed, and you cannot necessarily
intermix dynamically-allocated arrays with conventional,
statically-allocated ones (see question 6.20, and also question
6.18).
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-
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.
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
int array[NROWS][NCOLUMNS];
int **array1; /* ragged */
int **array2; /* contiguous */
int *array3; /* "flattened" */
int (*array4)[NCOLUMNS];
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>
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");
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 */
}
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
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?
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.
A: Most implementations of malloc/free do not return freed memory
to the operating system, but merely make it available for future
malloc() calls within the same program.
7.27: So can I query the malloc package to find out how big an
allocated block is?
p = malloc(m * n);
memset(p, 0, m * n);
strcat(string, '!');
work?
strcat(string, "!");
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?
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).
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".
9.3: Is if(p), where p is a pointer, a valid conditional?
#define begin {
#define end }
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?)
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.
10.7: Is it acceptable for one header file to #include another?
#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
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.
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
TRACE(count);
as
printf("TRACE: %d\count", count);
A: See question 11.18.
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.
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.
struct x;
const int n = 5;
int a[n];
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.
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);
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?
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?
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.
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?
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?
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?
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()!
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
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.
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.
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?
References: ISO Sec. 7.3.2; H&S Sec. 12.9 pp. 320-1; PCS p. 182.
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.
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.
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().
#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.
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.
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>
(int)(x + 0.5)
14.9: How do I test for IEEE NaN and other special values?
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?
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);
if(retbuf == NULL)
return NULL; /* error */
(void)strcpy(retbuf, first);
va_end(argp);
return retbuf;
}
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>
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?
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
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:
crash?
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))
Is this good style?
if(x = 0)
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
17.10: Some people say that goto's are evil and that I should never use
them. Isn't that a bit extreme?
a "selective" C
preprocessor see question 10.18
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
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.
On some Unix machines you can try typing "learn c" at the shell
prompt (but the lessons may be quite dated).
Though not suitable for learning C from scratch, this FAQ list
has been published in book form; see the Bibliography.
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?
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?
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?
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?
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
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?
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
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!
A: Even in large memory models, MS-DOS compilers apparently toss
certain data (strings, some initialized global or static
variables) into a default data segment, and it's this segment
that is overflowing. Either use less global data, or, if you're
already limiting yourself to reasonable amounts (and if the
problem is due to something like the number of strings), you may
be able to coax the compiler into not using the default data
segment for so much. Some compilers place only "small" data
objects in the default data segment, and give you a way (e.g.
the /Gt option under Microsoft compilers) to configure the
threshold for "small."
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.
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?
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).
On some systems, keyboard interrupt handling is also a function
of the mode of the terminal-input subsystem; see question 19.1.
On some systems, checking for keyboard interrupts is only
performed when the program is reading input, and keyboard
interrupt handling may therefore depend on which input routines
are being called (and *whether* any input routines are active at
all). On MS-DOS systems, setcbrk() or ctrlbrk() functions may
also be involved.
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?
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.
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?
20.14: Are pointers really faster than arrays? How much do function
calls slow things down? Is ++i faster than i = i + 1?
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.
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.
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.
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?)
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);}