C语言知识归纳
一.C语言知识思维导图
二.写出自己对下列语法的认识
1.if else语句
if(语句1){ 语句2; } else{ 语句3; }
执行流程:首先判断关键词 if 后括号内条件表达式的值,如果该表达式的值表达为真,则执行 if 体,接着执行 if 体后的其他语句;否则,若该表达式的值表达为假,则不执行该 if 体,直接执行 if 体后的其他语句。
问题:if语句中嵌合if语句时,难以判断else所对应的if体。
解决:else与其前面最近的还未配对的if相配对。
注意:一条if语句也可以看成一句简单语句。
2.switch语句
switch(ch){ case 1:语句1;break; case 2:语句2;break; default:语句3;break; }
执行流程:首先求解表达式,如果表达式的值与某个常量表达式的值相等,则执行该常量表达式后的相应语句段,如果表达式的值与任何一个常量表达式的值都不相等,则执行default后的语句段,最后执行break语句,跳出switch语句。
问题:在找到一个相同的case分支后忘记加break,输出错误。
解决:考虑到直接执行下一个语句,确定每个表达式后的break无法省去。
注意:每个case代码块内部的break语句不能少,否则会接下去执行下一个case,而不是跳出switch结构。
3.for语句
for(表达式1;表达式2;表达式3){ 循环体语句 }
执行流程:先计算表达式1,再判断表达式2,若值为“真”,则执行循环体语句,并接着计算表达式3,然后继续循环,若值为“假”,则结束循环,继续执行下一条语句。
问题:当for语句中嵌套for语句时,语句循环的次数是多少。
解决:类比跳绳,跳5组,每组跳10个,每一组都要跳10个,所以循环的次数为外循环次数*内循环次数。
注意:for语句中各个表达式间用“;”连接而不是“,”;且循环体语句只能是一条语句,若有多条语句参与循环,要用大括号括起来,因为复合语句被认为是一条语句。
4.while语句
while(表达式){ 循环体语句; }
执行流程:当表达式的值为“真”时,循环执行,直到表达式的值为“假”,循环中止并执行while的下一条语句。
问题:输出时一直在循环。
解决:循环体语句中要保证可以改变值,使表达式的判断发生改变。
注意:while语句中的循环体语句要能够改变运行时表达式的判断。
5.do-while语句
do{ 循环体语句 } while(表达式);
执行流程:第一次进入循环时,首先执行循环体语句,然后再检查循环控制条件,即计算表达式,若值为“真”,继续循环,知道表达式的值为“假”,循环结束。
问题:易于while语句使用时混淆。
解决:do-while语句时先执行循环体语句,再判断,所以do-while语句适用于先循环,后判断的循环条件的情况。
认识:do-while语句无论循环条件如何,至少会执行一次循环体。
6.break语句和continue语句
switch (表达式){ case常量表达式1:语句1;break; case常量表达式2:语句2;break; case常量表达式3:语句3;break; default常量表达式4:语句1;break; }
for(表达式1;表达式2;表达式3){
语句1;
continue;
语句2;
}
执行流程:break语句强制结束循环,一旦执行了break语句,循环提前结束;continue语句时跳过循环体中continue的下一个语句,继续下一次循环。
问题:break语句参与时,出现了与预期不同的输出结果。
解决:break语句参与时,循环有两个出口,或判断句的表达式为“假”,或执行了break语句,需认真判断循环结束的条件。
认识:break语句和continue语句的区别在于,break结束循环,continue只是跳过后面语句继续循环;break除了可以中止循环以外,还可以用于switch语句,而continue只能用于循环。
三.PTA分数截图
四.PTA代码分析
题目一.
#include<stdio.h> int main() { int i,n,item,sum; sum=0; item=1; for(i=1;i<=n;i++){ item=item*i; sum=sum+item; } printf("%d",sum); return 0; }
代码思路:首先输出范围n,读题可发现这种求和类问题可以首先考虑循环结构,sum为前n项和,n<=12,在int范围内,可以直接用int来定义sum,然后用for语句,item可以理解成准备求和的下一项,注意item不能一开始为0,否则计算结果总是0,item=item*i可以理解成一个数再乘以这个数加1,再将加1后的数赋值给sum,即达到的阶乘的目的,最后输出sum。
错误原因:刚开始读题时确实想到了循环,但是纠结着如何完成阶乘,想着对阶乘本身用循环,发现将问题想的太过复杂,自己暂时也没有办法完成直接求阶乘。
收获:在求阶乘时,可以先用item(如上定义)将阶乘的意义表示出来,再将其求和。
题目二:
#include<stdio.h> int main() { int A,B,C,D,E,score,n,i; A=0;B=0;C=0;D=0;E=0; scanf("%d",&n); for(i=1;i<=n;i++){ scanf("%d",&score); if(score>=90) A++; else if(score>=80) B++; else if(score>=70) C++; else if(score>=60) D++; else E++; } printf("%d %d %d %d %d",A,B,C,D,E); return 0; }
代码思路:首先按照题目要求输入n,然后统计学生人数,考虑到多个输入,可以用循环语句,之后按照题目的要求,用分支语句分类好(此时注意条件表达式的语句可以灵活表示,比如else if(score>=80),不用写成else if(score>=80&&score<90),因为此句else if的含义就已经包括了小于90了),最后输出。
错误原因:错误的把scanf("%d",&score);写在了for语句前,错误时发现我这样写只能输出1个成绩,没有达到统计,循环的效果。
收获:输入多个值时尤其再循环结构中一定注意要将其包括,否则无法多次输入。
#include<stdio.h> int main() { int a,b,n; int i=1; scanf("%d %d",&a,&n); while(scanf("%d",&b)){ if(b<0&&i<n){ printf("Game Over"); return 0; } if(b<a){ printf("Too small\n"); i++; } if(b>a){ printf("Too big\n"); i++; } if(a==b&&i==1){ printf("Bingo!"); return 0; } if(a==b&&(i>1&&i<=3)){ printf("Lucky You!"); return 0; } if(a==b&&i>3&&i<=n){ printf("Good Guess!"); return 0; } if(a==b&&i>n){ printf("Game Over"); return 0; } } return 0; }
代码思路:考虑到重复输入,可以用循环语句,考虑到多个分支,用分支语句,首先依题意输入游戏的随意数a和猜测的最大数n,再在循环结构中输入用户的猜测值b,如果b为负数,或者用户猜中时次数大于n,或者在三次以内猜对(注意三次以内和首次就猜中要分类,因为输出不同)直接输出后return 0,结束运行,如果用户猜大或猜小,将i加1继续下一次循环,达到多次猜的目的,最后输出。
错误原因:①将scanf("%d",&b)写在循环外,只能猜数一次。 ②在进行分类时,对大于3次小于n次的猜数次数的情况错误编写,忘记写了小于n的部分,导致如下图结果:
收获:在进行分支语句编写时,一定要正确保证每一块的进行和防止一块对下一块的影响,如我上述的错误使i>n的时候无法输出正确答案。
以上为我的第一次C语言知识归纳情况。