简介面向广州大学计算机专业C课程的一份习题答案文档系统覆盖变量、数据类型、运算符、控制结构、函数、数组、指针等基础知识点并对选择题和表达式求解给出解析适合正在学习C入门课程的学生用于课后自测与复习巩固。压缩包为单个doc文档共1个文件大小约1.55MB便于直接打开查阅和按章节索引。目前已有442人学习下载。文档以习题1的27道选择题及解答为主体涵盖标识符合法性、进制常量、运算符优先级、逻辑表达式求值、指针与引用等典型考点并配有数学表达式转C算术表达式、逻辑表达式表示条件等综合练习参考价值较集中。对于需要快速核对答案、理清C易错点的学习者来说这份材料能在期末备考或自学阶段提供明确指引帮助高效查漏补缺。1. 这门课的考点分布为什么选择题总在引用和指针上翻车看过这份C答案的人应该都有一个共同感受单选题看着都眼熟一选就错。整份习题里最反直觉、也最容易被抽去当考题的恰恰是第14到第17题那组指针和引用题——比如int i10, *pi;问 p 的值是什么很多人上来就选 10正确答案却是变量 i 的地址。这就是这门课笔试的典型考法不考你背没背概念考你对「名访问、引用访问、间址访问」三种访问方式是否真的分得清。要拿分先摸清题型的分布规律。这份资源覆盖的是C入门阶段最核心的五大模块语法与词法main函数、编译流程、标识符、常量、运算符与表达式优先级、自增自减、短路求值、控制结构if、switch、三种循环、指针与引用、简单编程题。其中运算符与表达式模块的选择题密度最高几乎占了三分之一的分值是性价比最高的得分点指针和引用则是拉开差距的区分点。下面按模块拆开讲每章直接给出高频考点和真题的答法照着练就行。2. 语法与词法基础main函数、编译、标识符与常量的高频选择题这一章对应的是习题1里的第1到第12题考点集中在C程序的基本结构、编译流程、关键字识别、合法标识符判定以及整型常量、浮点常量、字符常量的写法规则。题型以单选为主偶尔会变成判断改错题难度不大但细节非常琐碎是典型的「背了就会、不背就懵」的送分模块。2.1 程序最小单元与编译流程main函数为什么是唯一必选项选择题第1题问「一个最简单的C程序可以只有一个什么」正确答案是 main 函数。这道题考的是C程序的入口规则无论程序里有没有库函数、自定义函数操作系统都从 main 开始执行。同理第2题问「源程序变成目标程序必须经过什么」答案是编译因为C是编译型语言源文件要经过编译器翻译成机器码。这两题几乎每年都出答错的人多半是把编译和解释、汇编混在一起。做题时可以记一条主线源程序 → 编译 → 目标程序.obj→ 连接 → 可执行程序.exe。编译负责翻译语法连接负责把库文件和目标文件拼在一起。题目如果问「溢出发生在哪个阶段」本质上是在问错误产生的时机。第5题「溢出」属于运行错误因为只有程序真正跑起来、数据超出类型范围时才会发生编译阶段只检查语法检查不出数值溢出。2.2 关键字与合法标识符一套判定模板走遍所有变体第6、7题考的是关键字和标识符的区分。C关键字是语言保留的、不能用作标识符的单词比如 while、sizeof、case、extern、new。合法标识符要满足两条只能由字母、数字、下划线组成且不能以数字开头不能和关键字重名。第7题的正确答案 _abc 就是典型的合法形式new 是关键字不能用π 不是 ASCII 字符不能用带双引号的 age 是字符串常量不是标识符。这类题的快速判断顺序是先看首字符是不是数字再看有没有非法字符空格、引号、π 这类符号最后确认不是关键字。三步走完直接出答案。实际考试还可能变形为「下列哪个是非法标识符」套路完全相同。2.3 八进制、十六进制、浮点常量与字符常量格式细节决定对错进制和常量的写法是另一个爱出细节题的地方。八进制整型常量必须以 0 开头数字范围只能是 0~7所以 015 合法、080 不合法出现了 8、0a0 不合法a 不是八进制数字、0x 开头的是十六进制不是八进制。第9题选 015 就是这个道理。十六进制以 0x 开头后面跟 0~9 和 a~f0xg 错在 x 后面跟了 gg 不是十六进制数字。浮点常量的考点在三处e 前面必须有数字、e 后面必须是整数、小数点可以省略整数部分但不能两边什么都没有。第11题里 -1e3.5 错在指数是小数e-5 错在 e 前面没有数字5.0e(14) 错在指数不能是表达式。字符常量和字符串常量是高频混淆点。字符常量用单引号、只能有一个字符字符串用双引号。第12题里 \101 是合法的字符常量因为反斜杠开头的是转义序列\101 是八进制 ASCII 码对应字符 Aa 是字符串不是字符name 单引号里放了多个字符不合法。2.4 这一模块的真题速答清单题号考点正确答案一句话理由第1题程序最小结构main函数程序必须有入口第2题编译过程编译C是编译型语言第3题语句结束符分号简单语句以分号结束第6题关键字识别sizeof/case/extern全是保留字第7题合法标识符_abc下划线开头、无非法字符第9题八进制常量0150开头且只含0~7第10题十六进制常量0xgg不是合法数字第11题浮点常量12.34/-1e5/0.1E-12e前有数字且指数为整数第12题字符常量\101转义序列合法这个模块的复习策略就是背规则加刷题不需要理解太深。把进制前缀、e 的用法、单双引号的区别各写一遍选择题基本都能秒杀。3. 运算符与表达式优先级、短路、自增自减选择题的主战场如果说上一章是送分题这一章就是决定能不能上 80 分的关键。习题1里第18到第28题全部围绕运算符展开考点极其集中优先级、自增自减、逻辑短路、复合赋值、条件表达式、逗号表达式。这部分题目最大的特点是「看起来能算一算就错」因为C的求值规则和人的直觉经常不一致。3.1 优先级记忆法先背一个精简层级再处理同级结合性第18题问下列运算符中优先级最高的是哪个*高于而、*都很低所以选*。第19题问优先级最低的? :条件运算符是C里优先级最低的运算符之一低于!、、!所以选? :。优先级不需要背完整的十几行表格考试常考的层级可以压缩成一句话括号 → 单目!、、--、取址→ 算术* / -→ 关系 → 逻辑 高于 ||→ 赋值、 等→ 条件 ?: → 逗号。注意赋值和条件运算符特别低逗号最低。遇到混和表达式先按这个层级括起来再从左往右算正确率会高很多。3.2 自增自减与最贪心匹配ij 到底怎么拆第20题ij的值为 3因为C词法分析遵循「最贪心匹配」原则能多取一个字符就多取一个所以ij被拆成(i) j先取 i 的原值 1 参与加法得到 3然后 i 自增为 2。第21题ij是 4因为前置自增先把 i 变成 2 再相加。第22题问下列哪个表达式正确ab合法拆成(a)b(a)错在a不能做前置自增的操作数ab会拆成(a) b而a的结果不是左值不能再次自增。这类题的标准答题流程是第一步用贪心规则拆 token第二步判断参与运算的是原值还是自增后的值第三步注意自增结果能不能继续作为操作数。第23题i||--jk考的是另一件事——短路求值。||左边i让 i 变成 1非零即为真整个||表达式直接确定为真右边--j和k根本不会执行。所以表达式值为 1j 和 k 保持不变。第24题x || y同理x 先自增为 2非零为真||短路y 不会被自增保持 1。所以 x 是 2、y 是 1。这里特别容易错很多人写出 y2就是因为没意识到逻辑运算符的短路规则。遇到这种题先看左侧能否确定整个表达式的值能确定就立刻停。3.3 复合赋值、条件表达式与逗号表达式按执行顺序推第26题x x - x * x初看很吓人实际上遵守「从右往左」的结合顺序先算x - x * x即x 5 - 25 -20再算x (-20)即x -20 (-20) -40。这类连续复合赋值题关键是把每一个复合赋值还原成展开式并时刻盯住 x 的当前值而不是用最初的 5 代入每一步。第27题a b ? a : c d ? c : d是条件运算符的右结合。先看内层c d ? c : d34 为真结果是 3外层a b ? a : 312 为真结果是 1。第28题(x 4 * 5, x * 5), x 25考逗号表达式整个表达式的值是最后一个子表达式的结果但前面的逗号表达式要真正执行。先x20再算x*5得 100丢弃最后x2545结果为 45。3.4 条件表达式的反直觉陷阱1x5为什么错第25题是整份习题里错误率最高的一题。数学表达式1x5在C里不能直接写成1x5因为C会把1x5理解为(1x)5先算1x得到一个布尔值 0 或 1再拿这个 0 或 1 去和 5 比较结果恒为真完全失去判断 x 是否在区间内的意义。正确写法是1x x5或者用等价的x2||x3||x4。这类题在面试里也常被拿来当陷阱题答的时候要主动说出来关系运算符不能连续比较必须拆成两个独立比较再用逻辑运算符连接。这也是第1.3节「用逻辑表达式表示条件」那一整组题的通用思路。3.5 课后表达式转换题数学式改C的标准流程除了选择题这一模块还有一类必练的笔试题把数学表达式写成C表达式。原文里六个式子覆盖了常见考点答题模板如下// 1. 连分数 1/(11/(11/(xy))) double r1 1.0 / (1 1.0 / (1 1.0 / (x y))); // 2. 嵌套多项式 x{x[x(axb)c]d}e double r2 x * (x * (x * (a * x b) c) d) e; // 3. ln(1 |(ab)/(a-b)|^10) 注意fabs和pow double r3 log(1 pow(fabs((a b) / (a - b)), 10)); // 4. sqrt(1 PI/2 * cos(48 * PI/180)) 角度转弧度 double r4 sqrt(1 3.14159 / 2 * cos(48 * 3.14159 / 180)); // 5. cot((1-x^2)/(1x^2)) cos/sin double r5 cos((1 - x * x) / (1 x * x)) / sin((1 - x * x) / (1 x * x)); // 6. lg(a^2 ab b^2)以10为底的对数 double r6 log10(a * a a * b b * b);这类题有三条硬规则除法必须写成浮点数除法整数相除会直接截断三角函数、对数、幂运算要用sin、cos、tan、log、log10、pow、fabs这些库函数角度值要先转成弧度。只要照着这三条逐项翻译基本不会丢分。4. 控制结构与循环if悬挂、switch穿透、循环次数判定全解析这一章对应习题2的选择题和程序阅读题分值占比同样很高。考点集中在 if-else 的匹配规则、switch 的穿透行为、三种循环的执行次数判断以及 break、continue、goto 的使用场景。这是整份资源里「程序阅读题」最集中的模块读程序写结果的能力从这里开始真正拉开差距。4.1 if-else 悬挂与变量作用域两个必考的编译级陷阱习题2思考题第5题是一个经典案例变量 a 定义在 if 语句体内部编译时直接报a : undeclared identifier。很多人不理解为什么因为变量定义是编译期行为而 if-else 是运行期行为变量说明要求编译时就分配好存储空间放在语句体里意味着只有执行到那个分支才有定义编译器无法在分支外识别它。正确做法是把int a;提到 if 之前语句体里只做赋值。另一个高频坑是 if-else 的悬挂匹配else总是与最近的未匹配if结合。读嵌套 if 程序时先把每个 else 往上找最近的 if再逐层分析不要被缩进格式误导。典型的程序阅读题会故意把缩进写得与真实匹配关系不一致考的就是这个点。4.2 switch 的穿透行为case 只是入口标签习题2选择题第3题i2走case 2执行i--i 变成 1因为没有 break继续穿透到case 3执行ii 变成 2遇到 break 退出。很多人只算到 case 2 就停了漏掉了穿透。第2.2节程序阅读第2题也是这样外层 switch 的 case 0 结束后没有 break直接进入 case 1 执行a和b所以输出两行。switch 的答题模板一句话每个 case 分支执行完后如果没有 break就继续执行下一个 case 的语句直到遇到 break 或整个 switch 结束。default 放在哪里都会按顺序执行不是只到最后才生效。4.3 三种循环的次数判定先判断还是先执行while 是先判断后执行条件一开始为假就一次都不执行。do-while 是先执行后判断至少执行一次。for 的三个表达式里初始化只执行一次条件判断在每次进入循环体之前步进表达式在每次循环体结束之后。习题2的几道程序阅读题集中考这个。第1题while( !x i3 )初始 x0、i0!x为真且i3为真进入循环执行x后 x1再判断时!x为假整个条件为假退出。所以只执行 1 次选 d。do-while 那道题正好相反do { i--; } while( i ! 1 );i 从 3 开始第一次循环 i 变 2条件 2!1 为真第二次循环 i 变 1条件 1!1 为假退出共 2 次。第4题i4, j1模拟一遍就很清楚。for 循环判断次数的通用方法先列出每一次循环前后变量的变化再检查条件在哪一次循环开始时变假。第5题for( i1, j5; ij; i ) { j--; }每次循环 i 加 1、j 减 1循环结束时 i3、j3。这里特别要注意的是循环内 j-- 和循环步进 i 的执行顺序先执行循环体再执行步进。4.4 死循环、break 与 continue读程序时容易忽略的边界第7题选 bdo { k; } while( k0 );k 非负就永远为真是死循环。a 选项循环三次后 x3 退出c 选项 a 从 5 减到 0 退出d 选项 i 从 3 减到 0 退出。这类题检验的是对循环结束条件的敏感度。break 和 continue 的区别在程序阅读题里反复出现。break 直接结束整个循环continue 跳过本次循环剩余语句进入下一次循环的条件判断。第2.2节第3题while( i10 ) if( i % 3 ! 1 ) continue; else cout i;i 从 1 开始每次先自增再判断余数只有余数为 1 时才输出所以输出 4、7、10。第7题那个三层循环嵌套的x16考的是 continue 只影响内层循环。每次内层循环 j 为奇数时跳过后面的 x注意外层的两次 x 不受影响。这类多层嵌套题建议先写出内层循环的完整执行表再累加外层变量。4.5 编程题套路排序、三角形、成绩转换的标准框架习题2编程题有三道值得背框架。三数排序题用三次比较交换即可#include iostream using namespace std; int main() { int a, b, c, t; cin a b c; // 每次比较后保证 a 是当前最小值逐步完成升序排列 if (a b) { t a; a b; b t; } if (a c) { t a; a c; c t; } if (b c) { t b; b c; c t; } cout a b c endl; return 0; }这段代码的核心是「每轮比较把最小的放到最前面」三次比较两两交换即可完成三个数的排序。如果题目变成四个数就继续追加if比较模式相同。三角形判断题的优先级顺序要看清楚先判断能否构成三角形任意两边之和大于第三边再依次判断等边、等腰、一般三角形顺序反了会导致等腰三角形被等边条件提前输出。百分制转五级分制推荐的写法是整除 10 映射到 switch 分支switch (int(score) / 10) { case 10: case 9: grade a; break; case 8: grade b; break; case 7: grade c; break; case 6: grade d; break; default: grade e; break; }用整除代替区间判断避免多个 if 条件的边界错误也把 0 到 59 分的情况合并进 default。这里有一个细节int(score)是强制转换先把浮点成绩截断成整数再整除。如果题目要求 85 分以上输出 very good就不能用这个方法得回到 if-else 区间判断。5. 指针、引用与 const区分「值、地址、别名」就能拿满分的模块这一章是整份答案里最难、也是最值得花时间的一章。习题1第13到第17题全部围绕指针和引用思考题和验证程序更是把这部分拓展到了「三种访问方式」「const约束」「指针的指针」的深度。笔试和面试都爱从这里出题因为它能直接检验学生有没有真正理解内存模型而不是背了几个概念。5.1 指针的三层拆解定义、赋值、间址访问指针的核心只有三句话指针变量存的是地址*p是取指针指向的变量的值a是取变量 a 的地址。第14题int i10, *pi;里p 的值是 i 的地址不是 10*p表示变量 i 的值。所以 a 选项「p 的值为 10」错误。第15题int a5, b10, c; int *p1a, *p2b;问哪条赋值语句不正确。p1 a错在把整数值赋给指针变量整型和指针类型不匹配。这类题的判断标准就一条指针变量只能接收地址值或另一个同类型指针的值不能直接接收普通整数值。*p2 b是把 b 的值赋给 p2 指向的变量也就是 b 自己赋给自己合法p2 p1是把 p1 的地址值赋给 p2合法。第16题考引用int paa, pbb;pb pa等价于b a合法。pb a错在引用一旦绑定不能重新绑定不能取引用的地址再赋值pb pa是把地址赋给引用类型不对*pb *pa错在引用不能直接用*解引用。记住一条引用名在定义时绑定一个变量之后所有对引用名的操作都直接作用于被绑定的变量。5.2 引用与指针的四条对比思考题的标准答法课后思考题第3题专门问引用和指针的区别面试也常拿这道题当口试题。答题框架按四条说清楚比较维度引用指针是否占用独立空间不占引用名是别名占独立内存空间存地址能否改变绑定/指向定义后不能重新绑定可以改变指向访问方式直接访问被绑定对象需要*间址访问定义要求必须初始化绑定可以先定义后赋值追问版本还会问「引用和指针哪个更安全」标准回答是引用更安全因为不存在空引用使用引用不需要判断是否为空指针可能悬空使用前要判空。第16题的pb pa就是典型的引用传值实际效果等同于b a。5.3 const 的四种形态指向常量的指针 vs 常量指针课后思考题第5题考察 const 的不同组合。const int *p表示指向常量的指针即不能通过 p 修改它指向的值但 p 可以指向别的变量int * const p是常量指针即 p 本身不能修改但它指向的值可以通过 p 修改const int * const p两者都不能改。常引用const T r x;则是定义了一个不能通过它修改对象的引用实参传给形参时保护数据不被意外改动。这个知识点本身不会单独出一大道题但会嵌在选择题和改错题里比如问「下列哪个定义表示不能通过指针修改所指向的值」。答题时先看const修饰的是谁*右边是 const说明指针本身不可变*左边是 const说明所指对象不可变。5.4 交换变量的经典陷阱与程序阅读题第13题问哪组语句不能交换 a 和 b 的值。d 选项ab; ba;执行后 a 和 b 都变成原来 b 的值交换失败。b 选项的加减法交换aab; ba-b; aa-b;能成功但注意如果 a 和 b 是浮点数或数值很大时可能溢出。面试里追问「加减法交换的缺点是什么」答溢出风险所以常规交换还是用临时变量。第17题是引用做交换的阅读理解ra和rb分别绑定 a 和 b三条赋值语句实际交换的是 a 和 b 的值所以 a3、b5。第1.4节的第三道程序题考了流格式控制int a 123; int ra a; int *pa a; cout setw(5) dec a setw(5) oct ra setw(5) hex *pa endl;dec、oct、hex分别把输出切换为十进制、八进制、十六进制。123 的十进制是 123八进制是 173十六进制是 7b所以输出结果是三列对齐的 123、173、7b。注意格式控制符有记忆效应设置之后会一直影响后续输出直到被新的格式控制符改变。5.5 编程验证题名访问、引用访问、间址访问课后题第2和第4题都要求写验证程序这类题在笔试里出现频率很高。完整的验证程序可以直接背下来#include iostream using namespace std; int main() { int a; cin a; a a 5; // 方式一名访问直接用变量名 int *pa a; // 指针指向 a cout *pa endl; // 方式二间址访问通过指针解引用 int ra a; // ra 是 a 的引用 cout ra endl; // 方式三引用访问相当于用别名 cout a endl; // 输出地址验证三种方式操作的是同一对象 return 0; }答题时按三行分别说明名访问是aa5这类直接操作间址访问是声明指针后用*pa取对象引用访问是声明int raa后用别名操作。最后加上输出地址a验证三种方式指向的是同一个内存单元这一分就稳了。6. 常见失分点五类必踩的坑与答题避错模板把这份答案里所有题目过一遍失分几乎都集中在五个固定模式上。这些不是概念没背熟而是C语法行为和直觉不一致导致的系统性错误。下面按「错在哪 → 为什么错 → 怎么答对」逐一拆开考前过一遍能少丢不少分。失分点一if 判断写成赋值。习题2思考题第6题输入 4 和 9输出「9等于9」因为判断语句写成了if( ab )而不是if( ab )。赋值表达式的值是被赋的值9 非零即为真所以永远走等于分支。怎么答对遇到判断相等先检查是还是如果看到选项里出现if(xy)这种写法直接判定为逻辑错误因为它合法但行为完全错误。失分点二变量定义放进了语句体。思考题第5题把int a1;写在 if 分支内编译报undeclared identifier。原因是变量定义在编译期就要分配空间if 是运行期结构分支不执行就没有这个变量。怎么答对变量定义一律放在函数开头或块的最前面if、switch、循环体内部只做赋值。失分点三switch 漏 break穿透到下一个 case。选择题第3题i 从 2 开始执行i--后变成 1没有 break 继续执行 case 3 的i变成 2。这类题必须把穿透当成默认行为来算看到 case 结束没有 break 就要继续往下走直到遇到 break 或 switch 结束。失分点四逻辑短路导致后半段不执行。i||--jk这类题只要左侧已经能确定整体为真右侧整个不执行。怎么答对先看||左侧非零直接结束看左侧为零直接结束。结束时另一侧的所有自增自减都不发生变量值保持原样。失分点五进制和常量的边界规则记混。八进制出现 8 或 9、十六进制出现 g、浮点数 e 后面跟小数、字符常量用双引号每一条都是送命题。怎么答对考前花十分钟默写一遍规则八进制 0~7、十六进制 0~9 加 a~f、float 指数必须整数、字符单引号字符串双引号。我自己备考时吃过最大的亏就是第一种失分点那时候读程序题看到if(ab)直接当成ab算连错三道题。从那以后我每次做完选择填空都会专门回头扫一遍所有判断条件确认没有把赋值当比较。这份答案的价值不在于背答案而是把每一个错误都当成一个考点标本——你把错误的原因说清楚了考场上就不会再犯。希望帮到你。本文还有配套的精品资源点击获取