运算符
运算符指定了对操作数所进行的运算类别。
赋值运算符
C++语言提供了两类赋值运算符:基本赋值运算符和复合赋值运算符,具体说明如下。
- 基本赋值运算符:=。
- 复合赋值运算符:+=、−=、*=、/=、%=、<<=、>>=、&=、^=、|=。
赋值运算符都是双目运算符,结合性都是右结合,即赋值表达式的运算顺序是从右向左进行的
sum1 = sum2 = 0; //相当于sum1 = (sum2 = 0),先执行sum2=0,后执行sum1 = sum2.
n1 = 0;
C++语言要求赋值运算符左边的操作数必须是左值
x = 3+5; //正确
x+3 = 5; //错误
当同一个变量出现在赋值运算符的两边时,可以用复合赋值运算符表示。复合赋值运算符被视为一个整体,中间不能用空格隔开
x *= 2; //相当于x = x * 2.
x += 1; //相当于x = x + 1.
赋值运算符的优先级是同级的
算术运算符
C++语言提供了7个算术运算符:+(正)−(负)+−*/ %。
加法(+)、减法(−)和乘法(*)运算符的功能分别与数学中的加法、减法和乘法的功能相同,分别计算两个操作数的和、差、积。
除法运算符(/)要求运算符右边的操作数不能为0,其功能是计算两个操作数的商。当/运算符作用于两个整数时,进行整除运算。
%运算符要求两个操作数必须是整数,其功能是求余。
16/3 //整除运算,结果为5
15.3/3 //普通除法,结果为5.1
13%5 //取余,结果为3
算术运算符的优先级为:(单目+、−)高于(*、/、%)高于(双目+、−)。
比较运算符
比较运算符的功能是对项目内的数据进行比较,并返回一个比较结果。
运算符 | 说明 |
---|---|
mm==nn | 如果mm等于nn则返回true,反之则返回false |
mm!=nn | 如果mm不等于nn则返回true,反之则返回false |
mm<nn | 如果mm小于nn则返回true,反之则返回false |
mm>nn | 如果mm大于nn则返回true,反之则返回false |
mm<=nn | 如果mm小于等于nn则返回true,反之则返回false |
mm>=nn | 如果mm大于等于nn则返回true,反之则返回false |
逻辑运算符
C++语言提供了3个逻辑运算符,用于表示操作数之间的逻辑关系:!,&&和||。
- 逻辑非(!)是单目运算符,其功能是对操作数进行取反运算。当操作数为逻辑真时,!运算后结果为逻辑假(0),反之,若操作数为逻辑假,!运算后结果为逻辑真(1)。
- 逻辑与(&&)和逻辑或(||)是双目运算符。当两个操作数都是逻辑真(非0)时,&&运算后的结果为逻辑真(1),否则为0;当两个操作数都是逻辑假(0)时,||运算后的结果为逻辑假(0),否则为逻辑真(1)
!(3>5) //结果为1
5>3 && 8>6 //结果为1
5>3 || 6>8 //结果为1
自增自减运算符
自增(++)、自减(−−)运算符是C语言和C++语言所特有的运算符,它们是单目运算符。运算符++和−−是一个整体,中间不能用空格隔开。++是使操作数按其类型增加1个单位,−−是使操作数按其类型减少1个单位。
自增、自减运算符可以放在操作数的左边,也可以放在操作数的右边,放在操作数左边的称为前缀增量或减量运算符,放在操作数右边的称为后缀增量或减量运算符。前缀增量或减量运算符与后缀增量或减量运算符的关键差别在于:表达式求值过程中增量或减量发生的时间。
- 前缀增量或减量运算符是先使操作数自增或自减1个单位,然后使之作为表达式的值;
- 后缀增量或减量运算符是先将操作数的值作为表达式的值,然后再使操作数自增或自减1个单位。
位运算符
在C++中提供了6种位运算符,功能是进行二进制位的运算
设A的值为60,B的值为13
运算符 | 描述 | 实例 |
---|---|---|
& | 如果同时存在于两个操作数中,二进制 AND 运算符复制一位到结果中。 | (A & B) 将得到 12,即为 0000 1100 |
| | 如果存在于任一操作数中,二进制 OR 运算符复制一位到结果中。 | (A | B) 将得到 61,即为 0011 1101 |
^ | 如果存在于其中一个操作数中但不同时存在于两个操作数中,二进制异或运算符复制一位到结果中。 | (A ^ B) 将得到 49,即为 0011 0001 |
~ | 二进制补码运算符是一元运算符,具有"翻转"位效果,即0变成1,1变成0。 | (~A ) 将得到 -61,即为 1100 0011,一个有符号二进制数的补码形式。 |
<< | 二进制左移运算符。左操作数的值向左移动右操作数指定的位数。 | A << 2 将得到 240,即为 1111 0000 |
>> | 二进制右移运算符。左操作数的值向右移动右操作数指定的位数。 | A >> 2 将得到 15,即为 0000 1111 |
unsigned int a = 60; // 60 = 0011 1100
unsigned int b = 13; // 13 = 0000 1101
int c = 0;
c = a & b; // 12 = 0000 1100
c = a | b; // 61 = 0011 1101
c = a ^ b; // 49 = 0011 0001
c = ~a; // -61 = 1100 0011
c = a << 2; // 240 = 1111 0000
c = a >> 2; // 15 = 0000 1111
求字节数运算符
C++提供了一个有用的运算符sizeof,它是一个单目运算符,用于计算表达式或数据类型的字节数,其运算结果与不同的编译器和机器相关。当编写用于进行文件输入/输出操作或给动态列表分配内存的程序时,用户将发现,如能知道程序给这些特定变量所分配内存的大小将会很方便。
sizeof(类声明符/表达式)
举例如下
sizeof( int) //结果 为 4
sizeof( 3+ 3. 6) //结果 为 8
可用利用sizeof返回的字节数计算变量的数据范围,从而检查和避免溢出。
条件运算符
条件运算符是C++中唯一的三目运算符,也是被称为三元运算符。
a ? b : c
a一般为一个条件表达式,当a为真时,表达式的值为b的值;当a为假时,表达式的值为c的值。b、c可以是数据,也可以是表达式或者函数。可以视为一个简化写法的if语句。
其他运算符
逗号运算符:多个表达式可以用逗号组合成一个表达式,即逗号表达式。逗号运算符带两个操作数,返回值是右操作数。
表达式 1, 表达式 2,……, 表达式 n
它的值取表达式n的值。
a = 10,11,12; //a = 12
计算顺序是从左至右依次计算各个表达式的值,最后计算的表达式的值和类型便是整个表达式的值和类型.
其他
类型 | 运算符 | 例子 |
---|---|---|
全局变量或全局函数 | ::(全局) | ::GetSystemDirectory |
类中的域变量或函数 | ::(类域) | CWnd::FromHandle |
括号及函数调用 | () | (a+b)*(a−b) |
指针指向的结构或类种的域变量 | −> | (CWnd*wnd)−>FromHandle |
结构或类中的域变量 | . | (CWndwnd).FromHandle |
数组下标运算符 | [] | nYearsMonthsDays[10][12][366] |
内存分配运算符 | new | newCWnd |
内存释放运算符 | delete | delete(CWnd*wnd) |
其他相关
C++中预定义的运算符的操作对象只能是基本数据类型。但实际上,对于许多用户自定义类型(例如类),也需要类似的运算操作。这时就必须在C++中重新定义这些运算符,赋予已有运算符新的功能,使它能够用于特定类型执行特定的操作。运算符重载的实质是函数重载,它提供了C++的可扩展性,也是C++最吸引人的特性之一。
C++运行时的多态性主要是通过虚函数来实现的,而编译时的多态性是由函数重载和运算符重载来实现的。
当不同的运算符混合运算时,运算顺序是根据运算符的优先级而定的,优先级高的运算符先运算,优先级低的运算符后运算。在一个表达式中,如果各运算符有相同的优先级,运算顺序是从左向右,还是从右向左,是由运算符的结合性确定的。所谓结合性是指运算符可以和左边的表达式结合,还是可以与右边的表达式结合。
表达式
任何合法的变量、常量、运算符、函数的有机组合都可以称为表达式,表达式说明了一个概念或模型。C++表达式的功能是:把变量和字面值组合起来进行特点运算处理,以实现特定的应用目的。所有的表达式都是由运算符和被操作数(可以是数字、文本、常量和变量等)构成的。表达式可以嵌套使用,且任何表达式都可以再作为一个元素去构成更为复杂的表达式。
- 表达式必须是完整的,书写正确的,放在正确的位置,有着正确的语义和正确的操作数。
- 可在表达式中插入任意的Tab键、空格和括号。
- 末尾不能加分号,与语句区别开。
类型转换
在通常情况下,我们会设定指定的类型来定义数据类型。C++很强调数据的类型,我们不能随意把不同数据类型的变量或常量乱赋值。但是在很多情况下有特殊需要,我们必须把数据转换一下,转换为需要的数据类型。C++中的数据类型转换主要有隐式转换和显式转换两种。
-
隐式转换
发生在把“小东西”放到“大箱子”里的时候。大小的判别依据是数据类型的表示范围和精度。当一个变量的表示范围和精度都大于另一个变量定义时的类型,将后者赋值给前者就会发生隐式转换。这种转换不会造成数据丢失。一般的思想是尽可能地保留类型表达式中涉及的值的精度,通过把不同的类型提升到当前出现的最宽的类型来实现。 -
显示转换
形如:
(类型) 表达式;
类型( 表达式);
(类型)( 表达式);
常发生在把“大东西”放到“小箱子”里的时候。若一个变量的表示范围或精度无法满足另一个变量定义时,将后者赋值给前者就需要进行显式转换。显式转换可能会导致部分数据(如小数)丢失。以上的表达方式非常简洁,但是C++并不推荐使用该方式,而推荐使用强制类型转换操作符(包括static_cast、dynamic_cast、reinterpret_cast和const_cast)来完成显式转换
操作符 | 中文名称 | 含义 |
---|---|---|
dynamic_cast | 动态类型转换符 | 支持多态而存在,它主要用于类之间的转换 |
static_cast | 静态类型转换符 | 仅仅完成编译时期的转换检查 |
reinterpret_cast | 再解释类型转换符 | 完成不同类型指针之间的相互转换 |
const_cast | 常类型转换符 | 用来修改类型的const或volatile属性 |