没有找到您需要的,用Google搜索一下

2009年4月3日星期五

C++ Primer读书笔记 5-6章

文章来源http://xuexi88.blogspot.com/

C++ Primer读书笔记 5-6章
第五章 表达式
1.c++支持操作符重载,允许程序员自定义用于类类型时操作符的含义。标准库就是这样的。
2.每个表达式都会产生一个结果。如果表达式中没有操作符,那结果就是操作数本身。如果有,结果需要对操作数做指定操作。
3.除特殊用法外,表达式的结果是右值,可以读不能改。
4.操作符含义:操作符执行什么样的操作,以及操作结果的类型-取决于操作数。
5.unary operator一元操作符, binary operator二元操作符
6.要理解由多个操作符组成的表达式,必须先理解操作符的优先级precedence、结合性associativity、和操作数的求值顺序 oder of evaluation.
7.bool.char.short.int.long.都是整形,适用于整形的操作符他们都能用。
8.关系运算符和逻辑运算符适用算数或指针类型的操作数,返回bool值。
9.非、与或中间夹着关系运算符,其中关系运算符,大小的优先级又高于等于的优先级
10.逻辑与和逻辑或这两个运算符,总是先计算其左操作数,再计算器右操作数。只有在仅靠左操作数无法确定结果时,才去计算右操作数。 这叫短路求值。short-circuit evaluation.
如:
string s("hello world!");
string::iterator it= s.begin();
while(it!=s.end() && !isspace(*it))
{
.....
}
11.不应该串联使用关系运算符。
位操作符:
1.位操作符适用整形做操作数。位操作符将其整形数视为二进制集合。
2.优先级顺序:~ 求反;<< >>;&;^;|;
3.注意:对于为操作符,由于系统不能确定如何处理符号位,强烈建议适用unsigned类型
4.右移位补什么需要,看操作数的符号。
5.0或,1与,结果不变。
6.通常来说,bitset优于整形数据的低级直接位操作
7. 5.10 例题怎么做

赋值操作符:
1.赋值操作符是不可修改的左值。
2. int ival; ival=3.14; 大概自动类型转换吧。
3.为操作符>>等是左结合性; =赋值操作符是右结合性。
4.复合赋值操作符: += -= *= /= %= &= |= ^= <<= >>=
5.++i返回自增后的值,i++返回自增操作前的值。养成使用前置操作符的好习惯。
6 ->操作符 使用指针操作类类型的成员。
7.条件操作符 conditional operator 是c++唯一个三元操作符。他允许将简单的 if else语句嵌入表达式; 如: cond? expr1:expre2;
先计算表示式 cond ,如果true计算 expr1,否则计算expre2;
8.sizeof也是一个操作符,其作用是返回一个对象或类型名的长度,返回值类型为size_t,单位字节。
9.三种语法格式:sizeof(typename); sizeof(expr); sizeof expr;
后两个返回结果的类型的长度。
10.用sizeof 求数组元素个数: int sz=sizeof(ia)/sizeof(*ia); 总大小/单位大小
11.逗号表达式 逗号操作符,逗号表达式通常用于for循环,返回的是最右侧一个表达式的值。
12.结合性规定了具有相同优先级的操作符如何分组。
13.与求值顺序有关的操作符 如: && || ?: , 四个。
14.if(ia[index++]<ia[index]) 由于计算次序问题,此表达式没有明确定义。
new delete
1.动态创建的对象可以初始化变量的方式初始化
int i(1024); i=1024
int *pi = new int (1024); 动态分配一个int ,值是1024并且pi指向它。
string s(10,'9');
string *ps=new string(10,9);
如果不显示初始化,则:类类型使用默认构造函数初始化,内置类型不初始化。如 int *pi=new int();
当然也可以对动态创建的对象做默认初始化。如:
string *ps=new stirng(); int *pi=new int();//初始为0 cls *pc=new cls();
2.c++提供了delete表达式释放指针所指向的地址空间。 如 delete pi;
注意,如果指针指向的不是用new分配的内存地址,则在该指针上使用delete是不合法的。
如果delete 的不是变量,编译器会阻止,如果是指针,编译器不知道是不是用new分配的。
delete 0指针是合法的,但是没有意义。
3.一旦删除了指针所指向的对象,立即将指针置为0,这样就非常清楚地表明,指针不再指向任何对象了。
4.cosnt对象,动态分配和回收。const int *pi = new const int(1024);
必须初始化;只能付给const类型的指针。
内置对象和没有构造函数的类型,必须显示初始化。
5.动态内存的管理容易出错
1:删除指向动态分配空间失败成为内存泄漏。 memory leak.
2:删除后,指针要指0;
3:一个空间,两个指针的话,第二此删除会破坏自由存储区。
类型转换:
1.隐士类型转换: inplicit type conversion
2.1: 混合类型表达式中,其操作数被转换为相同的类型。
2: 用作条件表达式被转换为bool类型:
3: 用一个表达式初始化变量,或将一个表达式赋值给某个变量: int ival=3.14;
3. 算数装换:如果一个操作数的类型是 long double ,则无论令一个操作数是何类型,都会转换成long double.因为:转换规则要确保计算值的精度。
整形提升: intergral promotion.
4.32位的机器上,long和int通常都是一个字,那么当包含unsigned int 和 long时,两个都转成unsigned long.
5.指针转换:多数情况下,数组会转换成指向第一个元素的指针,以下除外:数组用作取地址&或sizeof操作符的操作数是,或对数组的引用进行初始化时。
6.指向任意数据类型的指针都可以转换为void *。0可以转换为任意类型的指针
7.bool 类型,算数值和指针值都可转换为bool,当其是0时,为false;
8.c++自动将枚举类型的对象转换为整形。转换成什么类型依赖机器,和枚举成员的最大值。至少是int;
9.转换为const对象
int i;
const int ci=0;
const int &j=i;
显示转换
1. 虽然有时候需要,但本质上,是危险的。
2. 何时需要:因为要覆盖通常的标准转换。
3. 强制转换操作符: static_cast、dynamic_cast、const_cast、reinterpret_cast;
4. 一般形式: cast-name<type>(expression);
5. const_cast 只有使用const_cast才能将const性质转换掉。这种情况下,其他三种形式的强制转换都会出现编译错误。除了添加删除cosnt特性,用const_cast做其他转换也会出编译错。
6.编译器隐式执行的类型装换可以由static_cast显示完成。当一个较大的算数类型到一个较小的数据类型赋值时。编译器通常会给警告。当使用显示的转换时,警告会关闭。
7.static_cast用于找回存放在void*中的指针值。
void *p=&d;
double *dp=static_cast<double*>(p);
8 reinterpret_cast 通常为操作数的位模式提供较低层次的重新解释。
其本质上依赖于机器,要求程序员完全理解所设计的类型,以及编译器实现强制转换的细节。
9建议避免使用强制类型转换。
10.旧式强制类型转换。char *pc=(char*) ip; 同reinterpret_cast;

第六章:
1.空语句: 一个分号;有时候语法需要一个语句,但逻辑上不需要,此时使用空语句
2. switch 程序从改点执行,并跨越case边界执行其他语句,知道switch结束或遇到break;
3.如果default分支什么也不用做,也要有个空语句。
4 switch 只能在最后一个case或default后边定义变量。
5. do while while中使用的变量必须在循环体之前定义,而不能定义在循环体的内部。
6.do while 总是以分号结尾。
7 break 用于结束最近的 while do while for switch语句。
8 continue语句将导致最近的循环语句的档次迭代提前结束。
9 goto 语句提供了函数内部的无条件跳转。
10 goto 语句和获得所转移的控制权的带标号的语句必须位于同一个函数内。
11 goto 语句不能跨越 变量的定义语句向前跳转。
goto end;
int ix=10;
end:
ix=42;
如果确实需要,放在一个语句块中。
goto end;
{int ix=10;}
12 goto 语句向后跳转到一个变量定义之前,会导致系统撤销这个变量的定义。
begin:
int z=10;
if(z>10)
{ goto begin;}

文章来源http://xuexi88.blogspot.com/

0 评论:

发表评论