C++算术运算符与类型转换
1、算术运算符C当中提供5种基础的算术运算符加法、减法、乘法、除法和取模。我们来看下代码1234567inta 10, b 3;cout a b endl;// 13cout a - b endl;// 7cout a * b endl;// 30cout a / b endl;// 3cout a % b endl;// 1前面三个都非常简单着重讲下最后两种。对于除法来说我们要注意的是它是区分类型的。当我们的除数和被除数都是整数的时候得到的结果也会是一个整数。所以10 ➗ 3得到的结果就是3它的小数部分会被抛弃。想要得到小数结果只需要除数或者被除数当中有一个是浮点型即可。取模运算符求的就是一个数除以另外一个数之后的余数。这里要注意在其他语言当中并没有对取模运算的限制而在C当中严格限制了取模运算的对象只能是整数。否则编译的时候会报错2、优先级C当中算术运算符的优先级和我们从小数学课本里是一样的先乘除再加减。如1233 4 * 5;// 23120 / 4 * 5;// 15020 * 5 4 * 6;// 124即当乘除法和加减法同时出现时先算乘除后算加减。如果有多个运算符同样优先级那么先左后右。3、类型转换前面说了同样是除法根据除数和被除数类型的不同得到的结果也不同。这样固然非常灵活但是除了更加复杂给学习、使用者带来负担之外也会使得计算机的操作更加复杂。比如我们一共有11种整型和3种浮点型那么我们在计算的时候就会出现大量不同的情况。比如short shortshort intshort double等等那么编译器就需要对这么多种情况都进行处理这显然是非常麻烦的。为了解决这个问题C会自动执行许多类型转换。下面我们对这些情况进行一一讨论。初始化和赋值时的转换当我们对某个值进行初始化或者赋值的时候C会自动将赋予的值转化成接收者的类型。比如12floata 3.5f;doubleb a;在上面这个例子当中我们将一个float类型的变量a赋值给了double类型的b。那么编译器会将a的值拓展成64位的double再赋值给b。也就是说不会影响b的类型。这样将长度更短的变量转化成更长变量的类型转换除了多占用一点内存之外不会导致什么问题。但反向操作可能就会出错比如12longlonga 0x3f3f3f3f3f3f3f;intb a;在上面的例子当中我们将一个long long赋值给了int由于a的数值非常大超过了int能够承载的范围进行这样的赋值之后编译器并不会报错甚至不会有警告但将会导致结果错误。b变量将不可能再和a变量相等。再比如将float变量赋值给int的时候同样也会有类似的问题所以在进行赋值的时候当两个变量的类型不同时千万要当心。使用花括号进行转换这是C 11的新特性使用大括号进行初始化这种操作被称为列表初始化。这种方式的好处和坏处都很明显好处是它不允许变量长度缩窄的情况坏处则是又增加了学习的成本。例如不允许将浮点型转换成整型。在不同的整型之间以及整型转化成浮点型的操作可能被允许取决于编译器知道目标变量能够正确地存储赋给它的值。比如可以将int类型赋值给long因为long总是至少与int一样长反向操作则会被禁止。12345inta 0x3f3f3f3f;longb {a};// 允许longa 0x3f3f3f3f;intb {a};// 禁止关于列表初始化C primer当中还列举了一个非常有意思的case1234567891011constintx 55;charc {x};// 允许intx 55;charc {x};// 禁止constintx 1255;charc {x};// 禁止constintx 1255;charc x;// 允许会警告这是为什么呢因为我们加了const修饰之后编译器就明确知道了x的值就等于55它在char类型的范围内所以允许将它转化成char。如果不加const那么在编译器看来x是一个int型的变量它的范围要大于char所以会禁止。即使我们加了const修饰如果x的值过大超过char的范围也同样会被禁止。4、表达式中转换当一个表达式当中出现多个变量类型的时候C也会进行转换。由于可能涉及的情况非常多使得这个转换的规则也会比较复杂。表达式时C会将bool、char、unsigned char、signed char和short全部转换为int对于bool类型来说true会被转化成1false转换成0其他类型的转换应该都很好理解都是将范围更小的变量转化成范围更大的int这种转换称作整型提升。因为通常int类型都是计算机最自然的类型也意味着计算机在处理int的时候处理的速度最快。将不同类型进行运算的时候也会做一些转换。比如将int和float相加的时候由于涉及到两种类型其中范围较小的那个会被转换成较大的类型。比如如果我们计算9.0 / 5那么编译器会先将5转化成5.0再进行除法运算这样得到的结果自然也是一个double。C11的规范中除了一个类型转换的校验表我们可以参考一下校验表理解一下类型转换的过程。如果有一个数类型是long double则将另外一个数也转成long double否则如果有一个数类型是double则将另外一个数也转成double否则如果有一个数类型是float则将另外一个数也转成float否则说明所有操作数都是整数执行整型提升