c++Primer——第四章:表达式
1、求值顺序
int i = 0;
cout << i << " " << ++i << endl;
int j = f1() + f2();
在书中提到的cout那一行存在未定义的行为,在实际编程环境中可能会出现不同的执行顺序:一种情况是先计算变量i的值后再执行i++操作;另一种情况则是会先执行i++操作然后再计算变量i的值;对于第二部分代码,并不清楚函数调用的具体顺序是先调用f1还是先调用f2;通过使用Visual Studio和GCC进行测试后发现,在不同编程环境下上述两种情况会呈现一致的结果:即当输入为"上面"时会输出"下面";而当输入为"下面"时则会依次执行f1函数后再执行f2函数的操作;
2、关系运算符
int a = 1, b = 2;
if (a == true)
{
cout << "1" << endl;
}
if (b == true)
{
cout << "2" << endl;
}
当第一个条件为真而第二个条件为假时,则返回值为1。只有在val等于true的情况下才会触发该条件;然而,在实际应用中编辑器采用的是val与数字1的比较方式。具体来说,编辑器采用的判断方式是将val与数字1进行比较。
3、复合运算符
任意一种复合运算符都完全等价于 a = a op b;
int a = 2;
a *= 5 + 3; // a *= 8, a = a*8, a=16
4、位运算
当运算对象为带有符号位的负数值时,则其对运算对象符号位的操作依据机器架构的不同而有所差异;这种情况下进行左移操作可能导致左移后的结果出现不可预知的影响. 此可被视为一种不被允许的操作.
int i = -3;
cout << ( i << 1 ) << " " << (i >> 1) << endl;
vs上输出-6 -2,-6尚可解释,-2完全不知道为什么。
5、sizeof运算符
该运算符用于表示该表达式或类型名称占用的空间量;该运算符遵循右结合特性;其计算结果是一个size_t类型的常数表达式;该运算符的操作对象分为两种情况:
sizeof(type)、sizeof expr
在第二种形式中,在第二种形式中
6、数组到指针的隐式转换
通常在涉及数组的表达式中,在将一个数组作为decltype关键字参数或取地址符、sizeof及typeid运算符的目标时(即上述情况),该自动转换不会发生。类似的场景下,在使用引用来初始化一个数组时(即前述情况),该自动转换也不会发生。
7、按位取反
其表示方法是采用一位符号位与若干位数值位共同表示数值大小的方式.
对于正数而言, 其反码与原码相同.
而对于负数值来说, 其反码是在其对应的原码基础上, 仅将数值部分取反.
在计算补码时, 对于正数值来说, 其补码与其原
看下面的题目(习题4.25)
假设在一台机器上运行某种编译环境时
首先将char型提升为int型
00000000 00000000 00000000 01110001 (原码)
11111111 11111111 11111111 10001110 (取反--反码)
在内存中的存储情况是这样的,在'q'处存放着该数值所对应的二进制补码形式;现在计算出真正的显示数值。
先算反码,反码+1=补码,所以反码为:
11111111 11111111 11111111 10001101 (真正显示值的反码)
取反(符号位不变)
10000000 00000000 00000000 01110010
左移6位
10000000 00000000 00011100 10000000
即 ~'q' << 6 = -7296
