本系列为本人温习C++基础时所记的tips,欢迎各位同学指正,共同进步TvT。
An expression is composed of one or more operands combined by operators.
Until we know the types of operands, it’s not possible to know what a particular expression means.
取余
%
时,现版标准是余数与被除数正负号相同,商向0
取整When the precedent may be confusing, use parenthesis to assure correctness.
We use
;
here to separate operators with different precedents:- Relational and logical operators:
!; <, <=, >, >=(left associative); ==, !=; &&; ||
(from higher order to lower) - Bitwise operators:
~; <<, >>; &; ^; |
; How to deal with the sign bit of a signed integral value is machine-dependent, try to avoid it
- Relational and logical operators:
The shift operators(
<<, >>
) have lower precedence than the arithmetic operators but higher than the relational, assignment, or conditional operators… In a word, use()
to get rid of confusion.The result and type of an assignment is the same as the left-hand operand. Assignment is right associative.
int a; int* b; a=b=0; //errror, inconvertable
->
is applied to pointers or iteratorsMyclass* mc = new Myclass(); mc->mfun(); (*mc).mfun(); *mc.mfun();//error
sizeof
is an operator, NOT a function. Its value is decided at compile time and the operand expression will not be executed, only the type is concerned.Order of evaluation(求值顺序)is unspecified except
&&, ||, ? :
. The order of operand evaluation matters if one subexpression changes the value of an operand used in another subexpression.if (ia[ind++] < ia[ind]); // Undefined int *p1 = new int; // Uninitialized int *p2 = new int(); // 0, or say, null pointer mClass *p3 = new mClass; // Default Constr mClass *p4 = new mClass(); // Default Constr
The
()
syntax for value initialization must follow a type name, not a variable name.new
returns a pointer to the type specified.int i; int *p1 = &i; delete p1;// error, i is local int *p2 = 0; delete p2;// ok, have no effect int *p3 = new int; delete p3;// right
Setting the pointer to
0
afterdelete
to avoid the pointer being dangling, that is, refers to memory that once held an object but does so no longer.Three common program errors associated with dynamic memory allocation:
- memory leak
- dangling pointer, reading or writing to the object after it has been deleted
- delete twice. This happens when two pointers point to the same dynamically allocated object, making the free store corrupted.
When
unsigned short
meetsint
, ifint
is large enough to hold all the values ofunsigned short
, it’s converted toint
; Otherwise, both of them are converted tounsigned int
. This is machine dependent behavior. Other similar situations involvingunsigned
are like this.Conversions for expressions involving signed and unsigned int can be surprising: signed is converted to unsigned.e.g
0U > -1
isfalse
because-1
is converted to a very large positive number in this case!!!A constant integral value of
0
can be converted to any pointer type; A pointer to any data type can be converted to avoid*
.char *p1 = false;// ok, false promoted to 0 char *p2 = true;// error
An explicit conversion:
static_cast, dynamic_cast, const_cast, reinterpret_cast
const_cast
, remove constness.dynamic_cast
, supports the tun-time identification of objects addressed either by a pointer or reference. Covered later.static_cast
, any implicit conversion performed by compiler can be explicitly specified by it, to inform everyone that we are aware of this conversion.reinterpret_cast
, rudely performs a low-level reinterpretation of the bit-pattern of its operands, strongly machine/compiler dependent.
Reference : C++ Primer 4th edition(评注版)