Expressions & Statements Lecture 4
Expressions An expression is composed of one or more operands and yields a result when it is evaluated. The simplest form of an expression is a single literal or variable. More complicated expressions are formed from an operator and one or more operands. cout << 2 a * b “Hello” + “World”
Operators Unary operators Binary operators int a = 3; int *p = &a; int b = *p; double x = 2.3 * 5.0; cout << x; // multiplication // insertion // address-of // dereference
Operators vector<int> v; string s; // do something to v string s; if (v.size( ) > 10) { s = “long”; } else { s = “short”; The conditional operator (ternary) vector<int> v; string s = (v.size( ) > 10) ? “long” : “short”; Syntax (condition) ? (if_true) : (if_false);
Precedence & associativity 优先级 结合性 3 + 4 * 5 20 – 15 – 3 int a[5] = {1, 2, 4, 8, 16}; int b = *(a + 3); int c = *a + 3; // b = 8 // c = 4
Precedence & associativity cout << a == b << endl; error: reference to overloaded function could not be resolved; did you mean to call it? 3.4 + 2 / 5 * 0.6 ok. the result is 3.4. if (a & b != b) // do something else // do something else warning: self-comparison always evaluates to false
Precedence & associativity vector<int> v{1, 2, 4, 8, 16}; vector<int>::const_iterator it = v.begin( ); while (it != v.end( )) { cout << *it << endl; ++it; } 利用优先级写出更简洁的code while (it != v.end( )) cout << *it++ << endl;
Increment & decrement 注意区分表达式的执行结果/效果和表达式的值。 An expression is composed of one or more operands and yields a result when it is evaluated. int a = 3, b = 3; cout << ++a << endl; cout << a << endl; cout << b++ << endl; cout << b << endl; ++a 变量a自增1,表达式的值为自增后的值 4 3 a++ 变量a自增1,表达式的值为自增前的值
Order of evaluation Precedence specifies how the operands are grouped. It says nothing about the order in which the operands are evaluated. In most cases, the order is largely unspecified. int a = Expr1 + Expr2 * Expr3; It is an error for an expression to refer to and change the same object. int a = ++i + i++ * i; // warning: multiple unsequenced modifications to 'i'
Order of evaluation 引用传递,函数改变传入参数的值 值传递,函数不改变传入参数的值 int f(int &x) { return ++x; } int g(int &x) { return x *= 2; } int main( ) { int a = 3; cout << a + f(a) * g(a) << endl; return 0; } int f(int x) { return x + 1; } int g(int x) { return x * 2; } int main( ) { int a = 3; cout << a + f(a) * g(a) << endl; return 0; } 不确定的evaluation顺序,且编译器无法发现。 OK。Evaluation顺序不影响结果。
Short-circuit evaluation The logical AND and OR operators always evaluate their left operand before the right. Moreover, the right operand is evaluated if and only if the left operand does not determine the result. int a = 5, b = 3, c = 7; if ( a++ == 3 || b++ == 3 || c++ == 3) cout << a << “, “ << b << “, “ << c << endl; 6, 4, 7
Assignment The value of an assignment expression is the value of the right-side operand. int a = 5; if ( a = 3 ) cout << “Equal.“; Equal. warning: using the result of an assignment as a condition
Assignment int i = get_value( ); while ( i != 42 ) { // do something } while ( ( i = get_value( ) ) != 42 ) { // do something }
Statements Null statement. Expression statements. ; a + 1; cout << a; ++a; The expression is evaluated but the result is discarded.
Using the null statement vector<int>::const_iterator it = v.begin( ); for ( ; it != v.end( ); ++it) // do something with *it 循环变量的初始化已经在循环头外完成。 if (1 <= a && a <= 5) { // do something } else if (b > 5) { // do something else } else ; // do nothing 补全if-else语句,表示什么也不做。
Scope for (int i = 0; i != 5; ++i) { // do something } cout << i; error: use of undeclared identifier 'i' 1 2 3 4 -1 int i = -1; for (int i = 0; i != 5; ++i) cout << i << endl; cout << i;
Scope // global variable i // local variable i1 // local variable i2 int i = 1; int main( ) { int i = -1; { int i = 0; cout << i << endl; cout << ::i << endl; } cout << i; return 0; // global variable i // local variable i1 // local variable i2 i2生命期结束 1 -1 i1生命期结束
If-else statement 在多重if-else嵌套时要注意if和else的正确配对 int a = 3, b = 4; if (a == 2) { cout << “a == 2\n”; } else if (a == 3) cout << “a == 3\n”; if (b == 3) cout << “b == 3\n”; else cout << “???\n”; 建议if-else语句始终使用括号 C++无视空格缩进,但应使用正确的缩进增强代码的可读性 a == 3 ???
Switch statement switch (Expr) { case Case1: // handle case 1 break; // handle other cases, if any default: // do default execution } Expr必须是整型或者能够被转换成整型 Case1、Case2必须是常数 break语句一般都要有
Switch statement string s = “hello”; switch (s) { case “hello”: cout << “hi\n”; break; case “goodbye”: cout << “bye\n”; default: cout << “…\n”; } error: statement requires expression of integer type
Switch statement int a = 0, b = 1; switch (a) { case 0: cout << a + b << endl; break; case b: cout << a * b << endl; default: cout << a - b << endl; } error: case value is not a constant expression
Switch statement int a = 0, b = 1; switch (a) { case 0: cout << a + b << endl; case 1: cout << a * b << endl; default: cout << a - b << endl; } Case语句提供一个标记,指示程序开始执行的位置。 1 -1
Break, continue & goto A break statement terminates the nearest enclosing while, do-while, for, or switch statement. for (int i = 0; i != 2; ++i) { for (int j = 0; j != 2; ++j) { for (int k = 0; k != 3; ++k){ if (k == 1) break; cout << “(” << i << “, “ << j << “, “ << k << “)\n”; } (0, 0, 0) (0, 1, 0) (1, 0, 0) (1, 1, 0)
Break, continue & goto A continue statement terminates the current iteration of the nearest enclosing loop and immediately begins the next iteration. for (int i = 0; i != 2; ++i) { for (int j = 0; j != 2; ++j) { for (int k = 0; k != 3; ++k){ if (k == 1) continue; cout << “(” << i << “, “ << j << “, “ << k << “)\n”; } (0, 0, 0) (0, 0, 2) (0, 1, 0) (0, 1, 2) (1, 0, 0) (1, 0, 2) (1, 1, 0) (1, 1, 2)
Break, continue & goto A goto statement provides an unconditional jump from to another statement in the same function. for (int i = 0; i != 2; ++i) { for (int j = 0; j != 2; ++j) { for (int k = 0; k != 3; ++k){ if (k == 1) goto break_me_here; cout << “(” << i << “, “ << j << “, “ << k << “)\n”; } break_me_here: // do something (0, 0, 0)
Break, continue & goto 尽可能避免使用goto语句。 从多重循环的深处跳出几乎是goto语句唯一的合理用法。
Next lecture C++ Primer, Chapter 6