表达式由一个或多个操作数通过操作符组合而成。最简单的表达式仅包含一个字面值常量或变量。
5.1、算术操作符
求模操作符(%)操作数只能为整型,包括bool、char、short、int和long类型,以及对应unsigned类型。如果两个操作数为正,求模的结果也是正或零;如果两个操作数都是负数,则求模操作的结果为负数或零;如果只有一个值为负,求模结果取决于机器。VS上a%b,求模结果的符号看a的符号。(注,java中%也可用于小数1.2%0.7=0.5,整型正负数求模符号跟C++一样)
5.2、关系操作符和逻辑操作符
if(i<j<k)这么写,只要k>1,上述表达式就恒为true。
5.3、位操作符
C++只有<<和>>两种以为,后者是有符号移位。JAVA有无符号右移>>>。
5.3.1、bitset对象或整型值的使用
bitset优于整型数据的低级直接位操作。
5.3.2、将移位操作符用于IO
移位操作符也是从左向右结合的。cout<<c++<<c++<<c++<<endl;c=0,输出210。
cout<<10<42;<<优先级高于42,会变成(cout<<10)<42;
5.4、赋值操作符
赋值操作具有右结合特性(前提各对象必须具有相同的数据类型或者具有可转换为同一类型的数据类型)。如int a,b;a=b=0;注,不能直接int a=b=0;这样编译不通过。
5.4.3、复合赋值操作符
op=可以是下述十个:+=、-=、*=、/=、%=、<<=、>>=、&=、^=、|=。
5.5、自增和自减操作符
*iter++表示的是*(iter++)。++的优先级比*高···。C++程序员更喜欢使用简洁的表达式而非冗长的等效表达式。
5.6、箭头操作符
(*p).foo;等价于pàfoo;
5.7、条件操作符
条件操作符优先级相当低。cout<<(i<j?i:j);正常,而cout<<(i<j)?i:j;输出i<j的值。cout的返回值看MSDN说是输出流对象(32位地址,针对我自己电脑)···。
5.8、sizeof操作符
(1)对char类型或值为char类型的表达式做sizeof,值恒为1。(2)对引用类型做sizeof操作将返回存放此引用类型对象所需的内存空间大小;(3)对指针做sizeof操作返回存放指针所需的内存空间;(4)数组做sizeof操作等效于将对其元素类型做sizeof操作的结果乘上元素个数。
用int sz = sizeof(ia)/sizeof(*ia);可求数组个数。
5.9、逗号操作符
逗号表达式的结果是其最右边表达式的值。
5.10、复合表达式求值
cout<<(i=k);等价于cout<<k;因此可以这么赋值i=(j=k);等价于i=j=k;
对于ia[index++]<ia[index],C++不能确保从左到右的计算次序,这类表达式的行为没有明确定义。一个表达式里,不要在两个或更多的子表达式中对同一对象做自增或自减操作。可以ia[index]<ia[index+1]
5.11、new和delete表达式
int *pi = new int;//不会初始化,int *pi = new int();//会初始化
int *ps = new string;//会初始化,因为不是内置类型;
如果new表达式无法获取需要的内存空间,系统将抛出名为bad_alloc的异常。
int *ip = 0;delete ip;是合法的,删除0值指针是安全的。
delete指针后,该指针变成悬垂指针(dangling pointer)。一旦删除了指针所指向的对象,立即将指针置为0。
const对象的动态分配:内置类型对象或未提供默认构造函数的类类型对象必须显示初始化,其他则可以通过隐式初始化。
动态内存的管理容易出错:特别是对同一个内存空间使用两次delete表达式,第二次可能导致自由存储区的破坏。
5.12、类型转换
int ival = 0;ival = 3.541 + 3;//这是可以的,只是会有警告。而java则是编译错误。
整型提升:对于所有比int小的整数,如果该类型的所有可能的值都能包容在int内,他们就会被提升为int型,否则为unsigned int(这个在正数方面范围更大)。
显式转换也称为强制类型转换(cast),包括以下列名字命名的强制类型转换操作符:static_cast(编译器隐式执行的任何类型转换都可以由static_cast显示完成)、dynamic_cast(支持运行时识别指针或引用所指向的对象)、const_cast(将转换掉表达式的const性质)、reinterpret_cast(通常为操作数的位模式提供较低层次的重新解释,该类转换非常危险)。如:
static_cast<int>(double类型数字)。可通过static_cast将存放在void*中的指针值强制转换为原来的指针类型。
const char *pc_str;
char *pc= string_copy(const_cast<char*>(pc_str));//可以将pc_str转成非const的。
int *ip;char *pc =reinterpret_cast<char*>(ip);
旧式强制转换符号形式:type (expr);或者(type)expr;建议只有在C语言或标准C++之前的编译器上编写代码时,才使用这种语法。