C++学习随笔3 计算表达
1. 算术运算问题
中间结果溢出:
#include <iostream> using namespace std; int main() { int a = 100000; int b = 100000; int c = 1000; cout<<a*b/c<<"\n"; cout<<a*(b/c)<<"\n"; }
输出结果:
1410065 (因为a*b = 1*1010 > 232=4294967296,所以a*b = 1*1010 % 4294967296 = 1410065408,所以a*b/c = 1410065408/1000=1410065)
10000000 (没有中间结果溢出,所以计算正常)
浮点数比较:
浮点数判断需要注意,float 和double 的精度范围,超过范围的数字会被忽略
(1) 浮点数大小判断
如果没有等号关系在里面,也就必然一大一小,那么直接用 > 或者 <
(2) 浮点数相等判断
因为浮点数在内存中存放,可能无法精确的储存,所以同一个值,可能有不同的内存数据,所以要使用以下的方法:
以float 为例,32位编译器中精度为有效位数为7,所以取 1e-7。
两个数字 A 、 B,
if ( |A-B| <1e-7 ) 则 A、B相等。
2. 相容类型转换
隐式转换:

如果一个int和一个unsigned long型数相乘,则先将两数都转换成double型数,再进行运算。
精度丢失:
由于参加运算的数据类型,可能先要转换成另外的数据类型(由低精度向高精度转换),进行中间运算,然后再转换回到低精度。因此,有一个从高精度数向低精度数转换的问题,转换中可能会引起精度丢失。
显示转换:
静态转换:static_cast<type>(表达式)
动态转换:dynamic_cast<type>(表达式)
常量转换:const_cast<type>(表达式)
重解释转换(一般用来转换不同类型指针): reinterpret_cast<type>(表达式)
指针的类型表明不同类型的指针,其类型不同,是不能互相赋值的。
例如:
float f = 34.5;
int *ip = &f; //错:float的地址不能赋给int指针
但从地址值的本质来说,无非是用二进制表示的整数而已。因此从内存空间位置性而言,不同类型的指针又是统一的,都是二进制的地址。
int *ip = reinterpret_cast<int*>(&f);
该地址的空间不管放着什么数据,都将它作为整形看待。
3. 表达式的副作用
表达式在求值过程中引发了多于一个的实体值发生改变,称为表达式的副作用。
编译器相关:
例如:
int a=3, b=5; int c = a*b + ++b; cout<<c<<endl;
编译器有可能先计算a*b再计算++b,则c=3*5 + 6 = 21;
也有可能先计算++b,这时b的值已经更改再计算a*b,则c=3*6 + 6 = 24。
交换律失效:
c = a*b + ++b;
d = ++b + a*b;
由于副作用的存在,c和d的值无法相等。
括号失效:
int a =3,b=5;
int c = ++b * (a+b);
由于副作用的存在,括号失效。
消除副作用:
解决副作用的方法是分解表达式语句。
例如:
c=a*b+ ++b;写成
c = b + a*b;
b++;
或者
b++;
c = b + a*b;

浙公网安备 33010602011771号