您的位置:首页 > 编程语言 > C语言/C++

C++复习 05 表达式

2007-10-22 13:19 204 查看
声明,所有的朋友,如果要转我的帖子,务必注明"作者:黑啤 来源:CSDN博客"和具体的网络地址http://blog.csdn.net/nx500/archive/2007/10/22/1836902.aspx,并且我的所有博客内容,禁止任何形式的 商业用途,请大家尊重我的劳动.谢谢!

目 录

五.表达式.
001 表达式是由一个或多个操作数通过操作符组合而成.除下标和解引用外,表达式的结果都是右值.
002 不应该串接关系操作符.
if(i<j<k)... // 这个例子中只要K大于1,结果就为ture.和i与j没有关系了. 正确的写法是if (i<j && j<k).
003 位异或:两个对应为有一个为1,另个为0,结果为1,否则结果为0.
004 后置"++"/"--"操作符,先为操作对象保存一个副本,然后操作增减,然后返回保存的那个副本.
前置"++"/"--"操作符,先进行增减操作,然后返回对象自身.对于不使用返回值的自增自减操作,推荐使用前置的方式.
005 箭头操作符具有"解引用+点操作符"联合使用的效果.
item1.same_isbn(item2);
Sales_item *sp = &item1;
(*sp).same_isbn(item2); // 这里也可以用sp->same_isbn(item2)
// 由于很多人忘记(*sp)外边的括号,其意义就不对了,所以箭头操作更安全一些
006 赋值操作符具有右结合性,比如一个经典的不经过临时变量来交换两个变量值或三个变量值的算法.
注意下边的算法只是用于说明作用,实际在C++中,这个表达式是错误的, 因为异或操作产生的是右值.
a= a^ b= b^ a= a^b; // a=a^b; b=a^b; a=a^b;
a= a^c^ b= a^b^ c= b^c^ a= a^b^c
再来一个n个变量的,注意总结规律哦,"..."表示在表达式"a1^a2^...^an"中排除后边对应的那个变量
a1= ...^ a2= ...^ a3= ... ... = ...^ an= ...^ a1 = a1^a2^...^an
007 逗号表达式是一组由逗号分隔的表达式,从左向右计算,结果是最右边表达式的值.如果最右操作数产生左值,则逗号表达式的结果也是左值.
008 C++中全部操作符表.
操作符 结合性 功能 用法
:: L 全局作用域 ::name
:: L 类作用域 class::name
:: L 名字空间作用域 namespace::name
-------------------------------------------------------------------------------------
. L 成员选择 object.member
-> L 成员选择 pointer->member
[] L 下标 variable[expr]
() L 函数调用 name(expr_list)
() L 类型构造 type(expr_list)
-------------------------------------------------------------------------------------
++ R 后自增操作 lvalue++
-- R 后自减操作 lvalue--
typeid R 类型ID typeid(type)
typeid R 运行时类型ID typeid(expr)
显式强制类型转换 R 类型转换 cast_name<type>(expr)
-------------------------------------------------------------------------------------
sizeof R 对象的大小 sizeof expr
sizeof R 类型的大小 sizeof(type)
++ R 前自增操作 ++lvalue
-- R 前自减操作 --lvalue
~ R 位求反 ~expr
! R 逻辑非 !expr
- R 一元负号 -expr
+ R 一元正号 +expr
* R 解引用 *expr
& R 取地址 &expr
() R 类型转换 (type)expr
new R 创建对象 new type
delete R 释放对象 delete expr
delete [] R 释放数组 delete [] expr
--------------------------------------------------------------------------------------
->* L 指向成员操作的指针 ptr->*ptr_to_member
.* L 指向成员操作的指针 ptr.*ptr_to_member
--------------------------------------------------------------------------------------
* L 乘法 expr * expr
/ L 除法 expr / expr
% L 求模(取余) expr % expr
--------------------------------------------------------------------------------------
+ L 加法 expr + expr
- L 减法 expr - expr
--------------------------------------------------------------------------------------
<< L 位左移 expr << expr
>> L 位右移 expr >> expr
--------------------------------------------------------------------------------------
< L 小于 expr < expr
> L 大于 expr > expr
<= L 小于等于 expr <= expr
>= L 大于等于 expr >= expr
--------------------------------------------------------------------------------------
== L 等于 expr == expr
!= L 不等于 expr != expr
--------------------------------------------------------------------------------------
& L 位与 expr & expr
--------------------------------------------------------------------------------------
^ L 位异或 expr ^ expr
--------------------------------------------------------------------------------------
| L 位或 expr | expr
--------------------------------------------------------------------------------------
&& L 逻辑与 expr && expr
--------------------------------------------------------------------------------------
|| L 逻辑或 expr || expr
--------------------------------------------------------------------------------------
?: R 条件操作 expr? expr : expr
--------------------------------------------------------------------------------------
= R 赋值操作 lvalue = expr
*=, /=, %= R 复合操作 lvalue *= expr 等
+=, -+,
<<=, >>=,
&=, |=, ^=
--------------------------------------------------------------------------------------
throw R 抛出异常 throw expr
--------------------------------------------------------------------------------------
, L 逗号 expr, expr
--------------------------------------------------------------------------------------
009 一个表达式里,不要再两个或者更多的子表达式中对同一对象做自增或自减操作.
if (ia[index] < ia[index++])... // 这样操作是有风险的.
if (ia[index] < ia[index + 1]){ // 这样操作就避免了由于求值顺序引发的问题.
++index;
010 new和delete表达式.
new可以动态创建对象,同时初始化.
int *ip1 = new int(10); // new创建了一个int类型对象,并初始化该值为10.
int *ip2 = new int(); // new创建了一个int类型对象,并调用默认构造函数,初始化为0.
int *ip3 = new int; // new创建了一个int类型对象,但没有提供初始化.


// 05010.cpp


#include <iostream>


using std::cout;


using std::endl;






int main()...{


int *ival = new int(999);




if (ival)...{


cout << *ival << endl;


}


delete (ival); // 切记,要及时释放申请的内存.


ival = NULL;


return 0;


}



如果new表达式无法获取需要的内存空间,系统将抛出名为bad_alloc的异常.
用delete释放内存后,必须将指针置为NULL,否则就会形成野指针,如果对其访问就会造成无法预料的后果.
011 动态内存管理容易出现的错误.
1. 删除动态内存失败将会造成"内存泄漏".
2. 读写已经删除的对象.
3. 对同一内存空间使用两次delete操作.当两个指针,指向同一个动态创建的对象,删除时就会发生错误.
如果其中一个指针做delete运算,该对象的内存返还给自由存储区,然后另外一个指针接着delete,此时自由存储区可能会破坏.
012 隐式类型转换.
1. 在混合类型的表达式中,其操作数被转换为相同的类型.
2. 用作条件的表达式中被转换为bool类型.
3. 用一表达式初始化某个变量,或将一表达式赋值给某个变量,则该表达式被转换为该变量的类型.
013 默认的,数组名称可以转换为指针,例外情况有:数组用作取地址操作符的操作数,或sizeof操作符的操作数,或用数组对数组的引用进行初始化时.
014 显式转换也称为强制类型转换,包括static_cast,dynamic_cast,const_cast,reinterpret_cast命名转换.
常用static_cast<type>取代隐式转换.设计良好的程序应该避免显示的转换,包括const_cast转换.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: