目录
前言
ex 8, 9, 10; //条件语句之三兄弟!
正文
习题8:if,else-if, else
C语言中没有真正的布尔类型,取而代之,任何为0的整数都为假(false),否则就为真(true)。
if语句格式:
if(TEST){ CODE; } else if(TEST){ CODE; } else { CODE; }
示例:
#include <stdio.h> int main(int argc, char *argv[]) { int a = 0; int b = 0; if(a > 0){ printf("如果你行,你来!"); }else if(b > 0){ printf("如果他行,他来!"); }else{ printf("没人么?俺老孙来也。。。\n"); } return 0; }
输出:
理解很容易,习惯要注意。花括号{}不要忘,不然据说发生错误时会变成小头爸爸的孩子。
习题9:while
C语言中最简单,最有用的循环结构。(真的吗?)
代码:
#include <stdio.h> int main(int argc, char *argv[]) { int sb = 1; printf("小僵,我帅不帅?"); while(sb){ printf("帅!"); } return 0; } ~
输出:
如果不是想耍帅,就别使用它!恩,有可能”帅到爆“!
楚河汉界
习题10:switch语句
在一些语言中,它其实和if加布尔表达式一样的。
在C中,switch很独特,它其实是一个跳转表(jump table)。可以放到其中的不是随机的布尔表达式,而是结果为整数的表达式。这些整数用于计算从switch顶部跳跃到匹配值的位置。
下面的代码可以帮你弄懂跳转表的概念。(哦,是吗?手动再敲一次代码,加深印象)
#include <stdio.h> int main(int argc, char *argv[]) { if(argc !=2){ printf("ERROR: You need one argument. \n"); //this is how you abort a program return 1; } int i = 0; for( i = 0; argv[1][i] != '\0'; i++){ char letter = argv[1][i]; switch(letter) { case 'a': case 'A': printf("%d: 'A'\n", i); break; case 'e': case 'E': printf("%d: 'I'\n",i); break; case 'o': case 'O': printf("%d:'O'\n",i); break; case 'u': case 'U': printf("%d: 'U'\n", i); break; case 'y': case 'Y': if(i > 2) { //it's only sometimes y printf("%d: 'Y'\n", i); } break; default: printf("%d: %c is not a vowel\n", i , letter); } } return 0; }
据说上面的是一个微型解析器原型(啥是微型解析器?)。肖老师的switch深度讲解,不太懂。据说实际应用只要记住下面这些简单的规则
default:分支,必须有! |
如果有“贯穿”,要加注释//fallthrough(个人理解中文的意思就是此处故意击穿) |
先写case与break,再写其中的代码 |
if能代劳的话,就别swicth了(恩,备胎!还有while,可能排第三,备胎的备胎) |
习题10:附加任务
前面四个感觉挺有难度
- 再写个程序,对字母做数学运算,将他们换成小写,然后删去多余的大写字母分支。(我伪三刷还不会,求助创作助手,不知道对不对)
#include <stdio.h>
int main() { char ch;
printf("请输入一个字母:"); scanf("%c", &ch); if (ch >= 'A' && ch <= 'Z') { ch = ch + 32; // 将大写字母转换为小写字母 printf("转换后的字母为:%c\n", ch); } else { printf("输入的不是字母\n"); } return 0;
}调试代码后
#include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { int i; char str[21]; label1: printf("请输入字母:"); fgets(str, sizeof(str), stdin);//siezeof(str)可以限制字符串长度,超过的就不读取 str[strcspn(str, "\n")] = '\0';// 移除换行符,不然输出时就会多出一个空行。 if (strchr(str, ' ') != NULL) { printf("字符串中请不要包含空格,谢谢!\n"); goto label1; } if(strlen(str) >10){ printf("字符串长度过长,请重新输入!\n"); goto label1; } if((strlen(str) == 1)&&(strchr(str, 'q') != NULL)){//输入字母"q",退出程序 goto label2; } for(i = 0; str[i] != '\0';i++) { if (str[i] >= 'A' && str[i]<= 'Z') { str[i] = str[i]+ 32; // 将大写字母转换为小写字母 printf("(%d)转换结果:%c\n", i, str[i]); } else if (str[i] >= 'a' && str[i] <= 'z') { printf("(%d)转换结果:%c\n",i, str[i]); } else { printf("(%d)%c不是字母!\n", i, str[i]);} } goto label1; label2: return 0; }
一不小心其实把所有的附加任务都做了,而且还超纲了不少
- 使用','(逗号)来初始化for循环中的letter
- 让它再用一个for循环来处理所有你输入的参数
- 把switch改写为if语句,你更新欢哪一个
- 在’Y‘分支中,把break放到if内部,会发生啥?验证你的猜想。(这个是最简单的了,多一个default呗!哦,if不执行,break就不执行。)
后语
1.习题10的附加任务收获总结:
获取字符串的scanf与fgets,scanf会把空格换行符识别为休止符;
感受到了label的顽皮;
把后面要学的字符串操作又巩固了下,只要是操作字符串,有一系列的现成函数能拿来用。
2.改了好几天,感觉上面那个小程序没有BUG了,你们说呢?
3.我用ai协助编程之路:以前是手机有星火,后来360有ai,再后来钉钉有了ai,现在csdn有了创作助手。但最终还是要自己有一定基础,否则一切都是浮云。一不小心好像夸了自己下,嘿嘿!
超纲提醒
个人感觉,下面是超纲的,可以大概了解下。学习需要保持在拉伸区,比如“笨C”,内容没难度,就挑战附加任务。内容都有点难于理解,就跳过附加任务。
以后牛叉了再回头收拾它!(嗯,为啥背景没了,灯光师在哪?!今天午饭没鸡腿!)
A、跳转表
跳转表(Jump table)是一种数据结构,用于在程序中进行跳转和分支。它主要用于优化大量分支语句的执行效率。
跳转表通常是一个数组,数组中的每个元素都是一个指针,指向相应的分支代码块。当程序需要根据某个条件进行分支时,可以通过查找跳转表中对应的索引位置,然后跳转到相应的代码块执行,从而避免了大量的if-else语句或switch语句的判断和执行过程。
跳转表在某些情况下可以比条件分支语句更高效,尤其是当分支条件的取值范围比较小且连续时,可以使用跳转表将条件和相应的代码块一对一地映射起来,减少判断和执行的开销。
需要注意的是,跳转表适用于离散的、静态的条件分支,不适用于连续的、动态的条件分支。在程序中使用跳转表时,需要保证条件的合法性和正确性,以避免出现跳转错误和漏判的情况。
B、解析器
解析器是一种计算机程序或工具,用于将一组复杂的输入数据解析为结构化的数据。它通常用于解析文本文件、配置文件或其他格式化的数据输入。解析器将输入数据分析成多个不同的组成部分,并提供对这些部分的访问和操作的方法。
解析器通常使用一种语法或规则来解析输入数据。这些规则描述了输入数据的格式和结构,并指导解析器如何将输入数据解析为更简单的元素或数据类型。解析器可以使用递归算法来分析复杂的嵌套结构,并将其转换为更简单的数据结构,例如树状结构或对象。
解析器的主要任务是将输入数据转换为更容易处理的形式,以便后续的处理、分析或操作。它可以将输入数据转换为内存中的数据结构,例如数组、哈希表或对象,以便其他程序可以更方便地访问和操作这些数据。
实际上,解析器在许多计算领域中都有广泛的应用。例如,在编译器中,解析器将源代码解析为抽象语法树,以便后续的语法分析和代码生成。在网络通信中,解析器将收到的数据流解析为协议数据单元,以便进行进一步的处理和分析。在数据分析和处理中,解析器可以将结构化数据解析为更容易分析和处理的形式。
总之,解析器是一种将复杂的输入数据解析为结构化数据的工具,它在许多计算领域中起着重要的作用。它可以帮助我们更好地理解和处理输入数据,并为后续的处理、分析和操作提供支持。