学习笔记 6.1 if语句
华为内部开发规范就是这样,我也要改成这样.
还有一个就是if ; for; while这样的语句块要和()中间各一个空格.
6.2 逻辑表达式 || ,逻辑OR运算符 第一个表达式为True则短路,==第一个为真则不去判断第二个表达式==
&& ,逻辑AND运算符 第一个表达式为False则短路,==第一个为假则不去判断第二个表达式==
转移字符’\a’是
反正每次遇到这种很多组合在一起的时候,不要急着立马一眼翻译出对应的汉语可以表达的逻辑关系
你就慢慢来把每一个表达式的情况都拆解出来.n个expr就对应2的n次方种情况.你就每一个表达式都罗列出来,然后最后判断整体的结果是true还是false.(不要偷懒,自以为是的一眼真或者一眼假,这样一定会吃亏)
[!NOTE]
我记得这里自己之前是写了
1 2 3 4 true && true true && false false && false false && true
这四种情况,也就是按照我上面的想法,n个expr就对应2的n次方种情况,这样子来分析的.
但是我后来又发现可以直接按照面向过程的思路来记忆,按程序6.5来做例子,就是看看在输入的过程中可能碰到的情况,然后分别要怎么处理,,具体如下
1 2 3 4 输入这个数之后,这个数不是负数 同时 没有满足六个,那么继续输入 输入这个数之后,这个数不是负数 同时 有满足六个,那么停止输入 输入这个数之后,这个数是负数 同时 没有满足六个,那么停止输入 输入这个数之后,这个数是负数 同时 有满足六个,那么停止输入
这样就很自然的理解了&& 的意思,
同理对于一个if也是的,例如
你从逻辑上来看可能是expr为真,然后do something;expr为假,就做后面的.
但是你从这个程序具体对应的例子上来看,从过程中分析: 可能是输入这个数之后,没有满足十个,那么就继续输入.当你输入的数满足了十个,就做后面的.
因此我们这两种都要掌握.尤其是第二种,对解读代码有更好的记忆效果.而且对于短路原则,第二种可以和实际效果联系得上.例如
1 2 3 4 5 6 int i = 0 ;if (i不超出数组范围 && array[i] < 10 ) { cout <<i<<endl; i ++; }
先从个人解读代码 的角度上,用第二种方法:
如果用第一种方式就对着感到一丝丝困惑,还要自己搞四种情况,一个一个来判断,就算判断出来了也不知道这里面的过程是怎么样的.
但是用第二种方式,你首先知道初始的时候i = 0,然后从实际的作用上来理解, 就是i在自增的过程中,起初是不超出数组范围的,所以就是筛选小于10的元素,一直自增到i超出范围就停止了.
总的来说,就是第一种方式是从离散数学的逻辑判断的角度上出来,严谨但是理解速度慢.第二种方式就是从是实际出来,理解速度快同时面向过程思考.而且从实际的角度出来能理解短路原则的好处就是:
我们先从实际的角度,面向过程的来分析下面的例子
一开始i = 0, 就是i在自增的过程中,
起初是不超出数组范围的,所以就是筛选小于10的元素,#1
一直自增到i超出范围就停止了.#2
———————————————分割线
你可以看到#1这句话对应离散数学的第一种方法就是
1 2 i不超出数组范围 同时 array[i]小于10 ,那么输出i,然后i++ i不超出数组范围 同时 array[i]不满足小于10 ,那么被筛选掉了,不执行花括号里面 的语句
你看到#2这句话对应离散数学的第一种方法就是
1 2 3 i超出数组范围 同时 array[i]小于10 ,那么停止 i超出数组范围 同时 array[i]不满足小于10 ,那么停止
也就是#2自然而然的在我们面向过程的对实际情况的分析中,很自然的只判断了表达式1为false,我们大脑也自然的不去执行和判断表达式2,因为表达式2无论是true还是false 都不影响这个表达式为false.
这就是面向过程的对着实际分析和短路原则两者不谋而合的地方,或者来说,这个&&之所以存在短路原则就是参照人脑的想法,人脑看到表达式1为false的时候就本能的不去管表达式2了.所以&&有一个短路原则来和人脑对应.至于后面短路原则刚好规避了表达式2执行起来不合法的巧合,,个人认为这是先有短路原则,然后人们发现存在表达式2执行起来不合法的情况.所以调整表达式1和表达式2的位置,来刚好让短路原则,在模拟人脑的本能在表达式1为false的时候不去管表达式2这种行为下,能将不去管表达式2这个行为 即达到了模拟人脑偷懒的想法,又 达到了对执行表达式2的规避(也就是保护表达式2不被执行)
总结就是:本来短路原则是模拟人脑的偷懒行为 的,但是通过拜访表达式1和表达式2 的位置,能够一箭双雕,一石二鸟.让短路原则即达到了模拟人脑的偷懒行为的效果,又达到了不执行表达式2(也就是规避表达式2 的执行,也就是保护表达式2不被执行)
.
如果表达式1为false 的情况下,表达式2的判断过程中有不合法的阶段(如同下面的例子,在i超出数组范围的时候,表达式2不能取值,一定是不合法的,因此在表达式1为false的时候,我们不希望表达式2被执行.)因此那么就把表达式1放在表达式2的左边,通过&&连接起来.这样在表达式1为false的时候,就可以保护表达式2不被执行.最经典要记忆的例子就是下面这种写法
1 2 3 4 5 6 int i = 0 ;if (i不超出数组范围 && array[i] < 10 ) { cout <<i<<endl; i ++; }
最后注意一个别人积累出来的规避错误的技巧:
在最后一次判断刚好超出范围的i的时候,取array[i]是不合法的,但刚好把判断i是否超出数组范围的语句写到前面,就能保护后面的语句不被执行.这是一种习惯,记住就行.
接着如果有可以优化的判断,或者是短路原则之类 的,你再去判断.这样一步一步的理解就不会有让自己有怀疑的点了.
第一次看程序6.5的时候自己有些迟疑,怀疑是自己没咋见过这种的,自己还不够熟练.自己现在不看给出的答案,自己写一遍
程序清单6.5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 #include <iostream> #include <cstring> using namespace std;const int ArSize = 6 ;int main (void ) { double arr[ArSize]; double temp; int i = 0 ; cout << "First value: " ; cin >> temp; while (i < ArSize && temp >= 0 ) { arr[i] = temp; i++; if (i < ArSize) { cout << "Next value: " ; cin >> temp; } } if (i == 0 ) cout << "No data -- bye" << endl; else { printf ("Enter your NAAQ:" ); double ave; cin >> ave; int count = 0 ; for (int j = 0 ; j < i; j++) { if (arr[j] > ave) count++; } cout << count << endl; cout << "of your neighbor have greater awareness of the New Age than you do . " << endl; } return 0 ; }
注意:在按照我的面向过程的想法看待这个输入的数据的过程的时候,总是不自觉地假定第一个输入的数字是符合要求的,从第二个开始往后输入的数字才是因为expr1或者expr2为false而不符合要求的,从这个过程中让自己了解各种情况.但是往往陷入一个思维误区,就是第一个输入的数字也完全可能是不符合要求的,从而一次while循环都没有进入过.具体到我这里的题意就是 第一个输入的数字是负数,因此arr数组里面一个数都没有,所以加一个特判
1 2 if (i == 0 ) cout << "No data -- bye" << endl;
很多时候自己写才发现自己会忘记很多东西,看代码的时候想当然,自己写的时候啥都不确定.
一句话送给自己:不要眼高手低,可能有难题,但绝对没有简单题目
6.2.3 用&&来设置取值范围
这里复习一下
程序清单 6.6 more_and.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include <iostream> #include <cstring> using namespace std;const char *qualify[5 ] = { "Perfect" , "Great" , "Good" , "Just so so" , "failed" }; int main (void ) { int score; int index; cout << "Enter your score:" ; cin >> score; if (score >= 90 && score <= 100 ) index = 0 ; else if (score >= 80 && score < 90 ) index = 1 ; else if (score >= 70 && score < 80 ) index = 2 ; else if (score >= 60 && score < 70 ) index = 3 ; else index = 4 ; cout << qualify[index] << endl; return 0 ; }
程序清单6.7 not.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 #include <iostream> #include <climits> using namespace std;bool is_int (double x) ;int main (void ) { double number; cout << "Enter an integer value:" ; cin >> number; while (!is_int (number)) { cout << "out of range , please enter again:" ; cin >> number; } int value = int (number); cout << "You have entered an integer: " << value << endl; return 0 ; } bool is_int (double x) { if (x <= INT_MAX && x >= INT_MIN) return true ; else return false ; }
不要眼高手低,还是每一个都敲一遍,不知不觉就有感觉和记忆.’
程序清单6.7 cctype.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include <iostream> #include <cctype> using namespace std;int main (void ) { int whitespace = 0 ; int digits = 0 ; int chars = 0 ; int punct = 0 ; int others = 0 ; char ch; cout << "Enter text for analysis, and type @ to terminate the input. " << endl; cin.get (ch); while (ch != '@' ) { if (isspace (ch)) whitespace++; else if (isdigit (ch)) digits++; else if (isalpha (ch)) chars++; else if (ispunct (ch)) punct++; else others++; cin.get (ch); } printf ("%d letters\n" , chars); printf ("%d whitespaces\n" , whitespace); printf ("%d digits\n" , digits); printf ("%d punctuations\n" , punct); printf ("%d others\n" , others); }
程序清单6.9 condit.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 #include <iostream> #include <cctype> using namespace std;int main (void ) { int a, b; cout << "Enter two integers:" ; cin >> a >> b; int max = a > b ? a : b; cout << "the larger is " << max << endl; }
程序清单6.10 switch.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 #include <iostream> #include <cctype> using namespace std;void showmenu (void ) ;void report (void ) ;void comfort (void ) ;int main (void ) { char choice; showmenu (); cin >> choice; while (choice != 'Q' && choice != 'q' ) { switch (choice) { case 'a' : case 'A' : cout << "Warning!!!" << endl; break ; case 'r' : case 'R' : report (); break ; case 'l' : case 'L' : cout << " The boss was in all day" << endl; break ; case 'c' : case 'C' : comfort (); break ; default : cout << "That is not a choice" << endl; break ; } showmenu (); cin >> choice; } return 0 ; } void showmenu (void ) { cout << "Please enter 1, 2 , 3, 4, 5 as your choice:" << endl; cout << "a) alarm r) report" << endl; cout << "l) alibi c) comfort" << endl; cout << "q) quit" << endl; } void report (void ) { cout << "Sales are up 120%, Expenses are down 35%." << endl; } void comfort (void ) { cout << " You are the best CEO !" << endl; }
程序清单6.11 enum.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 #include <iostream> #include <cctype> using namespace std;enum { red, orange, yellow, green, blue, violet, indigo }; int main (void ) { int code; cout << "Enter color code(0~6): " ; cin >> code; while (code >= red && code <= indigo) { switch (code) { case red: cout << "You choose red!" << endl; break ; case orange: cout << "You choose orange!" << endl; break ; case yellow: cout << "You choose yellow!" << endl; break ; case green: cout << "You choose green!" << endl; break ; case blue: cout << "You choose blue!" << endl; break ; case violet: cout << "You choose violet!" << endl; break ; case indigo: cout << "You choose indigo!" << endl; break ; } cout << "Enter color code(0~6): " ; cin >> code; } cout << "bye1" << endl; return 0 ; }
程序清单6.12 jump.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 #include <iostream> #include <cstring> using namespace std;const int ArSize = 80 ;int main (void ) { char line[ArSize]; cout << "Enter a line of text: " ; cin.get (line, ArSize); int blankspaceCount = 0 ; for (int i = 0 ; i < strlen (line); i++) { cout << line[i]; if (line[i] == '.' ) break ; if (line[i] == ' ' ) blankspaceCount++; } cout << endl; cout << "blankspaceCount is " << blankspaceCount << endl; cout << "Complete line :" << line << endl; return 0 ; }
老师讲的简单例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <iostream> #include <cstring> using namespace std;int main (void ) { int num1, num2; cout << "First number: " ; cin >> num1; cin.clear (); while (cin.get () != '\n' ) ; cout << "Last number: " ; cin >> num2; cout << "num1 = " << num1 << ", num2 = " << num2 << endl; return 0 ; }
程序清单6.13 cinfish.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include <iostream> #include <cstring> using namespace std;const int Max = 5 ;int main (void ) { double fish[Max]; cout << "Please enter the weight of your fish: " << endl; cout << "You may enter up to " << Max << " fish <q> to terminate. " << endl; cout << "fish #1:" ; int i = 0 ; while (i < Max && cin >> fish[i]) { i++; if (i < Max) cout << "fish #" << i + 1 << ":" ; } double ave; double sum = 0 ; for (int j = 0 ; j < i; j++) sum += fish[j]; cout << "total :" << sum << endl; if (i == 0 ) cout << "No fish" << endl; else { ave = sum / i; cout << "Average weight of " << i << " fish is " << ave << endl; } return 0 ; }
程序清单6.14 cingolf.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <iostream> #include <cstring> using namespace std;const int Max = 5 ;int main (void ) { int golf[Max]; cout << "Please enter your golf scores." << endl; cout << "You must enter " << Max << " rounds. " << endl; int i; for (i = 0 ; i < Max; i++) { cout << "Round #" << i + 1 << ": " << endl; while (!(cin >> golf[i])) { cin.clear (); while (cin.get () != '\n' ) ; cout << "Error: bad input , please enter your golf scroe again!" << endl; } } double total = 0 ; for (int i = 0 ; i < Max; i++) total += golf[i]; cout << "Average score is " << total / Max << endl; return 0 ; }
6.8 简单文件输入/输出 发现可以在VScode的终端里面按照ubuntu一样的用命令行来编译运行,就可以在同一路径下放多个有main函数的cpp文件了.(缺点是windows下的路径的符号是反斜杠也就是\ ,不想Ubuntu下的是斜杠,也就是除号/,也叫做正斜杠.反正你没事按下tab就能自动补全,甚至能帮你修改一些微小的格式错误.).
用快捷键Ctrl + alt + n肯定是把当前目录下的所有cpp文件都一起编译链接了,所以出了问题有多个main函数作为程序的入口
程序清单6.15 outfile.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 #include <iostream> #include <fstream> #include <cstring> using namespace std;const int Max = 5 ;int main (void ) { char automobile[50 ]; int year; double a_price; double d_price; ofstream outFile; outFile.open ("hsuwindow.txt" ); cout << "Enter the make and model of automobile:" ; cin.getline (automobile, 50 ); cout << "Enter the model year: " ; cin >> year; cout << "Enter the original asking price:" ; cin >> a_price; d_price = a_price * 0.913 ; cout << fixed; cout.precision (2 ); cout.setf (ios_base ::showpoint); cout << "Make and model: " << automobile << endl; cout << "Year: " << year << endl; cout << "Was asking: " << a_price << endl; cout << "Now asking: " << d_price << endl; outFile << fixed; outFile.precision (2 ); outFile.setf (ios_base ::showpoint); outFile << "Make and model: " << automobile << endl; outFile << "Year: " << year << endl; outFile << "Was asking: " << a_price << endl; outFile << "Now asking: " << d_price << endl; outFile.close (); return 0 ; }
程序清单6.16 sumafile.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 #include <iostream> #include <fstream> #include <cstdlib> using namespace std;const int SIZE = 100 ;int main (void ) { char filename[SIZE]; ifstream inFile; cout << "Enter name of data file: " ; cin.getline (filename, SIZE); inFile.open (filename); if (!inFile.is_open ()) { cout << "Could not open the file " << filename << endl; cout << "Program terminating." << endl; exit (EXIT_FAILURE); } cout << "Success open the txt file." << endl; double value; double sum = 0.0 ; int count = 0 ; inFile >> value; while (inFile.good ()) { count++; sum += value; inFile >> value; } if (inFile.eof ()) { cout << "End of file reached." << endl; } else if (inFile.fail ()) { cout << "Input terminated by data mismatched. " << endl; } else cout << "Input terminated by unknown reason " << endl; if (count == 0 ) { cout << "No data processed." << endl; } else { cout << "Items read: " << count << endl; cout << "Sum: " << sum << endl; cout << "Average: " << sum / count << endl; } inFile.close (); return 0 ; }
复习题解析 1.第一种格式不论什么情况,两个if语句都会被执行一次,第二种格式在ch 为空格的时候,不会执行else if里面的语句,所以第二种格式第一种格式好的地方
2.ch + 1的结果是int类型,cout之后结果是整形数
++ch是ASCII码值向后或者向前挪一位,因此他在运算完毕之后,他仍然还是一个char类型,因此他cout之后结果仍然是字符
H$i$!$
$S$e$n$d$ $ct1 = 9, ct2 = 9
weight >= 100 && weight < 125
ch == ‘q’ || ch == ‘Q’
x % 2 == 0 && x != 26
x % 2 == 0 && x % 26 != 0
(donation >= 1000 && donation <= 2000) || (1 == guest)
(ch >= ‘a’ && ch <= ‘z’) || (ch >= ‘A’ && ch <= ‘Z’)
如果是x是bool类型,那么!!x和x是一样的
如果说x是char或者int类型,!x变成变成bool类型的 false,!!x就是true,那么!!x和x肯定就不一样 了
(x > 0) ? x : -x;
switch(ch){
case: ‘A’:
a_grade++;
break;
case: ‘B’:
a_grade++;
break;
case: ‘C’:
a_grade++;
break;
case: ‘D’:
a_grade++;
break;
default :
f_grade++;
break;
}
这里书上可能是编译器的问题,反正跟b站视频的结果和我自己测试的结果有出入
我把我的测试代码贴在下面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 #include <iostream> using namespace std;void showMenu (void ) ;int main (void ) { int choice; showMenu (); cin >> choice; while (choice != 5 ) { switch (choice) { case 0 : cout << "kankan choice is or not 0\n" ; break ; case 1 : cout << "you enter 1\n" ; break ; case 2 : cout << "you enter 2\n" ; break ; case 3 : cout << "you enter 3\n" ; break ; case 4 : cout << "you enter 4\n" ; break ; default : cout << "That is not a choice\n" ; break ; } showMenu (); cout << choice << endl; cin >> choice; } cout << "Bye!\n" ; return 0 ; } void showMenu (void ) { cout << "Please enter 1, 2, 3, 4, or 5:\n" ; cout << "1) alarm 2) report\n" ; cout << "3) alibi 4) comfort\n" ; cout << "5) quit\n" ; }
本题的答案应该是
修改成 char类型之后,无论你输入的是数字还是26个英文字符,程序运行起来都没有问题.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <iostream> using namespace std;int main (void ) { int line = 0 ; char ch; while (cin.get (ch) && ch != 'Q' ) { if (ch == '\n' ) line++; } return 0 ; }
编程练习ing
💡 有关C++PrimerPlus上的问题,欢迎您在底部评论区留言,一起交流~