简介:面向准备C语言程序设计考试的学生与自学者,这份PTA理论考练习文档聚焦基础语法判断与选择题的自测场景,帮助读者在考前系统核对概念、定位易错点。内容围绕编译预处理命令、main函数入口、语句结束符、变量与内存存储单元、单目运算符、表达式合法性、赋值运算符优先级、scanf与printf格式控制、for循环结构、复合语句与空语句等高频考点逐题给出答案,并配合逐条知识点详解,说明每个判断的依据而不只停留在对错。压缩包内共1个docx文件,约345KB,为可直接打开查阅的Word试题集,按HW02、HW03等题组顺序编排,题干与答案相邻排布,便于打印或边看边记。目前已有1897人学习下载。读者可借此获得一份覆盖C语言基础语法易错细节的题库,通过对照答案与讲解自查运算符优先级、输入输出格式匹配、循环累加等常见误解,适合课堂练习与考前突击使用。
1. 一份 PTA 理论考错题地图长什么样
PTA 理论考这部分题,和能敲进编译器跑一遍的编程题完全是两种不同的考查方式:判断题和选择题给的是一段段代码片段,答案对错全押在脑子里那套语法判定规则准不准上。把整份题库摊开重排,会发现它反复考的其实只有五束东西:词法与语句结构、表达式与运算符、输入输出与字符处理、流程控制,以及散落在这四块边界上的易漏点。适合两类人:正在准备 C 语言理论考的,和代码写得动但一遇到「以下程序段是否符合语法」就凭感觉蒙的。理论考不考你能不能跑通,考你能不能在没编译器的时候判断这段代码会不会炸。
2. 词法与语句地基:预处理、分号、声明顺序与单目运算符
这一章对应题库里最前面那批题,看着最基础,但丢分往往也丢在这里。原因不复杂:这些规则平时写代码时被 IDE 帮你兜住了,自动补全、波浪线提示、编译报错,全都在替你判断;到了纸面判断题上,判断的人换成你自己,边界一旦记模糊,就只能靠语感。语感在这类题上基本靠不住。
2.1 编译预处理命令与 main 函数的两个硬约束
#include <stdio.h>是一个编译预处理命令,判定特征有三个:以#开头、独占一行、在编译之前由预处理器处理。预处理的工作方式是把stdio.h的内容原地展开到当前文件里,展开完才轮到编译器干活。所以它不产生运行期代码,也不参与运算,行尾按惯例不写分号——写了多半也不报错,但规范化写法是不写。
stdio.h这个头文件里放的是printf、scanf、getchar、putchar这些函数的声明。少了这一行,编译器在遇到printf时会认为这个函数没有被声明过,行为就不确定了。
main 函数有两条硬约束,题库反复在这上面出题。第一条:一个可以独立运行的程序,有且只有一个main()函数,它是程序入口。第二条更爱考——C 程序不是从源文件的第一条语句开始执行的,而是从main()函数体的第一条可执行语句开始。源文件开头那些#include、宏定义、函数声明、甚至写在main前面的其他函数定义,都不属于「执行起点」。
| 说法 | 判定 | 理由 |
|---|---|---|
| 程序从源文件第一行开始执行 | 错 | 起点是 main 函数体第一条可执行语句 |
| 程序从 main 的第一条可执行语句开始执行 | 对 | 注释、空行、声明不算可执行语句 |
| 一个程序可以有多个 main | 错 | 独立程序有且只有一个入口 |
| 一个程序可以没有 main | 错 | 缺入口,链接阶段就过不去 |
提示:判断题里出现「任何」「必须」「只能」这类绝对化措辞时,先别急着判错,回到规则本身核对一遍。C 语言的硬规则确实不少,绝对化措辞只是提高警惕的信号,不是判错依据。
2.2 分号、复合语句与空语句
C 语言里语句以分号结束,这条规则本身没难度,难度在分号的三种不同身份上。第一种是普通语句的结束符,sum = sum + i;后面那个。第二种是复合语句的边界,一对大括号{}把多条语句括起来,语法上整体算作一条语句,所以if、for、while后面的循环体或分支体如果是多条语句,必须用大括号包起来;包起来之后,它对外就是「一条语句」,不需要在右大括号后面再加分号。第三种最容易被忽略——单独一个分号构成空语句,它什么也不做,但它是合法的、完整的语句。
空语句单独出现没危害,混进控制结构里就是灾难。下面这段代码是理论考里最经典的陷阱之一:
int i, sum = 0; /* 注意 for 后面这个分号:它构成一条空语句,成了整个循环的循环体 */ for (i = 1; i <= 10; i++); { sum = sum + i; /* 大括号块和 for 无关,只执行一次,此时 i 已经是 11 */ }这段代码跑完sum是 11,不是 55。逻辑上拆开看:for的循环体是那个空语句,循环老老实实跑了 10 次,每次什么也不干,跑完之后i停在 11;后面的大括号块是一条独立的复合语句,顺序执行一次,sum = 0 + 11。要改成累加 1 到 10,得把分号删掉,让大括号块成为循环体。写循环时养成一个习惯:for那一行结尾看到分号就停下来确认一下,这是踩坑率最高的位置之一。
复合语句还有一条判定要点:因为它在语法上被视为一条语句,所以它可以出现在任何「只允许一条语句」的位置。if (x > 0) { a = 1; b = 2; }是合法的,两个赋值被大括号打包成一条。反过来,if (x > 0) a = 1; b = 2;里只有a = 1受条件控制,b = 2是无条件执行的,这是另一类高频错题。
2.3 变量必须先声明后使用
k = 1; int k;这样的程序段不符合 C 语言语法,原因是变量k在被赋值时还没有声明。C 语言要求先声明后使用,声明的作用是告诉编译器「这个名字存在,类型是这个,给它留一块空间」。声明之后,这个变量就代表内存中的一个存储单元,对变量的读写就是对这个存储单元的读写——这条判定在题库里以「C 程序中定义的变量,代表内存中的一个存储单元」的形式出现,是对的。
正确顺序只有一种写法:
int k; /* 先声明:告诉编译器 k 是 int 类型,分配存储单元 */ k = 1; /* 再使用:把 1 写进 k 对应的存储单元 */ /* 或者声明的同时初始化,效果一样 */ int m = 1;参数说明:int k;是定义性声明,既声明名字又分配空间;k = 1;是赋值表达式语句,要求k已经可见。如果在函数内部写k = 1;而前面没有int k;,编译器会报「未声明的标识符」,这不是警告,是错误。
同一节里还有一条关于单目运算符的判定:单目运算符只需要一个操作数。++、--、!、-(取负)、sizeof都是单目,+、-、*、/、%在双目语境下需要两个操作数。判断这类题不用背表,抓住「单目 = 一个操作数」这个定义就够了:fahr++只有一个操作数fahr,是单目;a + b有两个操作数,是双目。
3. 表达式与输入输出:优先级、整数除法、赋值陷阱与格式对齐
这一章是整份题库里失分最集中的区域,因为这里的规则彼此咬合:优先级影响求值顺序,类型影响运算结果,格式串影响输入输出能不能对上。任何一环记错,整道题的结论就反了。复习时不要孤立地背某一条,要把它们串成一条链:先看操作数类型,再看运算符优先级,最后看格式串匹配。
3.1 运算符优先级与隐式乘法的缺失
赋值运算符的优先级低于算术运算符,这一点决定了n = 10 + 2先算加法再赋值,n得 12。题目里有一种反向考法:假设赋值优先级比算术高,问n是多少。按假设走一遍,n = 10先执行,得到 10,然后+ 2无处可去,整段不成立。这类「假设规则反过来」的题,考的是你能不能按给定前提推演,而不是考真实规则,读题时盯住「假设」两个字。
比优先级更容易错的是运算符缺失。5(fahr-32)/9这种写法在 C 语言里不成立,因为 C 没有隐式乘法,数字和括号之间必须显式写出*。题库里这类题在标注上有出入,复习时以规则为准:任何两个操作数之间必须有运算符,5 * (fahr - 32) / 9才合法。写温度转换这类公式时,5.0 * (fahr - 32) / 9.0是标准写法,用5.0和9.0而不是5和9,是为了让整个表达式按浮点运算走。
另外两条合法性判定经常一起出现。x + y = 22不合法,因为赋值号左边必须是可修改的左值,x + y是一个表达式结果,没有对应的存储单元,不能作为赋值目标。x % 2在x声明为double时不合法,因为取模运算符%只接受整型操作数。
| 表达式 | 前提 | 是否合法 | 原因 |
|---|---|---|---|
5 * (fahr - 32) / 9 | int fahr; | 合法 | 运算符完整,整型运算 |
5(fahr - 32) / 9 | int fahr; | 不合法 | 缺乘号,C 无隐式乘法 |
x + y = 22 | int x, y; | 不合法 | 赋值左侧不是左值 |
x % 2 | double x; | 不合法 | %只接受整型 |
n = 10 + 2 | int n; | 合法 | 加法先于赋值 |
3.2 整数除法与类型提升
整数除法是这份题库里出现频率最高的知识点,没有之一。规则只有一条:两个整型操作数做除法,结果还是整型,小数部分直接丢弃,不四舍五入。由此推出两个结论:1 / n在n的绝对值大于 1 时恒为 0,因为真实结果在 0 和 1 之间,取整后是 0;1 / 2得 0,不是 0.5。
要让结果带小数,必须让参与运算的至少一方是浮点类型。写法上有三种,效果一样:
int i, n = 4; double a = 1.0 / i; /* 1.0 是浮点字面量,i 被提升为 double */ double b = 1 / (double)i; /* 强制转换,把 i 临时转成 double */ double c = (double)1 / i; /* 转换分子,同样触发浮点除法 */ /* 反例:两边都是 int,结果先取整再赋给 double,得到 0.000000 */ double d = 1 / i;参数说明:类型提升的规则是「低精度向高精度靠」,int和double混算时int先转成double。所以关键不是结果变量声明成什么类型,而是除法执行的那一刻两个操作数是什么类型。很多题的陷阱就设在这里:结果变量是double,但除法两边都是int,赋值发生在取整之后,白搭。
求1 + 1/2 + 1/3 + ...前 N 项和的题,四个选项的差别就落在这几个点上:sum有没有初始化、sum声明成int还是double、累加项写1.0/i还是1/i、for里的分隔符是分号还是逗号。逐项排查的方法是按顺序问自己四个问题:变量初始化了吗、类型够宽吗、除法是浮点还是整数、语法结构对吗。四个都对,才是正确答案。
sum未初始化是个隐蔽的坑。int i, sum;之后直接sum = sum + i;,用的是不确定值,结果不可预期。理论考里凡是出现「执行以下程序段,sum 的值是」而sum没初始化的,判定一律往「结果不确定」上靠,不要真去算。
3.3 赋值=与相等==的混淆
if (x = 20)这种写法在语法上合法,在语义上是错的。=是赋值运算符,整个表达式的值是赋值之后x的值,也就是 20;20 非零,条件恒为真,else分支永远进不去,x也被改成了 20。题目问「执行后 x 的值不变」,判定是错——x被改写了。
同类题里还有else if (x = 0)的变体,这时候赋值表达式的值是 0,条件恒为假,这个分支永远进不去,x同样被改成 0。两个方向都要会判:赋非零值恒真,赋零值恒假。
注意:编译器对
if (x = 20)通常只给警告不给错误,所以代码能编译、能运行、结果错。理论考抓的就是这个「能跑但不对」的缝隙。
防这类错误有个几乎零成本的习惯:写条件时把常量放左边,if (20 == x)。万一手滑写成if (20 = x),编译器直接报错,因为 20 不是左值。这个写法在团队里叫「尤达条件」,看着别扭,但确实能省掉一类排查成本很高的调试。
3.4 scanf 与 printf 的格式串对齐
格式串和变量类型必须严格对应,这是输入输出部分唯一的硬规则。对应关系如下:
| 数据类型 | scanf 格式符 | printf 格式符 | 常见错法 |
|---|---|---|---|
int | %d | %d | 用%f读 int |
float | %f | %f | — |
double | %lf | %f | scanf 用%f读 double |
char | %c | %c | 用%d读字符 |
| 字符串 | %s | %s | — |
最容易记混的一格是double:scanf读double必须用%lf,因为要区分float和double的存储宽度;printf输出double用%f就行,因为可变参数在传递时float已经自动提升为double,不需要再区分。这一格不对,输入输出全是垃圾值。
double x; /* 正确:double 配 %lf */ scanf("%lf", &x); printf("%.2f\n", x); /* 输出保留两位小数 */ /* 错误示范一:double 配 %d,读进来的是垃圾,且可能破坏内存 */ scanf("%d", &x); /* 错误示范二:double 配 %f,格式符宽度对不上 */ scanf("%f", &x); /* 错误示范三:变量是 int,格式串却写 %lf */ int year; scanf("%lf", &year);格式串里除了转换说明,还可以夹普通字符,这些字符在输入时必须原样敲进去。scanf("x=%lf", &x)要求用户输入x=30这样的形式,只敲30是匹配不上的,x拿不到值。这类题判断的关键是:格式串里的非格式字符属于「必须匹配的字面内容」,不是提示文字。
scanf里空格的处理也常考。格式串中的空格表示「跳过任意数量的空白字符」,scanf("%d %lf %d", &a, &b, &c)里两个空格的作用是允许输入时用任意多个空格、制表符或换行分隔。但格式串末尾多写一个空格,会让scanf停下来等更多输入,因为它在等一个非空白字符来结束「跳过空白」这个动作。
printf这边重点是精度和宽度。%.2f表示小数点后保留两位,%4d表示输出至少占 4 个字符宽度、右对齐、不够左边补空格,%6.1f表示总宽度 6、小数一位。这类格式串在算循环执行次数、输出对齐的题里经常配套出现,判断时不需要精确还原输出,只要确认格式符和变量类型对得上。
3.5 字符常量与 ASCII 码
字符常量用一对单引号括起单个字符,'A'、'z'、'0'、'$'都是合法的字符常量。字符型数据的值就是它在 ASCII 字符表里的次序值,所以'A'的值是 65,'a'是 97,'0'是 48。判定题里最爱考的两个反直觉点:
第一,数字字符'1'的值不是数字 1,是 49。'1' - '0'才等于 1,这是把字符转成对应数值的标准写法。
第二,大小写字母的 ASCII 码差 32,且小写比大写大。'a' - 'A' == 32,所以'a'的值比'Z'大。'D' - 'A' == 'd' - 'a'这个表达式为真,因为两边都等于 3,大小写偏移量相同。
排列规律要记牢三组:'0'到'9'升序连续,'A'到'Z'升序连续,'a'到'z'升序连续。但三组之间不连续——'9'后面紧跟的不是'A','Z'后面紧跟的也不是'a',中间夹着其他符号。
字符输入输出用getchar和putchar,不是只能靠printf和scanf。putchar('S')在屏幕上输出的是S,不带引号;引号只是代码里标记「这是字符常量」的语法符号,不参与输出。getchar()从输入流读一个字符,scanf("%c", &ch)也能读,两者在单字符场景下都能用。
4. 流程控制:if-else 配对、switch 穿透与 for 边界
流程控制这部分题的特点是「代码看着顺,结论反着来」。缩进、换行、大括号位置都会骗人,唯一可信的是语法规则。复习时把每条规则还原成一句话,遇到题就拿这句话去套,比凭眼睛扫代码靠谱得多。
4.1 悬空 else 与分支覆盖
else的配对规则只有一句:和之前最近的、还没有配对的if配对。缩进不参与配对,纯粹是给人看的排版。
int a = 2, b = -1, c = 2; if (a < b) if (b < 0) c = 0; else c++; /* 这个 else 配的是内层 if (b < 0),不是外层 */分析这段:a < b即2 < -1为假,外层if的整个语句体(包含内层if-else)被跳过,c保持 2。如果误以为else配外层,就会算成c加 1 得 3。这类题的正确做法是先在纸上给每个if标号,再连线配对,别用眼睛直读。
分支覆盖的题考的是测试用例设计。规则是:每个分支至少要被一组用例走到,用例数等于需要区分的等价类数量。几个典型数字要记住:
| 分支结构 | 分支数 | 最少用例数 | 说明 |
|---|---|---|---|
if (grade < 60)单分支 | 2 | 2 | 小于 60、大于等于 60 |
if-else双分支 | 2 | 2 | 真假各一 |
if-else if-else三分支 | 3 | 3 | 大于、小于、等于 |
else-if五区间 | 5 | 5 | 小于 0、0、0 到 15、15、大于 15 |
| 字符分类三分支 | 3 | 63 | 52 字母 + 10 数字 + 1 其他 |
字符分类那道题容易算错,因为分支只有三个,但字母分支覆盖的是 52 个字符(26 大写 + 26 小写),数字分支覆盖 10 个,其他分支至少 1 个,加起来 63。这里的原则是:用例数按「能区分出不同处理路径的输入类别」算,不是按分支语句的条数算。
还有一类嵌套题要注意:if或else后面跟的分号会截断分支体。
int x = -5, y = 0; if (x >= 0); /* 分号让 if 的分支体变成空语句 */ if (x > 0) y = 1; else y = -1; /* 这个 else 配的是内层 if,与外层无关 */ /* 结果:x = -5,内层 if (x > 0) 为假,走 else,y = -1 */4.2 switch 的三条硬规则与穿透
switch的规则不多,但每条都能单独出题。第一条:case后面必须跟常量表达式,不能是变量,也不能是关系表达式。case choice == 1:不合法,因为choice == 1是一个求值结果,不是常量。第二条:同一个switch里case的值不能重复。第三条:default可以省略,位置可以放在任意地方,不一定在最后。
执行流程分两种,差别全在break上:
| 写法 | 匹配到 case 之后的行为 | 常见考点 |
|---|---|---|
每个 case 带break | 执行对应语句段后跳出 switch | 与 if-else 链等价 |
不带break | 从匹配位置一直往下执行,穿透到后面所有 case | 输出结果叠加 |
default写在中间 | 位置不影响匹配优先级,只有全部 case 不匹配才进 | 判断等价性 |
不带break的穿透不是 bug,是有意设计的特性,只是大多数场景下不符合预期。看这道题:
int x = 1, a = 0, b = 0; switch (x) { case 0: b++; /* x 是 1,不匹配,跳过 */ case 1: a++; /* 匹配,执行;没有 break,继续往下 */ case 2: a++; b++; /* 穿透进来,继续执行 */ } /* 结果:a = 2, b = 1 */判断这类题的方法是从匹配点开始往下数,数到switch的右大括号为止,中间遇到的每条语句都算执行。等价性判断题则反过来:把每个switch的完整执行结果(包括default兜底)算出来,逐一比对,只有在所有输入下结果都相同才叫等价。default放在最前面但带break的写法,和放在最后的写法是等价的,因为匹配优先级相同。
break的使用范围也要记清:break可以用在switch和循环里,不是只能配switch;switch里不一定非用break不可,也不一定非用default不可。两条「必须」都是错的。
4.3 for 三表达式的执行顺序与次数计算
for (表达式1; 表达式2; 表达式3) 循环体的执行顺序固定:表达式1 只在进入循环前执行一次;表达式2 在每次循环体执行前求值,为真就执行循环体,为假就结束循环;表达式3 在每次循环体执行完之后执行。
int fahr; double celsius; /* 表达式1:fahr = 91,只执行 1 次 表达式2:fahr <= 100,每次循环前判断,共判断 11 次(第 11 次为假) 表达式3:fahr++,每次循环体后执行,共执行 10 次 */ for (fahr = 91; fahr <= 100; fahr++) celsius = 5.0 * (fahr - 32) / 9.0; printf("%4d%6.1f\n", fahr, celsius);这段代码的循环次数算法是(100 - 91) / 1 + 1 = 10,也就是(终值 - 初值) / 步长 + 1。三个数字要分清:表达式2 求值 11 次(10 次为真、1 次为假)、循环体执行 10 次、表达式3 执行 10 次。循环结束后fahr是 101,不是 100——fahr++在最后一次循环体后把 100 加到了 101,然后表达式2 判断 101 <= 100 为假,退出。问「循环结束时循环变量的值」的题,答案永远是「越过终值的第一个值」。
循环里还有两个初始化问题,属于同一类错误的两个面:
/* 问题一:sum 未初始化,累加结果不可预期 */ int i, sum; for (i = 1; i <= 10; i++) sum = sum + i; /* 正确写法:int i, sum = 0; */ /* 问题二:阶乘的累乘单位元是 1,不是 0 */ int i; double product; product = 0; /* 错:0 乘任何数都是 0,结果恒为 0 */ for (i = 1; i <= 20; i++) product = product * i; /* 正确写法:product = 1; */累加的单位元是 0,累乘的单位元是 1。这个「单位元」的概念比死记「加法初始化为 0、乘法初始化为 1」更牢,遇到新的累运算(累除、累乘方)也能自己推。另外,累乘的变量类型要够宽,int存 13 以上的阶乘就会溢出,题目里通常把product声明成double就是在提示这一点。
5. 易漏点:五类最容易翻车的判定
这一章把散在各处的坑集中收一遍。每条按「易漏点 → 为什么漏 → 怎么补」写,补法都是能立刻用上的动作,不是「多练习」这种空话。
5.1 易漏点一:整数除法的取整发生在赋值之前
为什么漏:眼睛看到结果变量是double,就默认整个计算是浮点的,忽略了除法执行的那一刻两个操作数都是int。类型提升只发生在混算时,不发生在赋值时。
怎么补:读到一个除法表达式,先圈出两个操作数,分别看它们声明成什么类型。两个都是整型、又希望得到小数结果,就必须在分子或分母上加.0或强制转换。养成写完除法回头看一眼操作数类型的习惯,比事后 debug 便宜得多。
5.2 易漏点二:格式串和变量类型错位
为什么漏:%d、%f、%lf长得太像,double在scanf里要用%lf、在printf里用%f这个不对称最容易记混。而且类型错了代码照样编译通过,只是结果变成垃圾值。
怎么补:把对应关系压缩成一句口诀——「读 double 带 l,写 double 不带」。scanf是「读」,要%lf;printf是「写」,用%f。另外格式串里的普通字符(比如x=)必须原样输入,这一点在判断题里常被当成「可以省略」。
5.3 易漏点三:条件表达式里混进赋值号
为什么漏:if (x = 20)和if (x == 20)只差一个字符,扫一眼根本分不出来。而且赋值表达式有值,语法合法,编译器只警告不报错。
怎么补:看到if、while、for的条件里出现单个=,立刻标红。判断结论时按「赋值表达式的值决定真假」推:赋非零恒真,赋零恒假,同时被赋值的变量已经被改写。写代码时把常量放左边,让编译器帮你拦。
5.4 易漏点四:switch 的穿透和 default 的位置
为什么漏:case标签看起来像「分支入口」,直觉上以为匹配到哪个就只执行哪个,忘了没有break会一路往下走。default写在最前面时,又容易误以为它有更高的匹配优先级。
怎么补:判穿透类题,从匹配的case开始往下画一条竖线,画到右大括号,线经过的语句全算执行。判default位置类题,记住匹配规则是先比case、全不比才进default,位置只影响代码可读性,不影响逻辑。
5.5 易漏点五:循环结束后的循环变量值
为什么漏:算循环次数时盯着「跑了几轮」,忘了问「跑完之后变量停在哪」。for (i = 1; i <= 10; i++)跑 10 轮,但i结束时是 11,因为i++先执行、条件判断后失败。
怎么补:把三个量分开记——条件判断次数、循环体执行次数、循环变量终值。终值等于「最后一次让条件成立的值再走一步」。题目问「语句①执行了几次」和「循环体执行了几次」时,先确认语句①在循环体内还是循环体外,位置不同答案可能差一次。
6. 复习清单:按判定路径把判断题重走一遍
复习到这一步,知识点已经铺开了,缺的是一条能重复走的路径。理论考的判断题和选择题,绝大多数可以拆成三步判定,按顺序走,比凭印象答稳得多。
| 步骤 | 看什么 | 典型结论 |
|---|---|---|
| 第一步:语法边界 | 运算符是否完整、声明是否在前、分号位置 | 缺乘号、声明后用、for 后多分号 |
| 第二步:类型匹配 | 操作数类型、格式串、赋值目标 | 整数除法、%lf对 double、左值检查 |
| 第三步:流程走向 | else配对、break有无、循环边界 | 就近配对、穿透、终值越界 |
第一步最容易得分,因为它只要求你认识语法。看到5(fahr-32)/9、x + y = 22、x % 2(x是double)这类写法,先别管它想算什么,只看合不合法。这一步过了再往下。
第二步是失分重灾区。做一道输入输出题,先把变量声明抄在草稿纸左边,格式串抄在右边,一一连线,连不上的地方就是答案。做一道表达式题,把每个操作数的类型标在它头顶上,除法、取模、赋值三类运算逐个核对。
第三步管流程。判断题里出现嵌套if,先给每个if编号再配对;出现switch,先看有没有break;出现for,先把三个表达式各执行几次列出来。这三件事都是机械动作,练几遍就能形成条件反射。
有一条血泪经验值得记:题库里少数题目的标注和语法规则存在出入,比如隐式乘法、格式串类型这类。遇到这种题,考试时按题库记,写代码时按规则来,两套系统分开存,别用其中一个去覆盖另一个。真正的能力是知道哪条是规则、哪条是题库的约定,而不是把两者混成一锅。
从那以后我每次做理论题前,都强制走一遍「先看语法边界、再看类型匹配、最后看流程走向」这三步,草稿纸上必定留三行痕迹,一行都不省。这份文档我按判断题、选择题分好了块,答案和题干放在一起,适合对着这张清单一条条过。系统学的时候当地图用,考前当查漏补缺用,两种用法都不冲突。希望帮到你。
本文还有配套的精品资源,点击获取