C++零基础入门:从变量、指针到分支循环的习题式学习指南
简介广州大学计算机C课程的习题答案合集面向C初学者、在校本科生及考研复习者。内容覆盖变量与数据类型、运算符与表达式、控制结构、函数、数组、指针等核心章节以选择题与解答形式梳理常见易错点如标识符合法性、八进制和十六进制常量写法、运算符优先级、逻辑表达式求值以及指针与引用交换变量等问题同时配有将数学表达式改写为C算术表达式、用逻辑表达式表示条件的习题解答方便对照自查。资源共1个doc文件压缩包约1.55MB轻量易用下载后可直接按章节查阅。已有442人学习使用尤其适合课后刷题巩固与考前快速复习可帮助读者进一步检查对C语法细节的把握减少编译和运行阶段的常见错误。1. C零基础入门最容易被卡死的瞬间不是代码难是该从哪句开始读很多零基础同学翻开C教材第一感受是“全是英文是不是得先背单词”。其实C没你想的那么玄——它就是让计算机照做的指令比发朋友圈的输入格式更严格而已。这份资料是一套“带答案的C入门练习册”用选择、改错、读程序、写程序四类题目把变量、运算符、分支循环、指针这些第一学期最常考的知识点挨个过一遍。它不把原理讲成天书只负责让你确认“我想对了没”。刚开C课、连编译器都没装过的新手完全可以把它当同伴。别急着背答案先自己写再对照——这是它最好用的方式。2. 先搞懂一个关键问题C到底怎么把代码变成结果的在动手做题之前有三个问题值得先想明白C是什么、程序怎么跑起来、这份答案式资料到底能帮你什么。这一章不写代码只帮你把脑子里的模糊印象擦干净。2.1 为什么第一门编程课几乎都选C你是在学“指挥计算机”的思维方式为什么零基础入门往往从C开始而不是那些“更好上手”的语言因为C愿意把底层的东西摊开给你看。你写int a 5它就真的在内存里找一块地方放进一个整数5你写int *p a它就把这块地方的地址交到你手里。这种“看得见内存”的感觉是很多更省事的语言不会主动展示给你的。新手学C与其说是背语法不如说是在建立一种“我说一句机器做一步”的思维方式。C也没有传说中那么不近人情。变量名可以起成age、score这种一眼能看懂的名字每条语句用一个分号告诉编译器“这句话到此结束”。习题1第3题专门考了这一点C程序中的简单语句必须以分号结束。看起来是送分题但新手写完程序被编译器打回来十有八九就是漏了分号。这些细节单看都很小连在一起就是你能否顺利写完第一个程序的差距。我第一次学C时的感受是它像一套乐高说明书每个零件都有固定的插法不按规则拼机器就不理你。这份习题集里的选择题大部分就是在帮你确认“零件这么插对不对”。你不需要把每个选项背下来但要把“为什么对、为什么错”想明白。这样到了考试或者自己写程序的时候你才能真正用出来而不是靠蒙。2.2 从源代码到可执行程序编译器、编译错误和运行错误要分清你写的.cpp文件是给人看的计算机只认机器码。把源代码翻译成可执行程序的过程叫作编译。习题1第2题问“源程序要变为目标程序必须要经过什么”答案就是编译。你用任意一款常见C开发环境写完代码点“运行”按钮时编译器会在后台做这样几件事检查单词和符号拼得对不对、括号配没配齐、变量类型用没用对全部通过后才生成能运行的程序。新手经常把编译错误和运行错误混为一谈看到报错就慌。其实只要分清两类第一类是编译阶段报的错通常是语法写错了比如少个分号、多个花括号编译器会明确告诉你“第几行出了什么问题”按提示改就行第二类是运行阶段的错程序能启动但执行到某一步出了状况比如习题1第5题说的“溢出”——数字太大超出了变量能装的范围。做题时养成先看报错类别的习惯后面自己调程序能少走很多弯路。这里有一个很常见的“黑匣子”误区新手总以为代码过了编译就等于程序对了。其实编译通过只说明语法没问题逻辑对不对还得靠运行结果判断。习题2.3思考题6就是典型案例程序能编译但因为把写成了运行结果完全错误。所以跑通一次程序之后一定要盯着输出结果追问一句它真的符合我的预期吗2.3 这套带答案的习题怎么用先做题、再对答案、把错题重写一遍这套资料里的题目大致分四类选择题帮你确认概念、读程序题练你“在脑子里运行代码”、思考题把易混点掰开讲、编程题让你真正动手。新手最容易犯的错是拿到带答案的资料就直接看解答看完觉得“这不难嘛”合上书自己一写就卡住。这种“眼睛会了手不会”的落差几乎每个人都会经历一次。我建议你按这个顺序用第一步做题前把书合上只拿题目当任务。编程题想不出完整代码也至少要写出思路比如“先取百位、再取十位、最后取个位”。第二步选择题不要只看正确选项把每个错误选项为什么错也标出来。比如习题1第7题问合法标识符正确选项是_abc那你就要知道new是关键字、π是特殊字符、双引号括起来的“age”是字符串常量都不能当标识符。第三步对答案时重点看自己卡在哪一步而不是只看结果对不对。这样才能让错误变成经验。读程序题是性价比最高的训练。每一道都先别运行在纸上写出你认为的输出结果再拿上机结果对照。最开始一定会写错错了正好——你从错误里学到的比看十遍答案都多。这套方式坚持下来你对变量、运算符、分支、循环这几个基础主题的理解会比单纯看解答扎实得多。另外别担心学C会和“做实际项目”脱节。很多你以后会接触的技术比如操作系统、嵌入式开发、游戏引擎的底层都和C关系密切。第一学期把它学扎实后面学其他语言会轻松很多。这份习题覆盖的变量、运算符、分支循环、指针和引用恰恰就是C第一学期最重要的一层地基。3. 跑通你的第一个C程序把三位整数倒过来输出概念讲再多不如亲手跑通一个程序。这一章我们直接做编程题里最简单的那道输入一个三位整数程序把它反向输出。全程跟着做做完你会对“写代码到底是怎么回事”有真实的感觉。3.1 动手前先准备环境装一个能编译运行的C工具跑程序之前你得先有一个能“翻译并执行”C代码的环境。这里我不推荐具体某一款软件因为每台电脑情况不一样你只要记住一个原则装好任意一款带C编译器的开发环境能让你新建文件、写代码、点一下运行、看到结果就行。安装完成后新建一个源代码文件把下面的代码完整粘贴进去先别管每行什么意思让程序跑起来再说。第一次运行如果报错不要慌。把报错信息读一遍多半是以下几类代码没保存、文件名后缀不对、或者粘贴时漏掉了某个符号。环境准备这一步很多新手会卡在“装了好几个软件还是不行”上我的建议是一条路走到黑选定一个环境把它的新建、保存、运行三个按钮找齐就够了。3.2 每一行代码在做什么从输入到取位再到输出我们要完成的题目是从键盘输入一个三位整数比如123程序立刻输出它的反向排列321。完整代码如下#include iostream using namespace std; int main() { int x, i, j, k; cout please input x:; cin x; i x / 100; // 取百位123 / 100 1 j x / 10 % 10; // 取十位123 / 10 1212 % 10 2 k x % 10; // 取个位123 % 10 3 cout k j i endl; return 0; }逐行看。第一行#include 是让程序能用cin读入、cout输出这一行是固定“头文件”初学者先照抄即可。第二行using namespace std;意思是“我接下来要用的标准功能都在std这个命名空间里”也是一句固定开场白。int x, i, j, k;声明了4个整数变量x保存你输入的数i、j、k分别保存百位、十位、个位。cin x;会等待你在键盘上输入按回车后把数字放进x。接着三行是出题人精心设计过的取位写法x / 100是整数除法123除以100等于1小数部分直接丢掉x / 10 % 10先整除得到12再对10取余得到2x % 10直接取个位得到3。最后cout k j i把三个数字按“个位、十位、百位”的顺序打印于是得到321。运行结果演示屏幕显示please input x:你输入123回车程序输出321。如果你输入987输出789。这里的运算规则很关键整数之间做除法时C会丢弃小数部分而不是四舍五入。比如7 / 2的结果是3不是3.5。想保留小数需要把操作数写成浮点类型比如double。习题1第4题就考了类似的类型混用问题。3.3 把这个例子改着玩从三位数到回文数判断程序跑通之后别急着做下一题。试着改一改改完你会更理解这三条取位语句。第一个改动输入12会怎样12 / 100等于0百位取出来是012 / 10 % 10是112 % 10是2。输出情况会变成“021”。这说明程序只能正确处理三位数。想要程序更健壮可以先判断输入是否在100到999之间再决定是否执行取位运算。这个思考过程比背下代码更重要。第二个改动把“反向输出”改成“判断回文数”。回文数是指正着读和倒着读一样的数比如121。你只需要在取位之后加一个判断if (i k) { cout 是回文数 endl; } else { cout 不是回文数 endl; }注意这里是比较相等用两个等号写成一个等号就变成赋值了这是新手最容易翻车的地方。第三个改动把三位数改成四位数。你需要再增加一个变量用 x / 1000 取千位原来的百位变成 x / 100 % 10十位和个位不变。改完对照运行结果检查一遍你会对“整除取位”这个套路形成肌肉记忆。下次遇到“把一个整数拆成各个数位”的题你就能条件反射地写出取模和整除的组合了。4. 新手第一道真正的坎变量、指针和引用到底是什么关系选择题做到指针和引用那几题很多人会开始怀疑人生p、*p、p、int ra怎么全是符号这一章我用三个类比把这组概念彻底讲清楚。4.1 变量是贴了标签的盒子先搞懂“名访问”把内存想象成一排排储物柜每个格子都能放东西。int a 5;做的事是找到一个能放整数的格子把5放进去然后在格子外面贴上一张写着a的标签。之后你写a就等于说“打开贴有a标签的那个格子”。这在C里叫“名访问”也就是通过变量名直接读写格子里的值。习题1.5思考题2里说的“普通数据类型变量通过名访问即直接访问”就是这个意思。给变量赋值、读取输出都是打开盒子看内容。而“类型”决定了这个格子里能放什么、能做什么运算。习题1第4题里int a0是整数格子double x5.16是浮点格子a % x会对浮点数取余这种操作C不允许所以编译直接报错。变量的格子还有一个特点同一时刻只能装一个值。你往里面放新值旧值就被覆盖。交换两个变量的值必须借助第三个格子临时中转这就是习题1第13题的考点。选项d“ab; ba;”为什么不能交换因为第一句执行后a已经变成b的值第二句再把a赋给b等于把同一个值来回倒原来a的值早丢了。4.2 指针是写着地址的纸条*号和号别再用混现在问题来了如果有一个格子它里面放的不是数字而是“另一个格子的编号”——这个格子就是指针变量。int a 5; int *p a;可以这样理解a是“取a这个格子的编号”也就是地址int *p是定义一张写着地址的纸条把a填进纸条p里面存的就是a的地址。那么*p是什么它是“顺着纸条找到的那个格子里的内容”。习题1第14题专门考这个int i 10, *p i; 正确的说法应该是“p的值是变量i的地址”、“*p表示变量i的值”、“p指向整型变量i”而“p的值为10”是错误的——p的值是地址不是10。习题15也一样int *p1 a, *p2 b; 选项b“p1 a”为什么错因为p1只能接受地址a是一个整数把整数塞给指针变量类型对不上。新手最容易把和弄混这里有个记忆方法声明语句里的是“我要一张纸条”是“我要取格子的编号”使用语句里的是“沿着纸条找格子”是“告诉我这个格子编号是多少”。习题1.5第7题就是一道专门辨析和含义的题做完那道题你会彻底分清楚。4.3 引用是同一个盒子的第二个标签它和指针有三个重要区别引用比指针更好理解int a 5; int ra a; 意思是给同一个格子再贴一张写着ra的标签。你不是新建了一个格子只是给旧格子起了个新名字。之后你写ra等于写a打开的都是同一个格子。习题1第16题里int paa, pbb; 用pa、pb去读写a、b所以“pb pa”是正确的“*pb pa”反而是错的——因为引用不需要用。引用和指针有三个区别是考试也爱考的第一引用名不占内存空间它只是个别名指针变量自己要占一个格子来存地址。第二引用在定义时就必须绑定某个变量而且之后不能改绑指针变量可以随时换指向今天指向a明天指向b。第三用引用访问变量写法和直接用变量名一模一样用指针访问必须写*。习题1第17题就是用引用交换a和b的值整个过程不需要指针也不用临时变量去操作地址直接用引用就能完成ra、rb相当于a、b的别名三句赋值就完成交换。做完这道题再看习题1.5思考题3的验证程序把输出结果逐行分析一遍指针和引用就算真正入门了。5. 常见问题排查新手最容易踩的五个C坑这一章全部来自真实出题人最爱布置的“陷阱题”。每一条我都按“现象 → 原因 → 解决”来讲你踩过也好、没踩过也好提前看一遍能省下不少调试时间。5.1 把比较写成赋值if(ab) 为什么会输出“9等于9”现象输入a4、b9程序却显示“9等于9”。原因if(ab)里用的是赋值号而不是比较符。ab会把b的值赋给a整个赋值表达式的值就是b的值也就是9。9非0被当成逻辑真于是走了第一个分支。习题2.3思考题6就是这个问题的完整版本。解决比较相等一律用。如果担心自己手滑可以把常量写在左边写if(9a)。这样万一漏写一个等号编译器会直接报错因为“把值赋给常量”不合语法。5.2 变量定义进花括号一出作用域就变“未定义”现象代码编译时报错提示某个变量“undeclared identifier”未定义的标识符。原因变量定义写在if或else的执行体里它的作用域只限制在那对花括号内。分支结束变量就“消失”了后面再使用它编译器找不到这个名字。习题2.3思考题5就是典型。解决需要在程序多处使用的变量定义在函数开头、所有分支之外。分支里只写赋值语句不写定义语句。这个习惯越早养成越好等到写复杂程序时你会感谢自己没把变量定义撒得满函数都是。5.3 switch少了breakcase会一路往下“穿透”现象switch(i)里i2进入case 2后执行了i--结果紧接着把case 3里的i也执行了最后i的值和自己预想的不一样。习题2.1第3题就是这种陷阱。原因case只是入口标记不是“执行完就自动退出”。不写break执行流会继续往下穿过后面的case直到遇到break或switch结束。解决每个case分支的末尾都要检查有没有break。如果有多个case要共享同一段逻辑也可以故意写成连续case例如习题2.4第4题把score/10得到的10、9都归为a这是“穿透”的合法用法。但要写清楚注释否则别人看代码会误以为你忘写了break。5.4 整数除法丢小数想算平均值却得到0现象int a1; int b2; 计算a/b的结果是0而不是0.5。原因两边都是整数时C做的是整数除法结果直接截掉小数部分不四舍五入。习题1.2里把数学表达式转成C表达式时所有除法都要小心这一点。解决想让结果保留小数至少让其中一个操作数是浮点类型例如1.0 * a / b或者把结果变量声明成double。判断能不能整除用取模运算a % b 0而不是看除法结果。5.5 continue和break用反循环结果和预想完全不同现象while循环里写了continue本以为会“跳过这次继续循环”结果循环提前结束了或者多跳了好几轮输出结果和自己手推的对不上。习题2.2第3题就是continue的典型i写在条件判断里导致输出的数不是1到10而是4、7、10。原因continue是“跳过本轮剩下的语句立刻回到循环条件判断”不是“跳到循环末尾”那么简单。当continue写在循环体前部并且循环变量的更新发生在continue之后的语句里那么循环变量可能来不及更新甚至造成死循环。解决把循环变量的更新放在循环体最前面或者改用for循环把i写在for的第三个表达式里。做题时先在纸上手推一遍循环流程再上机验证这是判断循环题对不对的最快方法。6. 下一步往哪走把这份习题吃透之后该学什么6.1 把已经会的题目改造成新题反向输出三位数怎么变成任意位学编程最有效的进阶方式不是做更多新题而是把做过的题“升级”。以第3章的反向输出为例改成“输入任意正整数反向输出每一位”你只需要在循环里反复取模和整除while (x 0) { cout x % 10; // 输出当前最后一位 x x / 10; // 去掉最后一位 }这段代码里x % 10永远取当前个位x / 10则把它丢掉。循环不断重复这两个动作直到x变成0。你会发现用循环实现之后三位数、四位数、任意位数都不再需要单独写取百位、取千位的公式了。这就是从“会一题”到“会一类”的跳跃。6.2 接下来按这个顺序学函数、数组、类与对象、文件这套习题覆盖的是C第一学期的前半程。把它吃透之后建议按这个顺序继续先学函数把重复代码拆成可复用的小积木再学数组一次性处理一批相同类型的数据然后学类与对象体会C里最核心的“把数据和操作打包在一起”的思想最后学文件读写让程序能把结果保存下来。每一步都可以像前面那样找几道带解答的题先做再对答案。另外提醒一句读程序题不要只读不想。每到一段代码都先问自己三个问题——它声明了什么类型每个运算符的优先级是什么循环到底执行几次这三个问题想清楚你的读代码能力会明显上一个大台阶。如果你手边正好缺一套能对照的练习题在各个课程资料平台搜“计算机C习题答案”就能找到与本文同源的资料按第2章教的顺序用起来即可。学到这里你已经不是那个看见C就发怵的新手了。说实话当年我也被那一堆选择题和指针题折磨过后来养成了一个习惯每学一个新知识点就逼自己在上机前先手写一遍输出结果或思路再运行验证。从那以后我每次写完程序都强制走一遍“先手推、再运行、最后对答案”的流程翻车的次数直线下降。希望这个方法也能帮到你。本文还有配套的精品资源点击获取