C++ Primer 学习笔记_16_表达式 --算术、关系、逻辑、位、赋值、自增/自减操作符
2015-11-06 12:07
716 查看
表达式
--算术关系逻辑位赋值自增自减操作符
引
正文
高优先级的操作符要比低优先级的结合得更紧密。
2、除法和求模操作:
1)如果两个操作数都是负数:则除法操作的结果为正数,而求模操作结果为负数
2)如果只有一个操作数是负数:这两种操作的结果都要取决于机器:求模结果的符号要取决于机器,除法操作的值则是负数。
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
cout << -21 % -8 << endl;
cout << 21 % -5 << endl; //1 or -4
cout << -21 / -8 << endl;
cout << 21 / -5 << endl; //-4 or -5
3、关系操作符和逻辑操作符的返回结果都是bool类型的值
短路求值-逻辑与&&与逻辑或||,都是只有仅靠左操作数的值无法确定该逻辑表达式的结果时,才会求解其右操作数。
4、一个&&操作符的使用技巧:如果某边界条件使得expr2的计算变得非常危险,那么应该在该条件出现之前,先让expr1成为false。
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
string s("Expressions in C++ are composed...");
string::iterator iter = s.begin();
while (iter != s.end() && ! isspace(*iter))
{
*iter = toupper(*iter);
++ iter;
}
cout << s << endl;
5、如果逻辑非的操作数为非零值,则!操作的结果为false。
6、不应该串接使用关系操作符,如:
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
if (i < j < k)
{
//...
}
该表达式的结果往往是出人意料的:这种写法只要k值大于1,则该表达式的结果就为true;
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
//P133 习题5.7
int main()
{
int val;
while (cin >> val && val != 42)
{
//...
}
}
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
//习题 5.8
if (a > b && b > c && c > d) {//...}
7、位操作符可以将整型操作符视为二进制位的集合,而且还可以作用于bitset类型。
8、如果位操作符的操作数为负数,则位操作符如何处理其操作数的符号要依赖于机器。因此,强烈建议使用unsigned整型操作数。
![](https://oscdn.geek-share.com/Uploads/Images/Content/201511/48d2f6d0472baf5e7b9176172b190018)
1<< n :相当于1* 2^n
m<< n :相当于m* 2^n
9、bitset对象与整型值的使用对比
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
//bitset对象的每一位都默认为0
bitset<30> bitset_quizl;
unsigned long int_quizl = 0;
//设置第27位为1
bitset_quizl.set(27);
int_quizl |= 1UL << 27;
//设置第27位为0
bitset_quizl.reset(27);
int_quizl &= ~(1UL << 27);
//获得第27位上的取值
bool status;
status = bitset_quizl[27];
status = int_quizl & (1UL << 27);
通常来说:bitset优于整型数据的低级直接位操作。
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
//P136 习题5.9
int main()
{
unsigned int ul1 = 3,ul2 = 7;
cout << (ul1 & ul2) << endl;
cout << (ul1 | ul2) << endl;
cout << (ul1 && ul2) << endl;
cout << (ul1 || ul2) << endl;
}
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
//习题5.10
int main()
{
bitset<30> bitset_quizl;
//设置第27位为1
bitset_quizl[27] = 1;
cout << bitset_quizl << endl;
//设置第27位为0
bitset_quizl[27] = 0;
cout << bitset_quizl << endl;
cout << bitset_quizl[27] << endl;
}
10、移位操作符用于I/O
移位操作符具有中等优先级:其优先级比算术运算符低,但比(1)关系操作符,(2)赋值操作符,(3)条件运算符优先级高。
11、赋值运算符具有右结合性,如:
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
int ival1,ival2;
ival1 = ival2 = 0;
//等价与
(ival1 = (ival2 = 0));
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
//P139 习题5.11 i、d的值分别为?
int i;
double d;
d = i = 3.5;
i = d = 3.5;
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
//习题5.12 下面程序会有什么结果
//(1)
int main()
{
int i;
if (42 = i)
{
//...
}
}
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
//(2)
int main()
{
int i;
if (i = 42)
{
//...
}
}
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
//P140 习题5.14 下面程序会有什么输出结果
int main()
{
int ival = 2;
ival += (ival + 1);
cout << ival << endl;
}
12、建议:只有在必要时才使用后置自增/自减操作符
前置操作符需要做的工作更少,而后置操作符必须先保存操作数原来的值,以便返回未加/减1之前的结果。【P140建议...值得仔细品读!】
13、后自增操作符的优先级高于解引用操作符,因此*iter++等价与*(iter++).
【建议阅读:P141建议:简洁即是美】
表达式
--算术关系逻辑位赋值自增自减操作符
引
正文
表达式
--算术、关系、逻辑、位、赋值、自增/自减操作符
引:
除了特殊用法,表达式的结果为右值:可以读取结果值,但是不能对其进行赋值。高优先级的操作符要比低优先级的结合得更紧密。
正文:
1、某些算术表达式的求解结果未定义:一部分有数学特性决定,如除0操作;另一部分则归咎于计算机特性,如溢出。2、除法和求模操作:
1)如果两个操作数都是负数:则除法操作的结果为正数,而求模操作结果为负数
2)如果只有一个操作数是负数:这两种操作的结果都要取决于机器:求模结果的符号要取决于机器,除法操作的值则是负数。
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
cout << -21 % -8 << endl;
cout << 21 % -5 << endl; //1 or -4
cout << -21 / -8 << endl;
cout << 21 / -5 << endl; //-4 or -5
cout << -21 % -8 << endl; cout << 21 % -5 << endl; //1 or -4 cout << -21 / -8 << endl; cout << 21 / -5 << endl; //-4 or -5
3、关系操作符和逻辑操作符的返回结果都是bool类型的值
短路求值-逻辑与&&与逻辑或||,都是只有仅靠左操作数的值无法确定该逻辑表达式的结果时,才会求解其右操作数。
4、一个&&操作符的使用技巧:如果某边界条件使得expr2的计算变得非常危险,那么应该在该条件出现之前,先让expr1成为false。
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
string s("Expressions in C++ are composed...");
string::iterator iter = s.begin();
while (iter != s.end() && ! isspace(*iter))
{
*iter = toupper(*iter);
++ iter;
}
cout << s << endl;
string s("Expressions in C++ are composed..."); string::iterator iter = s.begin(); while (iter != s.end() && ! isspace(*iter)) { *iter = toupper(*iter); ++ iter; } cout << s << endl;
5、如果逻辑非的操作数为非零值,则!操作的结果为false。
6、不应该串接使用关系操作符,如:
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
if (i < j < k)
{
//...
}
if (i < j < k) { //... }
该表达式的结果往往是出人意料的:这种写法只要k值大于1,则该表达式的结果就为true;
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
//P133 习题5.7
int main()
{
int val;
while (cin >> val && val != 42)
{
//...
}
}
//P133 习题5.7 int main() { int val; while (cin >> val && val != 42) { //... } }
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
//习题 5.8
if (a > b && b > c && c > d) {//...}
//习题 5.8 if (a > b && b > c && c > d) {//...}
7、位操作符可以将整型操作符视为二进制位的集合,而且还可以作用于bitset类型。
8、如果位操作符的操作数为负数,则位操作符如何处理其操作数的符号要依赖于机器。因此,强烈建议使用unsigned整型操作数。
1<< n :相当于1* 2^n
m<< n :相当于m* 2^n
9、bitset对象与整型值的使用对比
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
//bitset对象的每一位都默认为0
bitset<30> bitset_quizl;
unsigned long int_quizl = 0;
//设置第27位为1
bitset_quizl.set(27);
int_quizl |= 1UL << 27;
//设置第27位为0
bitset_quizl.reset(27);
int_quizl &= ~(1UL << 27);
//获得第27位上的取值
bool status;
status = bitset_quizl[27];
status = int_quizl & (1UL << 27);
//bitset对象的每一位都默认为0 bitset<30> bitset_quizl; unsigned long int_quizl = 0; //设置第27位为1 bitset_quizl.set(27); int_quizl |= 1UL << 27; //设置第27位为0 bitset_quizl.reset(27); int_quizl &= ~(1UL << 27); //获得第27位上的取值 bool status; status = bitset_quizl[27]; status = int_quizl & (1UL << 27);
通常来说:bitset优于整型数据的低级直接位操作。
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
//P136 习题5.9
int main()
{
unsigned int ul1 = 3,ul2 = 7;
cout << (ul1 & ul2) << endl;
cout << (ul1 | ul2) << endl;
cout << (ul1 && ul2) << endl;
cout << (ul1 || ul2) << endl;
}
//P136 习题5.9 int main() { unsigned int ul1 = 3,ul2 = 7; cout << (ul1 & ul2) << endl; cout << (ul1 | ul2) << endl; cout << (ul1 && ul2) << endl; cout << (ul1 || ul2) << endl; }
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
//习题5.10
int main()
{
bitset<30> bitset_quizl;
//设置第27位为1
bitset_quizl[27] = 1;
cout << bitset_quizl << endl;
//设置第27位为0
bitset_quizl[27] = 0;
cout << bitset_quizl << endl;
cout << bitset_quizl[27] << endl;
}
//习题5.10 int main() { bitset<30> bitset_quizl; //设置第27位为1 bitset_quizl[27] = 1; cout << bitset_quizl << endl; //设置第27位为0 bitset_quizl[27] = 0; cout << bitset_quizl << endl; cout << bitset_quizl[27] << endl; }
10、移位操作符用于I/O
移位操作符具有中等优先级:其优先级比算术运算符低,但比(1)关系操作符,(2)赋值操作符,(3)条件运算符优先级高。
11、赋值运算符具有右结合性,如:
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
int ival1,ival2;
ival1 = ival2 = 0;
//等价与
(ival1 = (ival2 = 0));
int ival1,ival2; ival1 = ival2 = 0; //等价与 (ival1 = (ival2 = 0));
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
//P139 习题5.11 i、d的值分别为?
int i;
double d;
d = i = 3.5;
i = d = 3.5;
//P139 习题5.11 i、d的值分别为? int i; double d; d = i = 3.5; i = d = 3.5;
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
//习题5.12 下面程序会有什么结果
//(1)
int main()
{
int i;
if (42 = i)
{
//...
}
}
//习题5.12 下面程序会有什么结果 //(1) int main() { int i; if (42 = i) { //... } }
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
//(2)
int main()
{
int i;
if (i = 42)
{
//...
}
}
//(2) int main() { int i; if (i = 42) { //... } }
[cpp]
view plaincopyprint?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
//P140 习题5.14 下面程序会有什么输出结果
int main()
{
int ival = 2;
ival += (ival + 1);
cout << ival << endl;
}
//P140 习题5.14 下面程序会有什么输出结果 int main() { int ival = 2; ival += (ival + 1); cout << ival << endl; }
12、建议:只有在必要时才使用后置自增/自减操作符
前置操作符需要做的工作更少,而后置操作符必须先保存操作数原来的值,以便返回未加/减1之前的结果。【P140建议...值得仔细品读!】
13、后自增操作符的优先级高于解引用操作符,因此*iter++等价与*(iter++).
【建议阅读:P141建议:简洁即是美】
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- ITeye上“10个人,8个人不会解释这个问题”的帖子
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua中调用C++函数示例
- Lua学习笔记之运算符和表达式
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(三):表达式和语句
- Lua基础教程之赋值语句、表达式、流程控制、函数学习笔记
- Lua教程(二):C++和Lua相互传递数据示例
- Ruby中case表达式详解
- Oracle 自增(auto increment) 或 标识字段的建立方法
- C++联合体转换成C#结构的实现方法
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结