1、21 % -5; // machine-dependent: result is 1 or -4
21 / -5; // machine-dependent: result -4 or -5
在%和/这两种操作中,如果仅有一个操作数是负数,则要根据不同机器来判断,拿/来说,如果结果的符号同分母,那么结果截断就靠近负无穷,而如果结果符号同分子,则结果截断后就靠近0。
2、如果在程序中这么写:
if (i < j < k) { /* ... */ }
那么会先计算i < k,然后返回一个bool型和k比较,结果就是oops!
3、位运算符:&,|,^
&:如果两个操作数都是1,那么结果就为1,否则结果均为0
|:只要操作数中有1,那么结果就是1,否则结果为0
^:只要操作书不同时为1,那么结果就是1,否则为0
要注意的是,不要和逻辑与和逻辑或混淆,位元算与和或是不同的
4、看了下面的两个例子就知道,直接使用位运算符和bitset的区别了,和使用C-style字符串与string的区别差不多:
bitset_quiz1.reset(27); // student number 27 failed
int_quiz1 &= ~(1UL<<27); // student number 27 failed
bitset的方式很容易懂,但是,用底层位运算符呢?先将一个值为1的unsigned long用<<运算符左移27位,就相当于一个32bit的整数,它的第27bit为1,然后再取反,再和int_quiz1和,最后才得到想要的结果(好辛苦啊~~)
5、cout << 10 < 42; // error: attempt to compare cout to 42!
<<操作符优先级比逻辑运算符高,所以,以上的例子是将cout同42做比较。。。
6、ex5_12给了我们一个很好的提醒:
if (42 = i) // . . .
if (i = 42) // . . .
虽然vc的编译器会给出警告,但是如果编译器不提供,后一个语句都是可以通过编译的,如果从pascal转到c++的程序员就容易犯这样的错误,将赋值当作==用,而如果写成第一种,如果是==可以通过编译,而赋值就不可以,所以可以避免一些低级错误的发生。
7、书中给出一个建议:
对于++和--,当需要的时候才使用后缀的方式(i++)。出于对性能的考虑,i++会造成除了要储存增加后的版本还要保存未增加的版本以便使用,这样就有不必要的开销。所以,书中推荐使用前缀模式(++i)
8、(*p).foo; p是一个类的指针,在使用的时候还要对p进行dereference,而且很容易把()忘记,所以c/c++提供了-〉,这样看起来更简洁些:p->foo;
9、ex5_23
int x[10]; int *p = x;
cout << sizeof(x)/sizeof(*x) << endl;
cout << sizeof(p)/sizeof(*p) << endl;
结果是:
10
1
因为x是一个数组名,sizeof返回一个数组的大小,而*p仅返回一个int型指针的大小
10、
// oops! language does not define order of evaluation
if (ia[index++] < ia[index])
结果是:
if (ia[0] < ia[0]) // execution if rhs is evaluated first
if (ia[0] < ia[1]) // execution if lhs is evaluated first
又是根据编译器决定的,不说什么了,不用就是了,避免这样模棱两可的语句
避免这些复杂问题的方法:
(1)使用括号
(2)避免在同一个语句中改变操作数后又使用它(有例外)
所以,以上的例子应该这样做:
if (ia[index] < ia[index + 1]) {
// do whatever
}
++index;
---end--- next: 5.11. The new and delete Expressions
time:05-9-26 0:22am