运算符

本文详细介绍了C++中的运算符,包括算术运算符、逻辑运算符、关系运算符、位运算符、复合运算符、赋值运算符,以及sizeof和typedef的用法,还有new和delete的使用和内存管理。内容涵盖了各种运算符的执行流程、注意事项和实例演示。
摘要由CSDN通过智能技术生成

 

运算符

[算术运算符][逻辑运算符][关系运算符][运算符][复合运算符][赋值运算符]

运算分类                                                           1)算术运算符

包括:

﹢(加),    ‐(减),    *(乘),    ∕(除),    ﹪(求模),    ++i(自增),    --i(自减),    i++(自增),

i--(自减)

注意:

  • 两个整型相除还为整型,两个负值除法求商中舍去方向一般 ' 向零取整 '
  • 不同类型运算,统一成高精度后再运算

例子:

运算符操作例子:

 int b = 3;
 int c = 0;
 
 c = a+b;   //此时 c 的值为 8
 c = a-b;     //此时 c 的值为 2
 c = a*b;    //此时 c 的值为 15
 c = a/b;     //此时 c 的值为 1
 c = a%b;   //此时 c 的 值为  2
 c = a ++;   //此时 c 的 值为 5
 c = a --;     //此时 c 的值为 6 
 c = ++ a;   //此时 c 的值为 6
 c = --  a;    //此时 c 的 值为 5

那么现在在对 i++,++i为例子(i--与--i同理)说明下他们的区别,由下面例子来说明:

 int c = 0, a = 0, b = 0;
 
 c =  ++a; // 此时 c 为1
 c = a     ;  // 此时 c 为 1
 //由此可以看到 c = ++a 的执行顺序好像是先执行 a 变量的自增 ,然后在执行 c = a 这个操作
 //所以可以这么理解 ++a 表示的是,先把变量a自加,然后再执行++a所在的执行语句
 
 c = b++; // 此时 c 为0
 c = b;      // 此时 c 为1
 //由此可以看到 c = ++b 的执行顺序好像是先执行执行 c = b 这个操作 ,然后在执行  b 变量的自增操作
 //所以可以这么理解 ++b 表示的是,先执行++a所在的执行语句,然后再执行把变量 b 自加这个操作

但是还有一个问题,要是一个语句中有多个 i++ 或者 ++i 呢?是执行多次自加还是只执行一次自加呢?让我们看看一个例子:

 #include <iostream>
 #include <cstdlib>
 
 using namespace std;
 
 void main()
 {
     int c = 0, a = 0, b = 0;
 
     cout<<"两次次使用 ++a"<<endl;
     c =  (++a) + (++a); 
     cout<<"the value of c is "<<c<<endl;
     c = a + a;
     cout<<"the value of c is "<<c<<endl<<endl;
     
     cout<<"两次次使用 b++"<<endl;
     c = (b++) + (b++);
     cout<<"the value of c is "<<c<<endl;
     c = b + b;
     cout<<"the value of c is "<<c<<endl<<endl;
 
     a = 0;//先重新初始化下 变量a
     cout<<"a++ 与 ++a 的混合使用, a++在前"<<endl;
     c =  (++a) + (a++); 
     cout<<"the value of c is "<<c<<endl;
     c = a + a;
     cout<<"the value of c is "<<c<<endl<<endl;
 
     a = 0;//先重新初始化下 变量a
     cout<<"a++ 与 ++a 的混合使用, a++在后"<<endl;
     c = (a++) + (++a); 
     cout<<"the value of c is "<<c<<endl;
     c = a + a;
     cout<<"the value of c is "<<c<<endl<<endl;
 
     a = 0;//先重新初始化下 变量a
     cout<<"一个 a++ 与 两个 ++a 的混合使用"<<endl;
     c = (a++) +(++a) + (++a); 
     cout<<"the value of c is "<<c<<endl;
     c = a + a + a;
     cout<<"the value of c is "<<c<<endl<<endl;
 
     a = 0;//先重新初始化下 变量a
     cout<<"两个 a++ 与 一个 ++a 的混合使用"<<endl;
     c = (a++) + (a++) + (++a); 
     cout<<"the value of c is "<<c<<endl;
     c = a + a + a;
     cout<<"the value of c is "<<c<<endl<<endl;
 
     system("pause");
 }

输出结果:

 现在好像有点头绪了吧,让我们梳理下上面所说的内容:

    • ++i 的执行流程好像就是把 i 的自增这个动作放到了执行语句的首部去执行,然后 i 自增这个动作结束后在回来执行 ++i 所在的执行语句
    • i++ 的执行流程好像就是把 i 的自增这个动作放到了执行语句的尾部去执行,然后执行完 i++ 所在的执行语句后在回来执行 i 自增这个动作
    • 按上面所说的我们在看看上面多个 i++ 和 ++i 组合产生的效果,执行语句先执行语句中的 ++i 让 i 自增n次(n便是在执行语句中 ++i 的次数),然后在执行 i++ 和 ++i 所在的执行语句,然后在执行 i++ 让 i 自增n次(n便是在执行语句中 i++ 的次数)

 

2)逻辑运算符

包括:

&&(与),    ||(或),    !(非)

注意:

最终会以bool值形式返回出来

例子:

 #include <iostream>
 #include <cstdlib>
 
 using namespace std;
 
 void main()
 {
     bool a;
     a = ( 5+10 == 15 ) && ( 5+10 == 5 );
     cout<<"a = ( 5+10 == 15 ) && ( 5+10 == 5 ) ?   "<<a<<endl;
     a = ( 5+10 == 15 ) || ( 5+10 == 5 );
     cout<<"a = ( 5+10 == 15 ) || ( 5+10 == 5 ) ?   "<<a<<endl;
 
     a = 0;
     a = !a;
     cout<<"a=0  !a= ?   "<<a<<endl<<endl;
 
     system("pause");
 }
 
 /*******************************************
 输出结果:
 a = ( 5+10 == 15 ) && ( 5+10 == 5 ) ?   0
 a = ( 5+10 == 15 ) || ( 5+10 == 5 ) ?   1
 a=0  !a= ?   1
 
 请按任意键继续. . .
 ********************************************/

3)关系运算符

包括:

<(小于),    <=(不大于),    >(大于),    >=(不小于),    ==(等于),    !=(不等于)

注意:

最终会以bool值形式返回出来

例子:

View Code 
 bool a = 0;
 a = 5>10;    //a = 0
 a = 5<10;    //a = 1
 a = 5>=10;  //a = 0
 a = 5<=10;  //a = 1
 a = 5==10;  //a = 0
 a = 5!=10;  //a = 1


4)位运算符

包括:

~ (取反),    &(位与),    | (位或),    ^ (位异或) ,    <<(左移) ,    >>(右移)

注意:

  • 所有位运算的处理都是建立在数据的内容以2进制形式
  • 左移形式:number<<n,将操作数number左移n位,丢弃移出位,以0填充

例子:

 unsigned double b = 0xffffffff,c = 0x0000ffff;
 
 cout<<hex;//把输出改为十六进制
 
 cout<<"the value of b is "<<b<<endl;
 cout<<"the value of c is "<<c<<endl<<endl;
 
 cout<<"c & b  then  "<<(c&b)<<endl;
 cout<<"c | b  then  "<<(c|b)<<endl;
 cout<<"c ^ b  then  "<<(c^b)<<endl;
 cout<<"~c     then  "<<~c<<endl;
 cout<<"c<<4   then  "<<(c<<4)<<endl;
 cout<<"c>>4   then  "<<(c>>4)<<endl;

输出结果:

 

5)复合赋值运算符

包括:

+=(加x等于),    -=(减x等于),    *=(乘x等于),    %=(除x取模等于),    /=(除x等于),

>>=(向右移n位等于),    <<=(向右移n位等于),    &=(与x与位等于),    ^=(与x异或位等于),

|=(与x或位等于)

解释:

我们以 += 为例,其他的也都一样,那么我们来看下面这个例子

int a = 0;
a += 1;   //此时 a 的值为 1, 其实这个就等价于 a = a +1;
a += 5+9;   //此时 a 的值为 15 , 道理同上,只是现在的 = 号的右边换成了表达式而已,也就是等价于 a = a + (5+9)


6)赋值运算符

说明:

对对变量赋值,格式为 变量名 = 表达式 or 常量 or 变量 or 有返回值的函数调用;

例子:

// 例1 ---
int max(int a; int b)
{
	return a>b?a:b;
}
void main() 
{
	int a, b, c, d;
	a = 0xff8;  //用常量赋值给变量, 十六进制赋值, 十进制表示为 4008,所以 a 值为 4008 
	b = a;        //用变量赋值给变量,所以 b 值为 a 值为 4008
	c = a+b;    //用表达式赋值给变量,所以 c 值为 a 值加上 b 值为 8016
	d = max(a,c);   //用函数返回值赋值给变量,所以 d 值为 8016
}

// 例2 ---
unsigned char a;
a = 0xff8;   //在变量赋值时候,若左边的值大于变量的所能存放的容量时候,会截取后半段,舍弃超出存储界限的前半段,所以此时 a 为 0xf8

[返回目录]



sizeof与typedef

 

---sizeof---------------------------

用法:

  • sizeof(object变量名 / 常量)
  • sizeof (typename类型名 )

说明:

  • sizeof(object变量名 / 常量)括号可加可不加,此时变量名,常量被解析成相对应的类型,返回类型占得内存字节数
  • sizeof(typename类型名) 例如 sizeof(int)括号必须有,返回类型占得内存字节数

例子:

 // 例子 -- 
  void main()
  {
      int ia;
      short sa;
 
      cout<<"整型变量的占用内存空间为:  "<<sizeof(ia)<<" 字节"<<endl;
      cout<<"短整型变量的占用内存空间为:  "<<sizeof(short)<<" 字节"<<endl;
  }
 /********************************
 整型变量的占用内存空间为: 4
 短整型变量的占用内存空间为:  2
 ********************************/

---typedef--------------------------

用途:

定义类型的同义词 <不是简单的宏替换>

格式:

  • typedef 类型 自定义名;
    此时声明变量时候可有两种方法:(1)类型 变量名;(2)自定义名 变量名; 
  • typedef* 类型 自定义名;
    此时声明指针时候可有两种方法:(1)类型* 指针变量名;(2)自定义名 指针变量名; 
  • typedef 返回类型 (*自定义名)();
    此时声明函数指针的时候可有两种方法:(1)类型 (*函数指针名) ();(2)自定义名 函数指针名; 

陷阱:

  • typedef在语法上是一个存储类型的关键字(与auto一样)虽然它并不影响对象的存储性质,但不能与auto,static,register,extern,mutable连用
  • typedef定义了一个类型的新别名,比如typedef char*PSTR,然后 int mystrcmp(const RSTR)const在这里给予了char*整个const的属性,所以const RSTR在这里为char* const

目的:

  • 为了隐藏特定类型,强调使用类型的目的
  • 允许一个类型有多个别名,使类型使用时目的明确易懂,跃过平台无关类型的限制
  • 简化结构体名<例:typedef struct tagPOINT{int x,y} Point;Point p1>
  • 为复杂的声明定义一个简单的别名

--------------------------------------------------------------------------------------------------------------

例子:

typedef int heigh;  //以后就可以用 heigh 来定义 int 类型 变量
heigh i;  //等价于  int i

来看个更复杂的例子:

typedef int*(*pfuc)(int ,char*); //以后可以用 pfuc 来定义函数指针
pfuc a;   //等价于函数指针定义 int*(*a)(int,char *) 

点这里查看变量定义

 

[返回目录]



new与delete

 

---new--------------------------

形式:

  • 结构 typename *point_name=new typename                          
    •  (解释:  typename *point_name为声明指针类型名,new typename声明分配空间类型)
  • 类 typename *point_name=new typename(构造函数参数表)         
    • (解释:typename *point_name声明指针类型名,new typename(构造函数参数表)声明分配空间类型)
  • 数组 typename *point_name=new typename[]                          
    • (解释:typename *point_name声明指针类型名,new typename[]声明分配空间类型) 

说明:

由于point_name为地址,new动态生成的结构体无名称,不能用*point_name . 成员名来访问成员,但由于()优先级高,所以可以用(*point_name).   成员名来访问或用point_name -> 成员名

例子:

用new开辟变量,数组,类的例子:

View Code 
 // 例1 -- 开辟变量
 int *a = new int(0);  //开辟变量并初始化变量为0,当然也可以开辟不初始的变量如: int *a = new int
 
 //例2 -- 开辟数组
 int *a = new int[5];  //开辟数组,数组长度为5
 
 //例3 -- 开辟类实例
 class A
 {
     int a ;
 };
 void main ()
 {
    A* a = new A();  //如果有构造函数有参数在括号中传递参数,如果有默认构造函数(即无参数的构造函数)括号可加可不加
 }

 用new开辟的类调用其成员函数或成员的例子:

 class A
 {
 public:
     void show(){cout<<"hello!"}<<endl;
 };
 void main()
 {
     A* a = new A;
     a->show();
     (*a).show();
 }


---delete-------------------------

形式:

  • 变量 delete point_name
  • 数组 delete []point_name

例子:

View Code 
 class A
 {
 public:
     void show(){cout<<"hello!"}<<endl;
 };
 void main()
 {
     int *a = new int(0);
     int *b = new int[5];
     A* c = new A;
 
     delete a;  //释放指针 a 指向的用new开辟出的变量内存
     delete[] b;   //释放指针 b 指向的用new开辟出来的数组的内存 
     delete c;   //释放指针 c 指向的用new开辟出来的类的实例的内存
 }

---new与delete使用说明----------

  • 用new生成的变量/结构体/[]point_name(数组)用delete来释放
  • delete释放的都是new指针指向的内存,而不会删掉指针本身
  • 用new或new val[]分配的内存由delete或delete[]val来释放
  • 对空指针应用delete是安全的
  • 不能用sizeof操作符来确定动态分配数组包含的字节数
  • new与delete必须互相兼容,new与delete,new[ ]与delete[ ]

 

[返回目录] 



C++操作符的优先级

 

 

操作符及其结合性

功能

用法

L
L
L

::
::
::

全局作用域 
类作用域 
名字空间作用域

::name
class::name
namespace::name

L
L
L
L
L

.
->
[]
()
()

成员选择 
成员选择 
下标 
函数调用 
类型构造 

object.member
pointer->member
variable[expr]
name(expr_list)
type(expr_list)

R
R
R
R
R

++
--
typeid
typeid
显示强制类型转换 

后自增操作 
后自减操作 
类型ID
运行时类型ID
类型转换 

lvalue++
lvalue--
typeid(type)
typeid(expr)
cast_name<type>(expr)

R
R
R
R
R
R
R
R
R
R
R
R
R
R

sizeof
sizeof
++
--
~
!
-
+
*
&
()
new
delete
delete[]

对象的大小 
类型的大小 
前自增操作 
前自减操作 
位求反 
逻辑非 
一元负号 
一元正号 
解引用 
取地址 
类型转换 
创建对象 
释放对象 
释放数组

sizeof expr
sizeof(type)
++lvalue
--lvalue
~expr
!expr
-expr
+expr
*expr
&expr
(type)expr
new type
delete expr
delete []expr

L
L

->*
.*

指向成员操作的指针 
指向成员操作的指针

ptr->*ptr_to_member
obj.*ptr_to_member

L
L
L

*
/
%

乘法 
除法 
求模(求余)

expr * expr
expr / expr
expr % expr

L
L

+
-

加法 
减法

expr + expr
expr - expr

L
L

<< 
>>

位左移 
位右移

expr << expr
expr >> expr

L
L
L
L


<=

>=

小于 
小于或等于 
大于 
大于或等于

expr < expr
expr <= expr
expr > expr
expr >= expr

L
R

==
!=

相等 
不等

Expr == expr
Expr != expr

R

&

位与

Expr & expr

R

^

位异或

Expr ^ expr

R

|

位或

Expr | expr

R

&&

逻辑与

Expr && expr

R

||

逻辑或

Expr || expr

R

?:

条件操作

Expr ? expr : expr

R
R
R
R
R

=
*=,/=,%=
+=,-=
<<=,>>=
&=,|=,^=

赋值操作 
符合赋值操作 

Lvalue= expr
Lvalue+= expr
…… 

R

throw

抛出异常

Throw expr

L

,

逗号

Expr, expr

前缀递增/递减与解除引用优先级相同;后缀递增/递减高于解除引用

 

[返回目录]

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值