学习笔记(C++Primer)--易错点总结(Chapter2)

时间:2023-12-22 09:19:08

2.1.2Type Conversions(1/10/2017)

1.If we assign an out-of-range value to an object of unsigned type, the result is

the remainder of the value modulo
the number of values the target type can

hold. For example, an 8-bit unsigned char can hold values from 0 through

255, inclusive. If we assign a
value outside this range, the compiler assigns the

remainder of that value modulo 256.
Therefore, assigning –1 to an 8-bit

unsigned char gives that object the value 255.

2. If
we assign an out-of-range value to an object of signed type, the result is

undefined.
The program might appear to work, it might crash, or it might

produce
garbage values.

3.Advice:
Avoid Undefined and Implementation-Defined Behavior

Undefined
behavior results from errors that the compiler is not required (and

sometimes
is not able) to detect. Even if the code compiles, a program that

executes
an undefined expression is in error.

Unfortunately,
programs that contain undefined behavior can appear to

execute
correctly in some circumstances and/or on some compilers. There is

no
guarantee that the same program, compiled under a different compiler or

even
a subsequent release of the same compiler, will continue to run

correctly.
Nor is there any guarantee that what works with one set of inputs

will
work with another.

Similarly,
programs usually should avoid implementation-defined behavior,

such
as assuming that the size of an int is a fixed and known value. Such

programs
are said to be nonportable. When the program is moved to another

machine,
code that relied on implementation-defined behavior may fail.

Tracking
down these sorts of problems in previously working programs is,

mildly
put, unpleasant.

4. The
compiler applies these same type conversions when we use a value of one

arithmetic
type where a value of another arithmetic type is expected. For example,

when
we use a nonbool value as a condition (§ 1.4.1, p. 12), the arithmetic value is

converted
to bool in the same way that it would be converted if we had assigned

that
arithmetic value to a bool variable:

int i = 42;

if (i) //
condition will evaluate as true

i = 0;

If
the value is 0, then the condition is false; all other (nonzero) values yield
true.

By
the same token, when we use a bool in an arithmetic expression, its value

always
converts to either 0 or 1. As a result, using a bool in an arithmetic
expression

is
almost surely incorrect.

5. Caution:
Don’t Mix Signed and Unsigned Types

Expressions
that mix signed and unsigned values can yield surprising results

when
the signed value is negative. It is essential to remember that signed

values
are automatically converted to unsigned. For example, in an

expression
like a * b, if a is -1 and b is 1, then if both a and b are ints,

the
value is, as expected -1. However, if a is int and b is an unsigned,

then
the value of this expression depends on how many bits an int has on

the
particular machine. On our machine, this expression yields 4294967295

6.2的32次方是4294967296

7.

unsigned
u = 10, u2 = 42;

std::cout
<< u2 - u << std::endl;//32

std::cout
<< u - u2 << std::endl;//4294967264

int
i = 10, i2 = 42;

std::cout
<< i2 - i << std::endl;//32

std::cout
<< i - i2 << std::endl;//-32

std::cout
<< i - u << std::endl;//0

std::cout <<
u - i << std::endl;//0

2.1.3literals

1.

Although
integer literals may be stored in signed types, technically speaking, the

value
of a decimal literal is never a negative number. If we write what appears to be

a
negative decimal literal, for example, -42, the minus sign is not part of the
literal.

The
minus sign is an operator that negates the value of its (literal) operand.

2.

3. The
type of a string literal is array of constant chars, a type we’ll discuss in §
3.5.4

(p.
122). The compiler appends a null character (’\0’) to every string literal.
Thus, the

actual
size of a string literal is one more than its apparent size. For example, the

literal
'A' represents the single character A, whereas the string literal "A"
represents

an
array of two characters, the letter A and the null character.

4. Two
string literals that appear adjacent to one another and that are separated only

by
spaces, tabs, or newlines are concatenated into a single literal. We use this
form of

literal
when we need to write a literal that would otherwise be too large to fit

comfortably
on a single line:

// multiline
string literal

std::cout <<
"a really, really long string literal "

"that spans
two lines" << std::endl;