接上一节内容
2.5条件和逻辑
自增和自减操作符
这个主要区别就是在前和后,大多数学习过其他语言的应该都知道。所以,一个程序带过。
示例如下:
/************************************************************************* > File Name: list1001_++.cpp > Author: suool_hu > Mail: 1020935219@qq.com > Created Time: 2014年05月18日 星期日 10时08分50秒 ************************************************************************/ #include<iostream> #include<string> using namespace std; // 自增测试 int main() { int x = 42; cout << "x = " << x << "\n"; cout << "++x = " << ++x << "\n"; cout << "x = " << x << "\n"; cout << "x++ = " << x++ << "\n"; cout << "x = " << x << "\n"; return 0; }
结果如下:
下面继续一个小练习:从标准输入读取整数到一个向量,然后将其反序后输出,一行一个。
示例代码如下:
/************************************************************************* > File Name: list1003_iter_reverse.cpp > Author: suool_hu > Mail: 1020935219@qq.com > Created Time: 2014年05月18日 星期日 22时36分41秒 ************************************************************************/ #include<algorithm> #include<iostream> #include<iterator> #include<string> #include<vector> using namespace std; // 从标准输入读取数字存储到向量,将其反序输出(用循环,不要用内置方法) int main() { vector<int> data; int x; // 读取输入,并存储到vector cout << "请输入数字:" << endl; while(cin >> x) { data.push_back(x); } // 循环反序 for (vector<int>::iterator start(data.begin()),end(data.end()); start != end; // 空!!!) { -- end; if (start != end) { int tmp = *start; *start = *end; *end = tmp; ++start ; } } // 输出 cout << "反序输出您输入的数字:" << endl; copy(data.begin(), data.end(), ostream_iterator<int>(cout, "\n")); return 0; }
注意上述的for循环中的第三个语句为空,虽然不推荐如此写,但是在此处却不得不这样做。
I/O & bool类型
一个小示例:
/************************************************************************* > File Name: list1101_bool.cpp > Author: suool_hu > Mail: 1020935219@qq.com > Created Time: 2014年05月19日 星期一 17时57分28秒 ************************************************************************/ #include<iostream> #include<string> using namespace std; // C++的I/O流允许读写bool值。默认情况下,流将他们当做数值. // 即是true为1,false为0。 // 而操作子std::boolalpha可以通知流将bool值解析为单词(word)。 // 默认情况下,为true和false。 // 下为示例: int main() { cout << "默认情况下的输出:" << endl; cout << "true=" << true << '\n'; cout << "false=" << false << '\n'; cout << "操作子的修改:" << endl; cout << std::boolalpha; cout << "true=" << true << '\n'; cout << "false=" << false << '\n'; return 0; }
C++可以将很多很多类型自动类型转换为bool类型,如下示例:
/************************************************************************* > File Name: list1002_auto_trans.cpp > Author: suool_hu > Mail: 1020935219@qq.com > Created Time: 2014年05月20日 星期二 10时22分55秒 ************************************************************************/ #include<iostream> #include<string> using namespace std; // Automatic Type Conversion to boom /* * C++ 不会将字符串的内容按照字面意思的解释以确定其是false或者true,所有的字符串都是true,即使空也是。 */ int main() { bool b; std::cout << std::boolalpha; b = false; std::cout << b << '\n'; b = true; std::cout << b << '\n'; b = false; std::cout << b << '\n'; b = true; std::cout << b << '\n'; b = 42; std::cout << b << '\n'; b = 3.1415926535897; std::cout << b << '\n'; b = 0; std::cout << b << '\n'; b = -0.0; std::cout << b << '\n'; b = -1; std::cout << b << '\n'; b = "1"; std::cout << b << '\n'; b = "0"; std::cout << b << '\n'; b = "false"; std::cout << b << '\n'; b = ""; std::cout << b << '\n'; b = '0'; std::cout << b << '\n'; b = '\0'; std::cout << b << '\n'; b = std::cout; std::cout << b << '\n'; b = std::cin; std::cout << b << '\n'; std::cout << '\n'; return 0; }
结果如下:
逻辑操作符
逻辑操作符我们之前或许一般习惯于使用符号,即&&、||、 !。其实我们更佳的选择是使用and, not, or因为上面的符号&也是一种操作符,|也是一种,我们往往使用错误,所以,推荐使用字符关键字版本的。
另:注意逻辑操作符的短路运算操作!
下面是一个示例:
/************************************************************************* > File Name: list1104_logic.cpp > Author: suool_hu > Mail: 1020935219@qq.com > Created Time: 2014年05月20日 星期二 10时42分20秒 ************************************************************************/ #include <iostream> #include <string> #include <istream> #include <iterator> #include <vector> using namespace std; /* * 注意for循环里的逻辑判断符用的是关键字,不是&& || !的符号 * 希望以后养成适用使用关键字的习惯,因为&和|本身就是一个有效的不同的操作符 * 容易混淆 */ int main() { vector<int> data; // 标准输入读入数字 data.insert(data.begin(),istream_iterator<int>(std::cin),istream_iterator<int>()); vector<int>::iterator iter; for (iter = data.begin(); iter != data.end() and *iter == 0; ++iter) /*empty*/; // 空循环,只是检测是否有0存在 if (iter == data.end()) std::cout << "data contains all zeroes\n"; else std::cout << "data does not contain any zeroes\n"; return 0; }
比较操作符
关于向量的大小比较,下面是一个示例:
/************************************************************************* > File Name: list1105_campare_vector.cpp > Author: suool_hu > Mail: 1020935219@qq.com > Created Time: 2014年05月20日 星期二 10时57分25秒 ************************************************************************/ #include<iostream> #include<string> #include<vector> using namespace std; // 比较两个向量的大小 // 比较的方式和string一样的 int main() { // 创建两个向量以及两个下标指示器并且初始化他们 vector<int> a, b; vector<int>::iterator iter_a, iter_b; a.push_back(10); a.push_back(20); a.push_back(30); b.push_back(10); b.push_back(20); b.push_back(30); // 初始化使他们相等 // 第一次比较 // 输出向量的内容 cout << "向量a的内容是:" << endl; for(iter_a = a.begin(); iter_a!=a.end(); ++iter_a) cout << *iter_a << ' '; cout << endl; cout << "向量b的内容是:" << endl; for(iter_b = b.begin(); iter_b!=b.end(); ++iter_b) cout << *iter_b << ' '; cout << endl; if (a != b) cout << "wrong: a != b\n"; if (a < b) cout << "wrong: a < b\n"; if (a > b) cout << "wrong: a > b\n"; if (a == b) cout << "okay: a == b\n"; if (a >= b) cout << "okay: a >= b\n"; if (a <= b) cout << "okay: a <= b\n"; // 增加a的内容 // 输出向量的内容 // 输出向量的内容 a.push_back(40); cout << "向量a的内容是:" << endl; for(iter_a = a.begin(); iter_a!=a.end(); ++iter_a) cout << *iter_a << ' '; cout << endl; cout << "向量b的内容是:" << endl; for(iter_b = b.begin(); iter_b!=b.end(); ++iter_b) cout << *iter_b << ' '; cout << endl; if (a != b) std::cout << "okay: a != b\n"; if (a < b) std::cout << "wrong: a < b\n"; if (a > b) std::cout << "okay: a > b\n"; if (a == b) std::cout << "wrong: a == b\n"; if (a >= b) std::cout << "okay: a >= b\n"; if (a <= b) std::cout << "wrong: a <= b\n"; // 增加b,再次比较 b.push_back(42); // 输出向量的内容 cout << "向量a的内容是:" << endl; for(iter_a=a.begin(); iter_a!=a.end(); ++iter_a) cout << *iter_a <<' '; cout << endl; cout << "向量b的内容是:" << endl; for(iter_b = b.begin(); iter_b != b.end(); ++iter_b) cout << *iter_b << ' '; cout << endl; if (a != b) std::cout << "okay: a != b\n"; if (a < b) std::cout << "okay: a < b\n"; if (a > b) std::cout << "wrong: a > b\n"; if (a == b) std::cout << "wrong: a == b\n"; if (a >= b) std::cout << "wrong: a >= b\n"; if (a <= b) std::cout << "okay: a <= b\n"; return 0; }
结果如下:
关于字符串的大小比较,下面是一个示例:
/************************************************************************* > File Name: list1106_campare_string.cpp > Author: suool_hu > Mail: 1020935219@qq.com > Created Time: 2014年05月20日 星期二 11时17分58秒 ************************************************************************/ #include<iostream> #include<string> using namespace std; /* * 不要直接比较双引号里面的字符,除非你创建了string类型,并初始化他 * 直接比较"help"和"SoS"是不对的,因为这样的比较是比较他们在内存中的位置,和内容本身无关, * 仅仅和编译器有关. * 因此要想比较"help"和"Sos"的大小,至少需要其中的一个为string类型 */ int main() { // 创建两个字符串并且初始化 string a("abc"), b("abc"); // 比较之前输出 cout << "a的内容:" << a << endl; cout << "b的内容:" << b << endl; // 判断 if(a != b) cout << "wrong: abc != abc \n"; if(a < b) cout << "wrong: abc < abc \n" ; if(a > b) cout << "wrong: abc > abc \n" ; if(a == b) cout << "okay : abc = abc \n" ; if(a >= b) cout << "okay : abc >= abc \n"; if( a<= b) cout << "okay : abc <= abc \n"; // 增加a的内容 a.push_back('d'); cout << "a的内容:" << a << endl; cout << "b的内容:" << b << endl; if(a != b) cout << "okay: abcd != abc \n"; if(a < b) cout << "wrong: abcd < abc \n" ; if(a > b) cout << "okay: abcd > abc \n" ; if(a == b) cout << "wrong : abcd = abc \n" ; if(a >= b) cout << "okay : abcd >= abc \n"; if(a<= b) cout << "wrong: abcd <= abc \n"; // 增加b的内容 b.push_back('e'); cout << "a的内容:" << a << endl; cout << "b的内容:" << b << endl; if(a != b) cout << "okay: abcd != abce \n"; if(a < b) cout << "okay: abcd < abce \n" ; if(a > b) cout << "wrong: abcd > abce \n"; if(a == b) cout << "wrong: abcd = abce \n"; if(a >= b) cout << "wrong:abcd >= abce \n"; if( a<= b) cout << "okay :abcd <= abce \n"; cout << "下面的做法是不对的!!!下面直接用了\"help\" == \"hello\"的判断语句,而不是用string类型." << endl; return 0; }
运行结果:
2.6复合语句
关于C++的复合语句,必然要涉及到局部变量的说明,其实关于变量,其实就是在哪定义的就在那儿有用,在复合语句内部定义那么他的可见范围就是这个复合语句,如果实在main函数内部定义,那么就是整个main函数,如果在main函数外面,且不在其它函数内部,就是全局变量,他在整个文件都可见,但是局部变量可以覆盖全局变量。就是我的地盘听我的,地头蛇大于强龙啊。他的可见范围被称为作用域。
而好的编程实践就是尽量限制变量的作用域,限制作用域的好处是:
- l防止出错
- 交流意图:方便阅读啊,不然一个变量管的太宽,怎么理解。。。
- 重用名字
下面是一个示例:
/************************************************************************* > File Name: list1202_vari.cpp > Author: suool_hu > Mail: 1020935219@qq.com > Created Time: 2014年05月20日 星期二 18时25分17秒 ************************************************************************/ #include<algorithm> #include<cassert> #include<iostream> #include<iterator> #include<string> #include<vector> using namespace std; int main() { vector<int> data; data.insert(data.begin(), istream_iterator<int>(cin), istream_iterator<int>()); // 排序变量的笨方法 // 假设向量中的迭代器iter之前的部分已经排好序. // 找到向量中已经排好序的部分中iter的位置,从向量中删除*iter,然后将其重新插入到排序位置. // 不变量: 下标[0, 1) 指向的元素都已经被排序 for (vector<int>::iterator iter(data.begin()); iter != data.end();++iter) { // 通过调用标准算法lower_bound,找到data.at(iter)的位置.lower_bound执行二分搜索. // 并返回一个迭代器,该迭代器指向value应该插入到data中的位置. int value(*iter); vector<int>::iterator here(lower_bound(data.begin(), iter, value)); iter = data.erase(iter); data.insert(here, value); } // 调试代码:通过将向量中的每个元素与前一个元素比较,检查循环是否真正的被排序 for (vector<int>::iterator iter(data.begin()),prev(data.end()); iter != data.end(); ++iter) { if(prev != data.end()) assert(not (*iter < *prev)); prev = iter; } // 将排好序的向量打印,空向量打印{} cout << '{'; string separator(" "); for (vector<int>::iterator iter(data.begin()); iter != data.end(); ++iter) { cout << separator << *iter; separator = ", "; } cout << "}\n"; return 0; }
结果如下: