C++ Primer_4 表达式

来源:互联网 发布:mousewheel.js使用 编辑:程序博客网 时间:2024/05/21 09:15

4.1 基础

4.1.1 基本概念

重载运算符:
    当运算符作用于类类型的运算对象时,用户可以自定义其含义。因为这种自定义的过程事实上是为已存在的运算符赋予另一种含义,所以称之为重载运算符。IO库的>>和<<运算符以及string对象、vector对象、和迭代器使用的运算符都是重载运算符。

左值和右值:
    左值可以位于赋值语句的左侧,右值则不能。C ++语言中,当一个对象被用作右值的时候,用的是对象的值(内容),当对象被用做左值的时候,用的是对象的身份(在内存中的位置)。

4.1.2 优先级与结合律

算数运算符满足左结合律,若运算符的优先级相同,则按照从左向右的顺序组合运算对象。

4.1.3 求值顺序

对于那些没有指定执行顺序的运算符来说,如果表达式指向并修改了同一个对象,将会引发错误并产生未定义的行为。
int i = 0;cout << i << " " << ++i << endl; // undefined

有四种运算符明确规定了运算对象的求值顺序:
    逻辑与(&&)运算符:先求左侧运算对象的值,只有当左侧为真时才求右侧;
    逻辑或(||)运算符: 先求左侧运算对象的值,只有当左侧为假时才求右侧; 仅当左侧无法确定表达式结果时才求右侧
    条件(?:)运算符:先求条件的值
    逗号(,)运算符: 先求左侧,然后将求值结果丢弃,真正的结果是右侧表达式的值。

1. 拿不准的时候用括号强制;
2. 如果改变了某个运算对象的值,在表达式的其他地方不要再使用这个运算对象。

4.2 算术运算符

整数相除结果还是整数,若商含有小数,直接摒弃。
(-m)/n and m/(-n)are always equal to -(m/n);
m%(-n) is equal to m%n ;
(-m)%n is equal to -(m%n) .

4.3 逻辑和关系运算符

关系运算符比较运算对象的大小关系并返回布尔值!(都满足左结合律)
// oops! this condition compares k to the bool result of i < jif (i < j < k) // true if k is greater than 1!

// ok: condition is true if i is smaller than j and j is smaller than kif (i < j && j < k) { /* ... */ }

4.4 赋值运算符

因为赋值运算符的优先级相对较低,通常需要给赋值部分加上括号。
int i;// a better way to write our loop---what the condition does is now clearerwhile ((i = get_value()) != 42) {// do something ...}

复合赋值形式:
+= -= *= /= %=// arithmetic operators
<<= >>= &= ^= |= // bitwise operators; see § 4.8 (p. 152) 

4.5 递增和递减运算符

cout << *iter++ << endl;// is easier and less error-prone than the more verbose equivalentcout << *iter << endl;++iter;

4.6 成员访问运算符

点运算符合箭头运算符都可以用于访问成员,其中,点运算符获取类对象的一个成员;箭头运算符和点运算符有关, ptr -> men 等价于 (*ptr).men :
string s1 = "a string", *p = &s1;auto n = s1.size(); // run the size member of the string s1n = (*p).size(); // run size on the object to which p pointsn = p->size(); // equivalent to (*p).size()

因解引用运算符的优先级低于点运算符,所以执行解引用运算的子表达式两端必须加上括号,否则含义大不相同:
// run the size member of p, then dereference the result!*p.size(); // error: p is a pointer and has no member named size

4.7 条件运算符

string finalgrade = (grade < 60) ? "fail" : "pass";
允许在条件运算符的内部嵌套另一个条件运算符:
finalgrade = (grade > 90) ? "high pass": (grade < 60) ? "fail" : "pass";
条件运算符满足右结合律。

在输出表达式中使用条件运算符:
    条件运算符的优先级非常低,因此当一条长表达式中嵌套了条件运算子表达式时,通常需在其两端加上括号:
cout << ((grade < 60) ? "fail" : "pass"); // prints pass or failcout << (grade < 60) ? "fail" : "pass"; // prints 1 or 0!cout << grade < 60 ? "fail" : "pass"; // error: compares cout to 60

4.8 位运算符

位运算符作用于 整数类型 的运算对象,并把运算对象看做二进制位的集合;
若运算对象是 小整型 ,则它的值会被自动提升;
尽量仅将位运算符处理无符号类型;

异或运算符:
    若两个运算对象的对应位置  有且只有 一个为1 ,则运算结果该位为1,否则为0 。

移位运算符的优先级不高不低:
比算数低,比关系、赋值、和条件高,使用时最好加上括号
cout << 42 + 10; // ok: + has higher precedence, so the sum is printedcout << (10 < 42); // ok: parentheses force intended grouping; prints 1cout << 10 < 42; // error: attempt to compare cout to 42!

4.9 sizeof 运算符

size_of 运算符返回一条表达式或一个类型名字所占的字节数;
对string对象或vector对象执行size_of 运算只返回该类型固定部分的大小,不会计算对象中的元素占了多少空间。

4.10 逗号运算符


4.11 类型转换


4.12 运算符优先级表



0 0