亲宝软件园·资讯

展开

C++算术运算符

一枚大果壳 人气:0

1. 前言

编写程序时,数据确定后,就需要为数据提供相应的处理逻辑(方案或算法)。所谓逻辑有2种存在形态:

表达式由2个部分组成:

运算符是计算机语言提供的能对数据进行基本运算操作的功能体。开发者在实现自己的逻辑运算时,需要组合这些运算符来描述自己的逻辑运算过程。

Tip: 可以把C++的运算符看成一种特殊语法格式的函数,或把C++中的函数当成一种特殊的运算符。

在使用运算符时,需要遵守下面的2个基本原则:

2. 运算符种类

C++中的运算符非常多,如下是几类常用的运算符:

使用运算符前,需要理解如下几个概念:

Tip: 只有当两个运算符作用于同一个操作数时,优先级和结合性才有意义。

C++中的基础运算符较多,且因C++是弱类型语言,每一种运算符在使用过程中都存在很多细节问题。算术运算符又是运算符中的基础运算符。

本文试图通过讲解清楚算术运算符,让阅读者了解使用C++运算符时应该注意的事项。

3. 算术运算符

3.1 功能描述

算术运算符用来对数字型数据进行数学语义上的加、减、乘、除。此类中有 5个运算符:

算术运算符是二元运算符。使用时,需要提供2个操作数。

3.2 运算符重载问题

C++可以重载运算符,所谓重载运算符,指同一个运算符可以根据使用时的上下文信息,表现出不同的运算能力。如-运算符, 当作为二元运算符时,用来对操作数进行相减操作。

int num1=30;
int num2=20;
//此处的 - 运算符表现出减法运算能力
int res=num1-num2;
cout<<res<<endl;
//输出结果: 10

当作为一元运算符时,则是取的意思。如下代码:

int num=-10;
int num01=-num;
cout<<num01<<endl; 
//输出结果为 10,负负为正 

同理,+运算符也存在重载。

运算符重载是C++中的一个特色。

对于有符号数据类型而言,如果在字面常量前面没有显示提供正、负符号,则默认为 +(正)符号。

3.3 两数相除的问题

/运算符作用于2个整型数字时,会得到舍弃小数点后的整数部分数值,或称为两数相除的商,意味着会丢失精度。

如下代码:

int num1=7;
int num2=3;
int res=num1/num2;
cout<<res<<endl; 
//输出结果:2,丢失精度

如果要保留两个数字相除的精度,则应该以浮点数据类型的身份进行相除。

double num1=7;
double num2=3;
double res=num1/num2;
cout<<res<<endl; 
//输出结果:2.33333

%运算符作用于2个整型类型的数据时,运算结果是2个数字相除之后的余数部分。如下代码:

int num1=5;
int num2=3;
int res=num1 % num2;
cout<<res<<endl;
//输出结果:2 。

%用于浮点数据类型相除时,会出现编译错误。也就是 %只能用于整型数据的运算,不能用于浮点数据类型。

3.4 关 于/和%运算符的正、负问题

当2个操作数据都是正数时

int num1=21;
int num2=8;
int res=num1 / num2;
cout<<" / 运算:"<<res<<endl;
res=num1 % num2;
cout<<" % 运算:"<<res<<endl;

/%动算符的输出结果都是正数。

/ 运算:2
% 运算:5

当2个操作数都为负数时

int num1=-21;
int num2=-8;
int res=num1 / num2;
cout<<" / 运算:"<<res<<endl;
res=num1 % num2;
cout<<" % 运算:"<<res<<endl;

输出结果,一个是正数,一个是负数。

 / 运算:2
 % 运算:-5

当2个操作数中被除数为负,除数为正时

int num1=-21;
int num2=8;
int res=num1 / num2;
cout<<" / 运算:"<<res<<endl;
res=num1 % num2;
cout<<" % 运算:"<<res<<endl;

输出结果都是负数。

/ 运算:-2
% 运算:-5

当2个操作数中被除数为正,除数为负时

int num1=21;
int num2=-8;
int res=num1 / num2;
cout<<" / 运算:"<<res<<endl;
res=num1 % num2;
cout<<" % 运算:"<<res<<endl;

输出结果为一负一正。

/ 运算:-2
% 运算:5

结论

3.5 数据溢出问题

在使用算术运算符时,有可能出现数据溢出现象。如下代码:

short num=32767;
short num01=num+1;
cout<<num01<<endl;

输出结果:

数字:-32768

无符号short(16位)的类型数据的最大值是 32767,在此数字上加一,num01的值理论是上 32768。但实际结果是 -32768。因为 32768已经超过short范围,编译器会重新计算出一个新的结果(并不是预期值)。这种现象叫数据溢出。

对于无符号 short,可以认为其有 2 部分,一部分为负数,一部分为正数。当正数溢出后,会进入负数部分。

如下代码,因溢出,超过了负数区域最小值,会溢出到正数区域。

short num1=-32768;
short num2=num1-1;
cout<<num2;
//输出结果:32767

数据溢出发生在当把数据类型范围大的数据存储到数据类型小的类型变量中时。

数学运算符也可以用于指针类型运算,因指针变量其数据本质就是数字数据。但指针变量不能用于乘法和除法,加、减的语义是指针的向前后后移动,乘法、除法没有语义价值。

3.6 类型转换

根据运算符的基本使用原则,要求所有操作数的类型必须相同。

有时,在一个表达式中,即使存在多个操作数的类型不一致,也能正常工作。那是因为,编译器会把不同的数据类型转换成一致,然后再进行运算。

由编译器完成的类型转换,称为自动(隐式)类型转换:

碗里的水倒到缸里,不会丢失水。

缸里面的水倒到碗里,如果缸里面的水很少,不够或者刚够一碗水,不会发生水丢失。但是,这里会有潜在丢失问题,因为生活常识告诉我们,缸里面的水往往是要超过一个碗所能盛下的容量。

所以,向下缩窄存在潜在的数据丢失风险。

如下代码,其中发生了2次自动类型转换,有数据丢失的潜在风险。

double num1=7;
int num2=3;
int res=num1/num2;
cout<<res<<endl; 
//输出结果: 2

如下代码,则不会发生数据丢失问题:

double num1=7;
int num2=3;
double res=num1/num2;
cout<<res<<endl; 
//输出结果:2.33333

如下的代码,也会发生自动类型转换。

int num1=20;
char num2='A';
int res=num1+num2;
cout<<res<<endl;
//输出结果: 85

如下代码,也会发生自动类型。

int num1=20;
bool num2=true;
int res=num1+num2;
cout<<res<<endl;

3.7 {}赋值语法

C++在进行自动类型转换时,如果目标类型小于原类型时,也是能够转换的,这种现象叫缩窄。缩窄会存在潜存数据安全问题。C++11提供了{}赋值语法,会对超过范围的缩窄进行编译提示。如下代码。

因 44555 数字已经超过 char 范围,向下缩窄不被允许。

char c1= {44555};

因 X是一个变量,在运行时,x有可能被修改,并让其值大于 char数字范围,向下缩窄不被允许。

int x=66;
char c4={x};

3.8 强制类型转换

C++允许开发者显式地进行类型转换。语法格式有2种:

强制类型转换不会修改变量本身,而是创建一个新的值。用于表达式中进行计算。

double num1=23.6;
//C++强制类型转换语法
int num2=double(num1);
cout<<num2<<endl;
//C 强制类型转换语法
num2=(double)num1;
cout<<num2<<endl;

C++还提供了 4 个类型转换运算符,使得转换过程更规范。这里只做简要介绍,有兴趣者可以深入了解一下。

3.9 auto 语法

auto关键字在C++的作用是自动类型推导。在声明变量时,可以使用 auto关键字,不指定变量的类型说明。编译器会根据变量中所存储的数据的类型自动推导出数据类型。

// num 是浮点数据类型
auto num=5.3;
//num1 是整型数据类型
auto num1=4;

如 PythonJS就是一种动态语言,表现在数据类型可以底层编译器自动识别。

虽然C++有 auto语法,但C++归属于弱类型语言,在数据类型识别上,一半依赖于开发者的语法约束,一半依赖编译器的自动识别。

4. 总结

C++语言的开放性,数据类型的自我适应性非常灵活。在一个表达式,当出现类型不同的情况时,编译器会试图进行各种类型上的转换,让表达式符合类型相同的运算原则。

宽松的好处是速度快,但也会带来潜在的风险,开发者应该尽可能在语法上对数据类型进行约束,不要过于依赖编译器。养成良好的编码习惯。

加载全部内容

相关教程
猜你喜欢
用户评论