Chapter 2
Trigraphs are used when the input device used, or the host system's
native character set, do not support enough distinct characters for the
full C language.
Trigraphs would not be used in a system that has enough distinct
characters to allocate a separate one to each of the C language symbols.
For maximum portability, one might see a trigraph representation of
a C program being distributed, on the grounds that most systems which do
not use ASCII will be able to read ASCII coded data and translate it into
their native codeset. A Standard C compiler could then compile such
a program directly.
White space characters are not equivalent to each other inside strings
and character constants. Newline is special to the preprocessor.
To continue a long line. Especially in systems that have an upper limit
on physical line length.
They become joined.
Because the */ which apparently terminates the inner comment
actually terminates the outer comment.
31 characters for internal variables, six for external variables. The six
character names must not rely on distinction between upper and lower case,
either.
A declaration introduces a name and a type for something. It does not
necessarily reserve any storage.
A definition is a declaration that also reserves storage.
It is always the case that the largest range of values can be held in
a long double, although it may not actually be any different from one of
the smaller floating point types.
The same answer holds true for the type with the greatest precision: long
double. C does not permit the language implementor to use the same number
of bits for, say, double and long double, then to allocate more bits for
precision in one type and more for range in the other.
There can never be problems assigning a shorter floating point type to
a longer one.
Assigning a longer floating type to a shorter one can result in overflow
and undefined behaviour.
Undefined behaviour is completely unpredictable. Anything may happen.
Often, nothing seems to happen except that erroneous arithmetic values are
produced.
Signed int (by the integral promotions).
- This cannot be predicted without knowing about the implementation.
If an
int can hold all of the values of an unsigned
char the result will be int , again by the integral
promotions. Otherwise, it will have to be unsigned int .
Unsigned int .
Long .
Unsigned long .
Long .
Float .
Float .
Long double .
i1 % i2
i1 % (int)f1
- If either operand is negative, the sign is implementation defined,
otherwise it is positive. This means that, even if both operands are
negative, you can't predict the sign.
- Two—unary negate, binary subtract.
i1 &= 0xf;
i1 |= 0xf;
i1 &= ~0xf;
i1 = ((i2 >> 4) & 0xf) | ((i2 & 0xf) << 4);
- The result is unpredictable. You must never use the same variable more
than once in an expression if the expression changes its value.
-
(c = (( u * f) + 2.6L);
(int = ((float) + long double);
(int = (long double));
(int);
Note: the integral promotion of char to int
might be to unsigned int , depending on the
implementation.
-
(u += (((--f) / u) % 3));
(unsigned += ((float / unsigned) % int));
(unsigned += (float % int));
(unsigned += float);
(unsigned);
-
(i <<= (u * (- (++f))));
(int <<= (unsigned * (- float)));
(int <<= (unsigned * float));
(int <<= float);
(int);
The rules for the shift operators state the right-hand operand is
always converted to int . However, this does not affect the
result, whose type is always determined by the type of the left-hand
operand. This is doubly so for the current example, since an assignment
operator is being used.
-
(u = (((i + 3) + 4) + 3.1));
The rules state that the subexpressions involving + can be
arbitrarily regrouped, as long as no type changes would be introduced.
The types are:
(unsigned = (((int + int) + int) + double))
so the leftmost two additions can be regrouped. Working from the
left:
(unsigned = ((int + int) + double));
(unsigned = (int + double));
(unsigned = double);
(unsigned);
-
(u = (((3.1 + i) + 3 ) + 4));
See the comments above on regrouping.
(unsigned = (((double + int) + int) + int));
The two rightmost additions can be regrouped.
(unsigned = ((double + int) + int));
(unsigned = (double + int));
(unsigned = double);
(unsigned);
-
(c = ((i << (- (--f))) & 0xf));
(char = ((int << (- (--float))) & int ));
(char = ((int << (- float)) & int ));
(char = ((int << float) & int));
(char = (int & int));
(char);
|
Printer-friendly version
The C Book
This book is published as a matter of historical interest.
Please read the
copyright and disclaimer information.
GBdirect Ltd provides up-to-date training and consultancy in
C,
Embedded C,
C++
and a wide range of
other subjects based on
open standards if you happen to be interested.
|