运算符
包括:
﹢(加), ‐(减), *(乘), ∕(除), ﹪(求模), ++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++ 的次数)
包括:
&&(与), ||(或), !(非)
注意:
最终会以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
请按任意键继续. . .
********************************************/
包括:
<(小于), <=(不大于), >(大于), >=(不小于), ==(等于), !=(不等于)
注意:
最终会以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
包括:
~ (取反), &(位与), | (位或), ^ (位异或) , <<(左移) , >>(右移)
注意:
- 所有位运算的处理都是建立在数据的内容以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;
输出结果:
包括:
+=(加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)
说明:
对对变量赋值,格式为 变量名 = 表达式 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 | :: | 全局作用域 | ::name |
L | . | 成员选择 | object.member |
R | ++ | 后自增操作 | lvalue++ |
R | sizeof | 对象的大小 | sizeof expr |
L | ->* | 指向成员操作的指针 | ptr->*ptr_to_member |
L | * | 乘法 | expr * expr |
L | + | 加法 | expr + expr |
L | << | 位左移 | expr << expr |
L | < | 小于 | expr < expr |
L | == | 相等 | Expr == expr |
R | & | 位与 | Expr & expr |
R | ^ | 位异或 | Expr ^ expr |
R | | | 位或 | Expr | expr |
R | && | 逻辑与 | Expr && expr |
R | || | 逻辑或 | Expr || expr |
R | ?: | 条件操作 | Expr ? expr : expr |
R | = | 赋值操作 | Lvalue= expr |
R | throw | 抛出异常 | Throw expr |
L | , | 逗号 | Expr, expr |
前缀递增/递减与解除引用优先级相同;后缀递增/递减高于解除引用 |