你该逆袭了
第7章:重点摘录
- 三、逻辑运算符
- 1、备选拼写:iso646.h 头文件
- 2、优先级
- 3、求值顺序
- 4、范围
- 四、一个统计单词的程序
- 1、针对代码,提出疑问,第8章节进行讲解
- 2、我结合自己的理解,自己写的代码
- 五、条件运算符 ?:
- 六、循环辅助:continue 和 break
- 1、continue 语句
- 2、break 语句
- 七、多重选择:switch 和 break
- 1、switch 语句
- 八、goto语句(C不需要,不要用)
- 1、能不用就不用 goto 语句
- 2、可以使用 goto 语句 的场合
- 九、关键概念
- 十、本章小结
三、逻辑运算符
#include <stdio.h>
#define PERIOD '.' //PERIOD 相当于 单引号—句点—单引号int main()
{char ch = 0;int charcount = 0;while ((ch = getchar()) != PERIOD){if (ch != '"' && ch != '\'')charcount++;}printf("there are %d non_quoto characters.\n", charcount);return 0;
}
1、备选拼写:iso646.h 头文件
#include <stdio.h>
#include <iso646.h> //and or not 代替 && || ! 的头文件
#define PERIOD '.' //PERIOD 相当于 单引号—句点—单引号int main()
{char ch = 0;int charcount = 0;while ((ch = getchar()) != PERIOD) //用 and 代替 &&{if (ch != '"' and ch != '\'')charcount++;}printf("there are %d non_quoto characters.\n", charcount);return 0;
}
2、优先级
优先级顺序:从上到下
( )
!
算数运算符
关系运算符
&&
||
赋值运算符
3、求值顺序
除了两个运算符共享一个运算对象的情况外,C 通常不保证先对复杂表达式中哪部分求值。
例如,下面的语句,可能先对表达式 5+3 求值,也可能先对表达式 9+6 求值:
apples = (5 + 3) * (9 + 6);
C 把先计算哪部分的决定权留给编译器的设计者,以便针对特定系统优化设计。
但是,对于 逻辑运算符 是个例外,C 保证 逻辑表达式 的 求值顺序 是 从左往右。
&& 和 || 运算符都属 序列点,所以程序在从一个运算对象执行到另一个运算对象之前,所有的副作用都会生效。
而且,C 保证一旦发现某个元素让整个表达式无效,便立即停止求值。
4、范围
#include <stdio.h>
#include <ctype.h>int main()
{int i = 0;char str[] = "test string.\n";while (islower(str[i])) //无论使用哪种特定的字符编码,islower()函数都能正常运行,是可移植的 {i++;}printf("%d\n", i); // 4 return 0;
}
四、一个统计单词的程序
//P195 程序清单7.7
//统计字符数、单词数、行数#include <stdio.h>
#include <ctype.h> //为isspace( )提供函数原型
#include <stdbool.h> //为bool、true、false提供定义
#define STOP '|' int main()
{char c = 0; //读入字符char prev = 0; //读入的前一个字符long n_chars = 0L; //字符数int n_lines = 0; //行数int n_words = 0; //单词数int p_lines = 0; //不完整的行数bool inword = false; //如果 c 在单词中,inword 等于 trueprintf("enter text to be analyzed ( | to terminate):\n"); //这里用 '|' 来作为 结束标志prev = '\n'; //用于识别完整的 行while ((c = getchar()) != STOP){n_chars++; // 统计 字符if (c == '\n') n_lines++; //统计 行if (!isspace(c) && !inword) //此时字符不是空格,并且inword为false,说明刚刚开始了一个单词,现在要改变inword的值为true,并且单词数量+1 { //!inword == falseinword = true; //inword == truen_words++;}if (isspace(c) && inword) //此时字符为空格,并且inword为true,说明刚刚结束了一个单词,现在要改变inword的值为false。inword = false;prev = c;}if (prev != '\n') //这里要注意 STOP 字符位于一行的中间的情况。是否递增行数计数?//我们可以作为特殊行计数,即没有换行符的一行字符。{ //可以通过记录之前读取的字符识别这种情况,即如果读取时发现 STOP 字符的上一个字符不是换行符,那么这行就是特殊行。p_lines = 1;}printf("characters=%ld,words=%d,lines=%d, ",n_chars, n_words, n_lines);printf("partial lines =%d\n", p_lines);return 0;
}
1、针对代码,提出疑问,第8章节进行讲解
问:检查代码,查看一下如果单词之间有多个空格时,程序是否能正常运行。
答:不能,第8章讲解了如何修正这个问题,让该程序能统计文件中的单词量。
2、我结合自己的理解,自己写的代码
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
#define STOP '|'int main()
{char c = 0; //输入的每一个字符char pre = 0; //上一个字符,如果上一个字符是 '\n',说明是一个完整的行//如果上一个字符不是 '\n',说明是一个不完整的行int n_words = 0; //单词个数int n_chars = 0; //字符个数int n_lines = 0; //完整的代码行数int p_lines = 0; //不完整的代码行数bool inward = false; //inward 从 false 变成 true ,说明新增了一个单词pre = '\n';inward = false;while ((c = getchar()) != STOP){n_chars++; //字符数量加 1 if (c == '\n'){n_lines++; //新增了 1 行}if (!isspace(c) && !inward) //始终记住:inward 从 false 变成 true ,说明新增了一个单词{ //根据这个原则来理解这两段代码inward = true; n_words++;}if (isspace(c) && inward) //始终记住:inward 从 false 变成 true ,说明新增了一个单词{ //根据这个原则来理解这两段代码inward = false;}pre = c;}if (pre != '\n'){p_lines = 1; //遇到 STOP 就停止程序了,所以直接给 p_lines 赋值为 1 就可以了。 }printf("characters = %d,words = %d,lines = %d,p_lines = %d\n",n_chars, n_words, n_lines, p_lines);return 0;
}
五、条件运算符 ?:
//P197 程序清单7.8
//使用条件运算符
//重点:商店只卖整罐油漆,不会拆分来卖,所以如果计算结果是 1.7 罐,就需要 2 罐。
//因此,该程序计算得到带小数的结果时应该进 1 。
//条件运算符常用于处理这种情况,而且还要根据单复数分别打印 can 和 cans 。#include <stdio.h>
#define COVERAGE 350 //每罐油漆可刷面积int main()
{int sq_feet = 0;int cans = 0;printf("enter number of square feet to be painted:\n");while (scanf("%d", &sq_feet) == 1){cans = sq_feet / COVERAGE;cans += ((sq_feet % COVERAGE == 0) ? 0 : 1);printf("you need %d %s of paint.\n", cans,cans == 1 ? "can" : "cans");printf("enter next value (q to quit):\n");}return 0;
}
自己写了一遍
#include <stdio.h>
#define MEIGUAN 350 //每罐油漆可以粉刷的面积int main()
{int mianji = 0;int cans = 0;printf("请输入你要粉刷的墙壁的面积:");while (scanf("%d", &mianji) == 1){cans = mianji / MEIGUAN;cans += mianji % MEIGUAN == 0 ? 0 : 1;printf("需要的油漆的罐数是 %d %s\n", cans, cans == 1 ? "can" : "cans"); //这是这个程序的亮点!!!printf("请再次输入你要粉刷的墙壁的面积:");}return 0;
}
六、循环辅助:continue 和 break
1、continue 语句
//P198 程序清单7.9#include <stdio.h>int main()
{const double MIN = 0.0f;const double MAX = 100.0f;double score = 0;double min = 0;double max = 0;double total = 0;int n = 0;min = MAX; //请注意理解max = MIN; //请注意理解score = 0;total = 0;n = 0; printf("请输入得分score:");while (scanf("%lf", &score) == 1){if (score < MIN || score > MAX){printf("数据无效,请重新输入数据:");continue; //注意点}min = (score < min ? score : min); //请注意理解max = (score > max ? score : max); //请注意理解 n++; //计算输入数据的个数total += score;printf("输入下一个数据:(输入非浮点数,退出程序)");}if (n > 0){printf("%d 个数据的平均分是:%lf\n", n, total / n);printf("low=%0.1f high=%0.1f\n", min, max);}else{printf("没有输入有效的数据。\n");}return 0;
}
上述代码的注意点:就是比较一组数据的最小值和最大值。
min = MAX; //请注意理解max = MIN; //请注意理解min = (score < min ? score : min); //请注意理解max = (score > max ? score : max); //请注意理解
2、break 语句
七、多重选择:switch 和 break
#include <stdio.h>
#include <ctype.h>int main()
{char ch = 0;printf("请输入小写字母,我会根据你所给的小写字母,来给定特定的语句:");while ((ch = getchar()) != '#'){if (ch == '\n'){continue;}if (islower(ch)){switch (ch){case 'a':printf("你输入的是小写字母 a \n");break; //跳出 switch 语句case 'b':printf("你输入的是小写字母 b \n");break;case 'c':printf("你输入的是小写字母 c \n");break;case 'd':printf("你输入的是小写字母 d \n");break;case 'e':printf("你输入的是小写字母 e \n");break;default:printf("可以了可以了\n");break;}}else{printf("我只认识小写字母。\n");}while (getchar() != '\n'){continue; //用于清除多余的字母}printf("请输入下一个字母:");}printf("bye\n");return 0;
}
while (getchar() != '\n'){continue; //用于清除多余的字母}
1、switch 语句
八、goto语句(C不需要,不要用)
1、能不用就不用 goto 语句
2、可以使用 goto 语句 的场合
九、关键概念
十、本章小结