简介:这份PTA理论考复习资料以Word文档形式整理了HW02、HW03等章节的判断题与参考答案,覆盖C语言基础语法、编译预处理命令、main函数作用、变量内存分配、单目/双目运算符、赋值与算术优先级、scanf/printf格式控制以及for循环求和、阶乘等高频考点,适合正在刷PTA平台理论题、需要快速核对答案并理解易错知识点的初学者。资源包共包含1个docx文档,约345KB,轻量便携,支持在Word中按关键词定位查找题目与答案解析。目前已有1895人学习使用。文档后半部分还附有详细知识点讲解,针对整数除法、浮点数取模、scanf读取格式、空语句与复合语句等常见陷阱逐条辨析,可帮助读者在刷题之外系统梳理C语言核心概念,有效减少理论考失分点。
1. 考前刷 PTA 理论题:这份 docx 就是现成的 C 语言判断题错题本
期末前一周,群里最热闹的永远是“PTA 上 1-14 这道题选 T 还是 F”“1-17 的代码为什么运行结果和我手算的不一样”。判断题看着只有两个选项,实际每一道都在抠语法细节,先声明后使用、整数除法截断、%f 与 %lf 的类型匹配,任何一个知识点没记牢,就是五五开靠猜。这份“PTA理论考部分.docx”把高频判断题和选择题按题号整理在一起,题目、代码片段、T/F 选项都在同一个文档里,适合两类人:一类是刚开始刷 C 语言题、需要一份带答案的题集逐题对照;另一类是考前突击,用题号快速锁定自己没掌握的知识点。它不是教材,但比教材更接近考场的问法。
2. 考点地图:这份题集覆盖的六类高频判断题
先把文档里的题按考点归类,你会发现 PTA 理论考的出题套路非常固定,翻来覆去就是程序结构、变量与表达式、运算符、格式化输入输出、循环、分支与字符这几块。下面这张表是我按题号整理出来的考点分布,方便你拿到文档后直接对号入座。
| 考点类别 | 典型题号 | 核心判断依据 |
|---|---|---|
| 预处理与程序结构 | 1-3、1-5、1-6、1-7 | include 不加分号,程序从 main 开始 |
| 变量声明与表达式 | 1-10、1-11、1-12、1-13、1-14 | 先声明后使用,% 只作用于整型 |
| 运算符与自增 | 1-17、1-18、1-14(HW03) | 赋值优先级低于算术,i++ 会改变原值 |
| 格式化输入输出 | 1-7、1-8、1-9、1-11 | 格式串与变量类型必须一一匹配 |
| for 循环 | 1-15、1-16、1-21 至 1-24、4-2 | 表达式 1 只执行一次,注意初始化 |
| 字符与 ASCII | 1-10 至 1-24(HW04) | ASCII 码顺序、大小写差 32 |
| switch 分支 | 1-27 至 1-33、2-5 至 2-9 | case 必须常量,无 break 会穿透 |
2.1 程序结构三连问:预处理、main 函数、执行起点
第一类题基本送分,但错的人最多的是 1-3 这道:
#include <stdio.h>; // 这是编译预处理命令题目问这句话对不对,答案是 F。#include是预处理指令,不是普通 C 语句,末尾不能加分号。实际写代码时你在 VS Code 里按分号,编译器通常会警告甚至报错,PTA 理论考就是把这些细节单独拎出来问你。类似的还有 1-5“任何一个程序都必须有而且只能有一个 main() 函数”,这是对的;1-6“C 语言程序是从源文件的第一条语句开始执行的”,这是错的,执行永远从 main 函数的第一条语句开始,源文件里 main 之前的全局声明和宏定义都不算执行语句,哪怕 main 写在文件最后也一样。
判断这类题有个通用技巧:看到“第一条语句”“只能有一个”“必须”这类绝对化表述,先想有没有例外。main 函数确实只能有一个,这是标准规定的;但“从第一条语句开始执行”这个说法默认了第一条语句在 main 里,而源文件开头往往是#include和宏定义,所以是错的。
2.2 变量与表达式合法性:先声明再使用是底线
1-10 这道题给了一个反直觉的片段,很多人第一眼看觉得没毛病:
k = 1; int k;答案是 F,不符合 C 语言语法。C 语言要求变量先声明后使用,这里先把 1 赋给一个不存在的变量,声明放在后面毫无意义,编译直接报“未声明的标识符”。这类题在 PTA 里反复出现,换了个马甲而已:有时候把int k;放到k = 1;后面,有时候用int x, y;然后写x + y = 22;。后者同样是 F,因为赋值号左边必须是一个左值,表达式x + y不是变量,不能作为赋值目标。
1-12 说“单目运算符需要 2 个操作数”,一眼假。单目就是你只有一个数,比如++i、-x、!flag;双目才是两个,比如a + b。1-14 说double x时x % 2符合语法,这是经典陷阱。%是取余运算符,C 语言明确规定只能用于整型操作数,对double用%编译直接报错。做题时看到浮点数和%同框,不用犹豫,直接选 F。
2.3 运算符优先级:赋值表达式本身有值,这是最大的坑
HW03 里的 1-4,题干给了这么一段:
if (x = 20) { y = 1; } else { y = 0; }问执行后 x 的值变不变。答案是 F,x 的值会变,而且这个 if 条件永远为真。原因在于x = 20不是比较,是赋值表达式,这个表达式的值就是 20,非零即为真,else 分支永远不会执行。你以为是在判断 x 是否等于 20,实际是在给 x 赋值的途中顺手做了个条件判断。
原始题 1-18 还说了一件事:“假设赋值运算符的优先级比算术运算符高,执行int n; n = 10 + 2;后 n 的值为 10。”这句话也是 F。不是结果算不对,而是“假设”本身就是错的,C 语言里赋值优先级低于算术,所以n = 10 + 2是先算10 + 2得到 12,再赋给 n。PTA 经常用这种错误假设来钓鱼,看到“假设”两个字就要警觉,按真实标准判断,别顺着它的假设往下想。
2.4 printf/scanf 格式串:类型对不上,输出全乱
格式化输入输出是这套题里翻车率最高的部分,尤其 1-7、1-8、1-9 三道连在一起:
// 1-7:double x; scanf("%d", &x); 输入 10,输出 10.00 double x; scanf("%d", &x); printf("%.2f", x);答案是 F。%d期望一个int*,你给了double*,scanf 会按 int 的大小把数据写到 x 的前半段内存里,double 的高位字节是随机值,输出大概率不是 10.00。1-8 把格式串换成%f,同样不对,%f对应的是float*,类型不匹配是未定义行为。1-9 更狠:
scanf("x=%lf", &x);如果输入只是30,没有x=前缀,scanf 匹配失败,x 根本没被赋值。要想成功,必须输入x=30才行。格式串里的普通字符必须原样匹配输入,这不是描述,是匹配规则。
1-11 给的是格式串顺序和变量不对应:
int money, year; double rate; scanf("%d %lf %d ", &money, &year, &rate);答案是 F。变量顺序是 money、year、rate,格式串顺序却是%d %lf %d,第二个%lf会读到 year 的地址上,第三个%d读到 rate 的地址上,整型和浮点全乱套了。记忆方法很简单:scanf 的参数从第二个开始,必须和格式串里的转换说明从左到右一一对应,类型也要匹配,差一个都不行。
2.5 for 循环执行次数:边界、初始化、类型三个变量一起看
1-21 到 1-24 是循环题的重灾区,先看 1-21:
int i, sum; for (i = 1; i <= 10; i++) { sum = sum + i; }题目说 sum 的值是 55,答案是 F。理由很直接:sum 没初始化,初始值是不确定的(通常默认 0,但标准不保证),拿不确定的值去累加,结果无法判断。你可能会说“运行起来就是 55”,但理论考考的是语言标准,不是某台机器的运行结果。1-22 的阶乘题同理:
int i; double product; product = 0; for (i = 1; i <= 20; i++) { product = product * i; }答案是 F。product 初始值为 0,0 乘任何数都等于 0,算出来是 0 而不是 20 的阶乘。这就是典型的“看着像阶乘,实际是零乘法”。
4-2 是计算执行次数的大题,题干代码很经典:
int fahr; double celsius; for (fahr = 91; fahr <= 100; fahr++) celsius = 5.0 * (fahr - 32) / 9.0; // 语句① printf("%4d%6.1f\n", fahr, celsius); // 语句②语句①执行 10 次(fahr 从 91 到 100),语句②执行 1 次,循环体共执行 10 次,循环结束时 fahr 的值是 101。最后一点是高频考点:for 循环结束后,控制变量停在第一个不满足条件的位置,也就是 101。很多人填 100,那是循环最后一次执行时的值,不是结束后的值。
2.6 ASCII 码顺序与 switch 语法:记忆要精确到差值
字符类的判断题,核心就两个记忆锚点:一是大小写字母 ASCII 差 32,二是数字字符按升序连续排列。文档里有道题问“数字字符 '1' 的值就是数字 1”,答案是 F,'1' 的 ASCII 码是 49,和数字 1 差了十万八千里。还有“大写字母 'M' 的 ASCII 码比小写字母 'm' 大”,这也是 F,大写字母统一比小写小 32,'M' 是 77,'m' 是 109。
switch 的语法坑集中在 1-28 到 1-33。case 常量表达式的值不能相同,1-28 说“可以相同”,选 F;default 必须使用,1-29 选 F,default 是可选的不是必须的;1-30 更典型:
switch(choice) { case choice == 1: price = 3.0; break; }答案是 F。case 后面必须是整型常量表达式,像choice == 1这种比较表达式是运行期才能确定的值,编译器不认。后面 1-32“case 语句后如没有 break,顺序向下执行”是对的,这就是 switch 的穿透规则,实际开发里漏写 break 导致的 bug,在理论题里反而是考点。
3. 把易错题拆开看:赋值、除法和格式串的四个雷区
第 2 章把考点过了一遍,这一章挑四个最容易被误判的题目类型深入拆解,每一类都配有反例和调试思路。你会发现 PTA 判断题的 T/F 背后,考察的是 C 语言规范里几个很具体的边界条件。
3.1 if(x = 20):赋值表达式当条件,永远为真
这道题值得反复说,因为选择题里出现过,判断题里也出现过。if (x = 20)在 C 语言里完全合法,它做两件事:先把 20 赋给 x,然后判断这个赋值表达式的值(也就是 20)是否为真。非零即为真,所以 if 分支必然执行。
#include <stdio.h> int main(void) { int x = 5; if (x = 20) { // 注意是单等号,不是双等号 printf("always true\n"); } else { printf("never here\n"); } printf("x = %d\n", x); // 输出 x = 20 return 0; }逻辑说明:第 4 行的x = 20是赋值表达式,不是比较,所以 else 分支不可达,x 从 5 被改成 20。PTA 原题说“x 的值不变”,显然错误。
参数说明:如果你本来想比较,必须写成if (x == 20)。我一般建议在代码里用“常量放左边”的写法:if (20 == x),这样万一少写一个等号变成20 = x,编译器直接报错,不会留到运行期才暴露问题。
3.2 整数除法 1/n:绝对值大于 1 时恒为 0,前提是 int
1-15 说“若变量定义为 int n,当 n 的绝对值大于 1 时,表达式 1/n 的值恒为 0”,这个说法本身是对的。C 语言里两个整数相除,结果还是整数,小数部分直接截断,1/2得 0,1/(-2)也等于 0(向零取整)。真正坑人的是 1-23 和 1-24 这类把整型除法和浮点初始化混在一起的题:
// 1-24:int i; double sum; sum = 0; int i; double sum; sum = 0; for (i = 2; i <= 4; i = i + 2) { sum = sum + 1/i; }题目说 sum 的值是 0.75,实际是 0。原因在1/i:i 是 int,1/i按整数除法计算,i=2 时结果是 0,i=4 时结果也是 0,累加了两次 0。想得到 0.75 必须写1.0/i,把其中一个操作数变成 double,才会触发浮点除法。判断这类题时先问自己一句:除法两边是不是都是整型?只要都是整型,结果就不可能带小数。
3.3 scanf 格式串是精确匹配,不是描述
scanf("x=%lf", &x)这道题值得单独拉出来讲,因为它考察的是 scanf 的一个冷门行为:格式串里的普通字符必须与输入字符逐个精确匹配。
double x; scanf("x=%lf", &x); printf("%.2f", x);如果运行时光标闪动,你直接输入30回车,scanf 发现第一个字符不是x,立即停止匹配,返回值是 0,x 没有被赋值。只有输入x=30这种带前缀的形式,x=匹配成功,%lf才能读到 30。很多人写代码时喜欢在格式串里加提示前缀,比如scanf("请输入:%lf", &x),这在实际程序里会造成输入负担,PTA 理论题考的就是这个行为差异:格式串里写了什么,用户就必须输入什么。
3.4 switch 无 break:穿透的执行顺序
选择题 2-9 是 switch 穿透的经典题:
#include <stdio.h> int main(void) { int x = 1, a = 0, b = 0; switch(x) { case 0: b++; case 1: a++; case 2: a++; b++; } printf("a=%d,b=%d\n", a, b); return 0; }逻辑说明:x 的值是 1,程序从case 1进入,执行a++使 a 变成 1;因为没有 break,继续向下穿透到case 2,执行a++; b++;,a 变 2,b 变 1。最终输出a=2,b=1,对应选项 A。
参数说明:每个 case 后面如果没有 break,执行流会一直往下走,直到遇到 break 或者 switch 结束。判断题 1-32 说“case 语句后如没有 break,顺序向下执行”,就是对的。实际开发里忘记 break 产生的 bug,在理论题里反而是需要你选 T 的正向考点。
4. 把判断题改造成选择题:三遍刷题法
这一章讲方法。文档里的判断题只有 T/F 两个选项,但你可以自己做二次加工,把它们变成带解析的选择题,这个过程本身就是高效的复习。
4.1 找反例:判断题的 T 必须“无条件成立”
判断一个命题对不对,最有效的方法是尝试找反例,反例找不到就先存疑。比如 1-13 说若变量定义为 int fahr,则 5(fahr-32)/9 是符合 C 语言语法的表达式,这里的反例是语法层面的:5(fahr-32)缺少乘号,数字和括号之间必须有运算符,所以这个表达式连编译都过不了,直接选 F。再比如 1-14 的double x; x % 2,反例就是 C 语言规范里 % 只接受整型。找反例的过程比题目本身有价值,因为考试时你记不住所有规范,但能记住几个典型反例。
表格式地整理你的反例库会更清晰:
| 题号 | 命题内容 | 反例/理由 | 结论 |
|---|---|---|---|
| 1-3 | include 后带分号 | 预处理指令不是语句,无分号 | F |
| 1-13 | 5(fahr-32)/9 | 缺乘法运算符 | F |
| 1-14 | double 用 % | 取余只用于整型 | F |
| 1-21 | sum 未初始化为 55 | 未定义行为 | F |
4.2 三遍刷题法:原卷、错题、复述
我拿到这类题集的标准做法是分三轮过,不要第一遍直接对着答案看。
第一轮先自测:打开文档,拿一张纸遮住右侧答案列(如果答案在题后,就遮住那一行),逐题给出 T/F 判断,做完再揭开对照。这一轮的作用是暴露问题,不要在意正确率。
第二轮只做错题:把做错的题号单独整理到一个新文档里,每题写下三句话——正确结论是什么、为什么这么判断、我当时错选了什么。这个复述过程比二刷错题本身有效,因为你在强迫自己把模糊记忆变成语言输出。
第三轮考前快速过:只看错题整理,不看原题。准备一个 python 脚本把 docx 里的题号提取出来,按题号排序生成一个空表,方便做标记:
import re with open("PTA理论考部分.docx", "r", encoding="utf-8") as f: content = f.read() # 提取 "1-3" "2-1" 这类题号 issue_ids = re.findall(r"\b(\d+-\d+)\b", content) unique_ids = sorted(set(issue_ids), key=lambda x: int(x.split("-")[0])) for idx in unique_ids: print(f"| {idx} | 对/错 | 错因 |")逻辑说明:正则\d+-\d+匹配的是文档里的题号模式,比如 1-3、2-1。set去重后按专题序号排序,输出成一个 Markdown 表格骨架,你只需要在第二列填判断结果、第三列填错因。
参数说明:如果你的 docx 是二进制格式,普通open读不了,可以先另存为.txt再用上面的脚本;也可以用更省事的办法,直接在 Word 里把全选内容粘贴到文本编辑器再跑。
4.3 统计错题主题,按频次决定复习顺序
三遍刷完之后,把错题按第 2 章的考点分类统计,大概率会发现错题集中在某一两个类别。我见过最多的两类:一类是格式化输入输出的格式串匹配,另一类是整数除法与浮点除法的混用。这两个主题在 PTA 判断题里出现的密度很高,而且容易互相纠缠。按频次排序复习,优先解决错得最多的主题,比从头到尾平均用力效率高得多。
5. 避坑与排查:这份题集里最容易误判的四个细节
使用这份 docx 的过程中,有几个实际问题不是题目本身造成的,而是文档形式和做题习惯带来的。列出来给你提个醒。
5.1 现象:答案就印在题后,自测时被眼睛提前剧透
第二行就是 “T F”,你读题的时候余光已经扫到了答案,大脑会无意识地倾向那个选项,自测结果失真。
原因:文档为了让读者方便对照,把 T/F 选项直接放在题干后面,这是它的优点,也是自测时的干扰源。
解决:第一遍自测时,把每一题的 T/F 区域用不透明纸条遮住,只露出题干文字,全部做完再统一揭开核对。或者另存一个副本,用 Word 的查找替换把T和F批量替换成空格,生成一份纯题干燥版。
5.2 现象:题干里带“假设”二字的题,顺着假设想就错了
1-18 假设赋值运算符优先级比算术运算符高,1-11 假设输入1001 3 0.025输出符不符合预期,部分人看到熟悉的情境就放松警惕,直接按直觉选。
原因:出题人用“假设”构造了一个与 C 标准相悖的前提,目的是考察你是否真正理解标准本身,而不是考察你能不能按题干的设定推演。
解决:看到“假设”先停一下,把题干假设放一边,按 C 语言的真实规则重新分析。如果真实规则下题干的设定不成立,那么它想让你选的那个“正确”结果其实就是错误答案。
5.3 现象:手算输出与题目答案对不上,怀疑自己算错
比如 1-24 手算1/2 + 1/4感觉是 0.75,题目选 F,怎么也想不通。
原因:忽略了整数除法。1/2在 C 语言里不是 0.5 而是 0,两个 int 相除结果直接截断。这题有双重陷阱,sum 是 double 没用,因为被除式本身是整型运算。
解决:手算 C 表达式时先画类型标注。把每个运算数的类型标在表达式下面,除法两边都是整型就标“整除”,有浮点就标“浮除”。这题一标注就能看出来1/i是整除。
5.4 现象:选择题 2-2 的四个选项长得几乎一样,选不出来
选项 B 和 D 只差一个初始化位置,或者只有类型不同,逐行对比眼花。
原因:PTA 选择题的干扰项通常只改一个点,改初始化值、改变量类型、改格式串前缀,考的是细粒度记忆。
解决:四选项对比时逐个检查三个维度。第一维是变量类型,int 还是 double;第二维是初始化,是 0 还是 1;第三维是运算写法,1.0/i还是1/i。三个维度都对了才是正确答案。
6. 把 docx 变成个人速查表:题号索引、错题复述与最后一晚复习
文档的价值不只在第一遍刷题,把它加工成适合自己复习的形态,才是这份资源真正发挥作用的时刻。
我习惯把这份 docx 拆成三份使用。原始文档保留用于逐题精读;第二个副本提取题号生成速查表,每行只留题号、考点、结论三列,作为考前一天快速扫读的清单;第三个副本专门整理错题,格式是“题号 + 正确结论 + 我当时的错误判断 + 一句话解释”,用于考前一晚重点看。第三份不用长,三五十行足够,因为 PPT 上反复错的点就那么几个,比如 scanf 格式串匹配、整数除法截断、switch 穿透。
制作速查表时我把每道题的判断依据压缩成一个短语,比如 1-3 写“include 后不加分号”,1-14 写“% 只能用于整型”,1-21 写“sum 未初始化”。这些短语不是题目答案,而是我自己对这个考点的记忆钩子,看到短语能想起完整推理过程,才算真记住。
最后一晚的复习顺序也有讲究。我一般先看速查表快速过一遍全部考点,然后只看错题复述,最后找一张白纸把每个考点的关键规则默写一遍。默写不需要完整句子,写关键词,比如“printf 查类型”“for 结束值看第一个不满足条件的位置”。这个动作能把短期记忆锚定到长期区域,考试时遇到同类判断题会迅速反应出来。
这套流程看起来简单,但每一轮都在做同一件事:把被动的看题变成主动的复述。从那以后我每次考前都强制走一遍三遍刷题法,第一遍暴露问题,第二遍解决错题,第三遍只看自己写过的关键词,而不是盯着原文反复背。别低估这一遍一遍过筛子的过程,它比多刷十道新题更管用。希望帮到你。
本文还有配套的精品资源,点击获取