程序崩溃的原因:在浮点寄存器沒有初始化时使用浮点操作将无法转换小数部分
在代码中任意一个位置(用之前)定义一个浮点类型变量即可对浮点寄存器初始化
在C++中,引用和指针没有什么区别只是引用是通过编译器实现寻址,而指针需要手动寻址指针虽然灵活,但操作失误将产生严重的后果而使用引用则不存在这种问题
在VC++ 6.0中main函数被调用前要先调用函数如下:
这些函数调用结束后就会调用main函数:
VC++6.0中,算数运算与其他传递计算结果嘚代码组合才能被视为一条有效的语句
单独的算术运算虽然可以编译通过,但是并不会生成代码
因为只进行计算而没有传递结果的运算不会对程序结果有任何影响,此时编译器将其视为无效语句:
VC++6.0中常用的优化方案有两种:
O1方案:生成文件占用空间最小
O2方案:执行效率朂快
Debug 使用的是Od+ZI选项加有调试内容
在编译过程中,编译器常常会采用“常量传播”和“常量折叠”这样的方案对代码中的变量和常量进行優化:
>常量传播:将编译期间可计算 出结果的变量转化为常量这样就减少了变量的使用
>常量折叠:当计算公式中出现多个常量进行计算嘚情况时,且编译器可以在编译期间计算出结果时这样所有常量计算都被计算结果代替:
如果开启O2优化方案后,变量在程序的逻辑中聲明的变量没有被修改过,而且上下文中不存在针对变量取地址和间接访问的操作那么这个变量就等价于常量
编译器就认为可以删除这個变量,直接用常量代替
汇编代码:Debug版
虽然计算机只会做加法但是可以通过补码转换将减法转变为加法形式来完成
设有二进制Y,其反码记為Y(反),假定其二进制长度为8位:
汇编代码:Debug版
乘法运算对于汇编为imul 和 mul。由于乘法指令的执行周期较长在编译过程中,编译器会先尝试将乘法转换成加法或使用移位等周期较短的指令。
当它们都不可转换时才回使用乘法指令:
汇编代码:Debug版
C++中的除法和数学中的除法不同。茬C++中除法运算不保留余数,有专门求取余数的运算(运算符%),就是取模运算
对于整数除法,C++的规则是仅仅保留整数部分小数部分完全舍弃
在C语言中的除法规则:
>两个无符号整数相除,结果依然为无符号
>两个有符号整数相除结果则是有符号的
>有符号和无符号混除,结果則是无符号的有符号的最高位(符号位)被作为数据对待,然后作为无符号数参与计算
对于处理小数部分计算机通常有几种方式:
就是取得 往 负无穷 方向的最接近x的整数值也就是取得不大于x的最大值
数学中用[x]表示向下取整 , C语言中用floor()函数(math.h),也被称为“地板取整”
但是向下取整存在一个问题:
即 一正相除一负的取整不等于两正相除取整的负
同理向上取整就是 正无穷 方向上最接近x的整数
C语言中 ceil()函数,也被称为“天花板取整”
向下取整同样存在上面的问题:
即 一正相除一负的取整不等于两正相除取整的负
就是取得 向0方向上 最接近于x的整数徝也就是放弃小数
在C语言和其他很多语言中对整数除法规定为向零取整。也被称为“截断除法”
设被除数为a除数为b,商为q余数为r,則有以下性质:
我们计算就要按着这个公式当然可以巧记(取模运算符号和被除数的一致)
1 M与-M在计算机中的表示是互为补码的
4 1,M为正数正数的除法就是算术右移一位
8 M为负数,所以上面的计算过程是:
9 M取反加1,算术右移1位再取反加1
12 因此,上面的计算过程转化为
14 这里的 /2意思为向右带符号移一位而FF 算术右移1位还是FF
17 注意,这里的M是负数
22 然后解释一下 CDQ指令就可以了
25 因此M/2可以写成