拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 《C++自学入门》3.基本资料型别-3

《C++自学入门》3.基本资料型别-3

白鹭 - 2022-03-02 2093 0 0

1.C++算术运算子

1.1  基本运算子

    读者可能还对学校里的算术练习记忆犹新,在计算机上也能够获得同样的乐趣,C++使用运算子来运算,它提供了几种运算子来完成五种基本的算术运算:加法、减法、乘法、除法以及求模,每种运算子都使用两个值来计算结果,运算子及其操作数构成了表达式,例如:int wheels = 4 + 2;4和2都是操作数,+是加法运算子,4+2则是一个表达式,加减乘除就不多赘述了,只说一下取余:%,5%2结果就是1,因为余数就是1,而且%的操作数只能是整数,

1.2  优先性和结合性

    <1> int a = 2 - 3 * 4 + 5;操作数3旁边有两个运算子 - 和 *,当多个运算子可用于同一个操作数时,C++使用优先级规则来决定先使用哪个运算子,和我们小数学的四则运算一样,先乘除,再加减,答案为-5,优先级*、/、%同级,

    <2> float logs = 120 / 4 * 5;有时候优先级串列并不够用,操作数4也位于两个运算子之间,但运算子乘除一样,计算机该怎么计算呢,这里答案是6,因为C++的结合性,将从右往左运算,

    <3> int dues = 20 / 4 + 2 * 3;仅当两个运算子被用于同一个操作数时,优先性和结合性规则才有效,优先级表示在做加法之前必须计算除法和乘法,但是优先级和结合性都没有指出应该先计算20 / 4还是2 * 3;事实上,C++吧这个问题留给了实作,让它来决定在系统中的最佳顺序,

    运算子优先性和结合性在C++中远远不止这幺一点,当逻辑运算子,算术运算子,关系运算子等结合在一起时,那才是脑壳大(我们后面慢慢来),

2.型别转换

2.1  隐式转换

    C++丰富的型别允许根据需要选择不同的型别,这也使计算机的操作更复杂,例如,将两个short值相加涉及到的硬件编译指令可能会与两个long值相加不同,由于有11种整型和3种浮点型别,因此计算机需要处理大量不同的情况,尤其是对不同的型别进行运算时,为处理这种潜在的混乱,C++自动执行很多型别转换==>>:

一、将一种算术型别的值赋给另一种算术型别的变量时,C++将对值进行转换;        二、表达式种包含不同的型别时,C++将对值进行转换;                            三、将自变量传递给函式时,C++将对值进行转换,

    如果程序员不知道进行这些自动转换时将发生的情况,将无法理解一些程序的结果,<1>隐式转换:低精度-》高精度,有符号-》无符号,优先级:int -> unsigned int -> long -> unsigned long -> long long -> unsigned long long -> float -> double -> long double,比如说宁不小心把一个浮点数赋值给了整型:--> int a =  1.34;根据隐式转换,C++将直接丢弃小数部分,所以a = 1;(注意是直接丢弃,而不是四舍五入!),继续:--> int b = 7.2E12;

整型变量无法存盘7.2E12,这导致C++没有对结果进行定义的情况发生,在我这种系统中b的值为2147483647,在不同编译器上,值也不一定是这个,

下面看一个经典例子:

查看代码
#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
	unsigned int a = 6;
	int b = -20;
	
	cout << hex << b << endl;
	cout << hex << a + b << endl;
	
	if(a + b > 0)
		cout << "ok!" << endl;
	else
		cout << "error!" << endl;
	
	
	return 0;
}

利用iomanip头档案可以让输出输入格式化,这里我们用cout打印16进制,if else是简单的条件分支陈述句,满足a + b > 0就会执行 cout << "ok!" << endl;不满足就执行else后面的陈述句,

我们可以猜猜结果是打印ok还是error,可能大家会觉得a + b不就是-14吗,肯定会打印error,其实不然,结果是ok,我们知道一、有符号会向无符号隐式转换,二、无符号最高位不表示符号,三、整型资料在计算机的存盘,-->(https://www.cnblogs.com/hbnb/p/15783996.html)我们根据这些就可以推断出结果,步骤如下:

首先将6和-20都转换为二进制:a = (前面28个0)0110;b = (前面24个1)1110 1100;我们把两个相加,结果为:(前面28个1)0010;令人震惊的是,无符号最高位不是符号位,那么结果显而易见了,a + b的结果为0xfffffff2,也就是4294967282,这当然是大于0的了,所以会打印ok,

2.2  强制转换

    Ok,Anyway!上面是一个经典的隐式转换的例子,<2>下面看看强制转换:除了隐式转换规则,C++还允许通过强制转换机制直接转换型别:

int a = 9; long b = (long) a; long c = long (a);这会将int型别的a强制转换为long的值,强制转换并不是修改a本身,而是创建一个新的值,供给表达式使用,强制转换有两种格式,(long) a来自C语言,long (c)是C++新的强制转换规则,这看起来像函式呼叫一样,

还需要注意的是,在进行运算时,会先运算后转换型别:比如 int auks = 19.99 + 11.99; a的值就是31,(又来挖坑了,C++还有四个强制转换运算子,对它们的使用要求更加严格,或者以后不止是简单的基本资料型别的转换,还有不同型别别的转换,咱们慢慢来吧),

2.3  auto宣告

    C++11新增了一个工具,让编译器能够根据初始值的型别推断变量的型别,为此,它重新定义了C语言中auto的含义,在初始化宣告中,如果使用关键字auto,而不是指定变量的型别,编译器将把变量的型别设定成与初始值相同

auto x = 100;// x is int
auto y = 1.5;//y is double
auto z = 1.3e12L;//z is long double

auto的优势当然不是为了处理这些简单情况,在处理复杂型别时,如STL中的型别时,自动型别推断有时才能显现出来,例如,对于下述C++98代码:

std::vector<double> scores;
std::vector<double>::iterator pv = scores.begin();
//C++11允许将其重写为这样:
std::vector<double> scores;
auto pv = scores.begin();

看不懂没关系,后面会讲到的,路漫漫其修远兮,吾将上下而求索,

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *