指导在C ++基础方面苦苦挣扎的学生[关闭]


26

我正在辅导一些在学习其第一门编程语言的基础知识方面遇到重大困难的学生:C ++。我认识许多优秀而聪明的学生,他们的第一门CS课程都失败或辍学。我正在辅导的每个人都对他或她在课堂上的经历有类似的描述:讲师的步伐太快,讲课中没有任何意义,等等。在参加CS课程之前,这些挣扎中的大多数学生对计算机的兴趣不大,除了文字处理程序,Web浏览器或其他娱乐方式。电脑是可以正常工作的黑匣子,为什么要搞乱它呢?

我最好的猜测是,他们在将计算机科学的抽象与熟悉的概念联系起来时遇到了麻烦。也就是说,这些学生可能知道如何学习数学,生物学或物理学,但是在编程时这些技术不起作用。

有人有任何建议吗?我所帮助的学生不应因此而失败。显然,导师没有考虑这些学生的学习风格。就是说,导师没有让他的学生失败。


2
评论员:如果有答案,请将其保留为答案:请勿将其保留为注释。如果您的答案已经添加,请投票。如果您想与其他人讨论这个问题的主题,请使用chat

1
别?根据我的经验,有足够的人编程和不应该...

Answers:


42

实际上,每个初学者都需要克服一些问题。学生必须先学会阅读代码,然后才能学习编写代码。

  • 祈使语言的顺序性质。人们很难理解功能是按顺序执行的,一次只能像配方一样执行。解决此问题的一种方法是通过调试器显示一些代码。
  • =C风格语言的赋值运算符()极具误导性。您需要非常仔细地解释,这a = 5意味着“将5分配给变量a而不是 ” a等于5”。
  • 对于初学者而言,将功能描述为其他功能可以跳转到的结构化代码块是安全的。同样,初学者很难理解在C ++中,函数参数是按顺序而不是名称来标识的。
  • 大多数命令式编程语言具有一些声明性组件和一些过程性组件,C ++也不例外。确保学生了解代码的某些部分描述了程序的结构,而其他部分(功能)则描述了程序应执行的操作。
  • 用调试器单步执行程序是非常重要且经常被忽略的教学工具
  • 表达式具有类型3+3是一个整数,3.5 + 3是一个双精度数,"3" + "3"(在C#中)是一个字符串,x == 5 * 3 + 25是一个布尔值(或C ++中的整数)。花很多时间来确保学生完全满意这个概念。
  • 可变范围使初学者一直感到困惑。向学生解释范围是如何工作的,并确保他们知道x一个范围中的x定义不同于另一个范围中的定义。
  • 每个变量在其生命周期中至少被引用3次:声明,赋值(通常与声明在同一行完成),消耗。如果缺少任何这些,则说明存在某个概念错误。出于同样的原因,如果您要分析一个正在运行的程序,则始终可以在代码中查找这三件事,以弄清变量的用途。
  • for除非给出足够的使用while循环的迭代示例,否则不应教授循环。速记语法令人困惑,它使学生想知道为什么他们不能只使用while循环。使用备忘单以for循环形式描述while循环可能会有所帮助。
  • 数组和指针很容易教,但学习却是一场噩梦。换句话说,在点击之前,练习很重要。
  • 代码是文本,而编译后的程序实际上是文件的想法对于某些初学者而言是难以捉摸的。确保在外壳中向他们显示.cpp,.h和二进制文件。

C ++的OOP组件完全是一个完全不同的野兽,我有点希望教官不要到那里-因为OOP最好使用从头开始设计为OOP的语言来教授。以我的经验,通过C ++进行OOP的教学从未如此顺利。


2
“人们难以理解功能是按顺序执行的”?我认为几乎没有人遇到这个问题(也许,除了那些在开始程序之前已经学习过某种功能语言的人)。但是我同意你所说的其他一切。
大约

2
+1与调试器一起使用,因此他们可以了解程序本身与程序执行之间的差异。
Mike Dunlavey

4
@leftaroundabout您会感到惊讶。数学主要是说明性的,因此命令式语言可以甩掉所有学习过代数的人。
宫坂丽

2
这个答案似乎只是“散布概念”。这些概念无疑是正确的,而且肯定很重要,但是以这种方式进行授课有点像试图教别人如何通过破坏道路规则来开车。
riwalk

@ Stargazer712每个人都必须先学习道路规则,然后才能进行路试。我可以提出诸如“实践是关键”,“富有创造力”或“逻辑思考”之类的蓬松大笔想法,但对于任何一位老师以及大多数学生来说,这些东西显然都是显而易见的。人们还可以教授诸如离散数学或语言理论之类的抽象知识,作为编程的先驱,但只有当机制如此复杂以至于不能仅凭直觉就能解决问题时,这一点才变得重要。迟早人们不得不停止禅宗,开始讲授内容
宫阪丽

19

您以前学过编程吗?

我教了CS和非CS专业的程序设计四年。第一个学期,我的经验和您一样,直到我学到了一些东西。

在我看来,空虚的简单对初学者来说根本不简单。

无论使用哪种语言,您都需要放置一个思维框架-如此明显的事情甚至都没有意识到您知道它们,例如:

  • 电脑一次只能做一件事。(任何说过具有并行性和流水线功能的人,请走开。学生们知道某些内容后再回来。)计算机只能做少量不同的事情,在上一个步骤完成之前,他们不能开始执行一个步骤。我之所以这么说,是因为计算机似乎可以做很多事情,并且是瞬间完成的,所以对于初学者来说,它们看起来像是一次完成所有事情,也可以读懂你的思想。

  • 变量很重要。必须理解,变量的名称及其在运行时的内容是完全不同的两件事。初学者为此感到挣扎。如果我说“写一个程序输入您的名字,然后向您问好”,他们需要弄清楚他们需要一个变量来保存其名字,并且他们必须为该变量想出一个名字,然后他们才会被吸引。以自己命名,并想知​​道“输入”是什么意思。

  • 在编写/编辑程序的时间与执行时间之间存在巨大差异。在第一次练习中,需要经常提醒他们这一点。

我使用的语言是BASIC,因为它对于初学者来说非常简单。在其他语言建立了一套基本的编程能力之后,继续学习其他语言并不难。

我们通常会在板上编写一个程序,然后“玩电脑”。也就是说,在当前语句旁边放置一个X,手动执行该操作,然后将X移动到下一个语句。变量是板上的矩形,我们将在其中写入当前内容。发生分配后,我们将其删除并放入新值。

我开发的一个技巧是模拟十进制计算机,该计算机具有1000个存储位置,每个位置都可以容纳4位数字。有一小组“操作码”,例如加载累加器,添加,存储,跳转等。我会让他们用这种“机器语言”编写一些小程序,然后单步执行即可。然后,诸如变量,跳转等概念更容易解释。

希望能有所帮助。


我喜欢那种模拟计算机的想法。您是否有正式语言,或者只是使用伪代码/普通英语讨论这些想法?
宫阪丽

@Rei:我用BASIC编写了一个名为Simple的模拟器。都是键盘界面。用户可以在“内存”中输入值;然后他们可以单步执行,并在需要时检查每个点的累加器和内存。我认为这真的很重要,因为这促使他们去做,而不仅仅是谈论它。
Mike Dunlavey

嗯好的 谢谢,我应该尝试类似的方法。
宫阪丽

我认为这应该是第一答案。
riwalk

12

在我看来,C ++作为第一语言是一种矫kill过正的做法。

如果我是您,并且有足够的时间在手,那么我将介绍使用Python(或类似工具)进行编程和CS的概念。

当概念明确时,即当他们熟悉基本数据结构,间接寻址,基本算法等时,我将慢慢介绍C ++,它们将很快能够与他们已经学过的东西联系起来。


2
我同意,但是教授通常无权选择教哪种语言,更不用说助教了。
宫阪丽

4
我不同意Python。我上了C ++的第一门CS 101课,然后转到了一所用Python教CS 101的学校。当我们都参加相同的CS 201课时,Python学生甚至对基础知识都感到困惑……但是所有C ++学生都表现出色。
OghmaOsiris

@OghmaOsiris,坦率地说,我对Python不够了解,但是您所看到的可能仅仅是自我选择偏见的表现。毕竟,C ++对于某些学生(特别是对于编程最缺乏经验的学生)来说是可怕的。
Stephan Branczyk 2011年

@Oghma 201班是什么?如果是低级的东西,它可能应该是它自己的分支,并以C为前提。
宫坂丽

1
@OghmaOsiris:嗯,我不得不不同意,而不是不同意,在我大学学改用python时分享了不同的经验,因为据我所知,第一语言已被证明非常有用(首先是Java no C ++)。我不认为个人经验可以证明一种经验比另一种更好,那就是永无止境的火焰战争。我可能会争辩说,尽管Python可能会成为一种很好的编程语言,因为它不会妨碍您的发展,实际上它比大多数编程语言要好得多,能吸引很多学生
。...– Trufa

4

这是我的建议:

  1. 向他们提供解决所需的所有详细信息
  2. 鼓励他们尝试了解细节
  3. 确保他们在需要时以紧凑的形式存储了详细信息

基本上,我建议您创建一张具有所有必需详细信息的A4纸。某种参考手册,其中包含所有详细信息。有些书也可以提供帮助,例如“ C编程语言”-书非常有用,因为它以紧凑的形式提供了所有必需的细节。信息压缩是创建包含所有细节的a4纸的必要部分。


3

编程与学生遇到的其他常见领域有很大不同。许多上大学之前的学生仅通过在课堂上集中注意力,并完成了一些家庭作业,就可以轻松解决问题和答案,这是成功的。它更多地是关于记忆过程,然后创建过程。这也是许多学生第一次反复得到错误的答案(语法错误,逻辑错误,段错误等)。在编写程序时,这会消耗学生的动力。

要真正了解编程的发展,他们需要练习很多。一种经常被忽略的技术是让他们以母语为第一的方式写出伪代码。要求他们继续扩大它,直到他们对问题有一个相当详细的解决方案为止。然后将其转换为真实代码即可。


3

在上大学时,我曾经是编程课程入门以及其他课程的导师。您描述的问题并不少见。根据您的特定角色,您可能会采用不同的方法。

首先,如果这是一个影响到班上大部分学生的普遍问题,如果您可以这样做,我将向教授授课的教授提供有关学生未能掌握哪些概念的具体反馈,以便他或他她可能会在学期中再次提出对该材料的其他评论,或者为将来的学期改进课程。

如果您在实验时间之外还教课程的一个讨论部分,那将是一个很好的时机,详细讲解那些令人困惑的内容,并使其变得更加具体,并确保所有基本知识都得到了理解。

如果您与这些学生一起工作的唯一时间是您在辅导实验室期间,那么您仍然可以利用这段时间来一次或一次地教学生一些他们需要的概念性组成部分,以便他们理解并完成功课。

他们可能在课堂上感到迷路,甚至不知道在哪里停下来问问题。如果是这种情况,请与他们一起回到基础知识。当他们最后一次了解发生了什么时,他们在课程中的什么位置?如果他们不确定或“从不”理解,则可能必须重新回到开始解释“ hello world”的方向,教他们诸如变量是什么,计算机如何获取其“指令”列表,并尝试进行操作。按顺序执行它们,但是计算机不像我们那么“聪明”,因此您必须非常直率,说出完全适合计算机理解的内容,等等。

这实际上是我在非专业编程课程中经常看到的奋斗和挫折点。学生写一些代码。似乎“大约”是正确的,但是随后他们去编译它,并给出了一个错误,这是一个非常神秘的错误。他们不知道这是怎么回事。盯着他们的代码几个小时。然后终于弄清楚这似乎是微不足道的,例如缺少分号或括号在错误的位置。然后他们再次编译它,仍然有一个错误,这是另外一回事。他们第二次使用变量名时的拼写方式有所不同。等等。因此,他们向朋友,导师或某人寻求帮助,然后他们就可以回答:“哦,只要在此添加,它就可以工作。” 因此他们的经验是编程有点“神秘”

这是一个辅导老师的领域,您在这里有很大的帮助空间。根据他们的沮丧程度,我可能有不同的方法来帮助他们弄清为什么他们的代码无法正常工作。如果他们有所了解,我可能会给他们一些提示,并尝试帮助他们自己解决问题。但是,如果他们只是在准备放弃沮丧的尽头,我经常会给他们几个免费赠品的答案,然后至少问他们一些问题,例如“您了解为什么这种改变会固定您的程序吗? ?

对于某些学生,尤其是非专业的学生,​​他们可能没有系统地关注成为一名优秀程序员或享受编程所必需的细节。您可以通过策略帮助他们,以帮助他们关注细节,并采取有条理的方法来解决问题,即使这对他们来说也是一个挑战。

但是对于学生“适当地”缩进代码却保持保留态度-经常,刚开始的程序员会在嵌套和范围方面产生问题,因为他们没有匹配的花括号之类的东西,因为他们不注意嵌套在什么下面的内容。给他们一张“检查程序何时无法编译的东西”的清单,例如正确缩进所有代码并确保花括号匹配,确保所有行都以分号结尾,尤其是第一个错误显示所在的行号附近等等

教他们尽早编译并经常编译。编写最小的框架代码(例如,hello world),进行编译/测试。添加几行,然后再次编译。如果您只查看很小的更改而不是很大的更改,发现错误就容易得多。

帮助他们学习如何将问题分解为较小的可解决问题。这是我们作为专业程序员解决不知道如何解决的更棘手问题的同一件事。您会不断将其分解成碎片,直到找到您知道如何解决的问题,或者可以进行一些研究来学习如何解决。“要采取可行的解决方案,您需要采取什么步骤?” 好吧,首先,您需要一些框架代码(Hello World)。你知道怎么做吗?是的,太好了,所以当我们完成交谈后,您可以开始这样做!然后它需要读取一个文件作为输入。您还记得在第4章中读到的内容吗?并不是的?您好,当您运行世界后,为什么不去看一下,看看您可以将其工作多近,然后再给我打电话,当您遇到困难时,它将为您提供更多帮助。头几次,您可能只需要为他们列出解决问题所需步骤的编号列表,以便他们可以从示例中学习如何分解问题。

如果他们在课堂上获得了全部但不是全部的材料,请鼓励他们在课堂上提问,因为十分之九的学生不是唯一不理解的学生,而教授可能只是掩饰了一些重要的东西。

如果他们花“几个小时”盯着一个错误却没有弄清楚它,那是浪费时间,他们没有从中学到很多。错误通常是洞察力问题,而要想出正确的洞察力来解决它的问题,而对于这些类型的问题,他们可能并不了解。建议遇到卡住时采取的其他一般方法:向班上的另一个朋友寻求帮助(必要时认识一些同学),提前开始作业,以便他们有时间停下来,然后再来在开放时间或在教授的上班时间问问题。如果他们习惯于记忆,这对记忆对象很有效,那么当他们 面对编程更多的是解决问题而不是记忆。向他们展示如何从他们的教科书,stackoverflow等中查找语法示例。鼓励他们在私人课程问题论坛上发布问题(如果有的话)。

教他们如何缩小代码停止工作的位置。注释掉所有内容,直到您返回正在运行的内容,然后慢慢将其添加回去,直到再次遇到该段错误为止。

如果这些想法很多,很多想法都可以变成讲义。策略通常是教授掩饰的部分-他们将时间花在语法,如何编写循环,数组,I / O等语义上。但是,没有足够的时间花在“尝试时该怎么办”上运行我的代码,它只是无法编译或崩溃?”

当涉及到概念性事物时,尤其是基础知识,例如“什么是变量”或“什么是循环”?不了解这将阻止他们跟上课程的其余部分。在基于讲座的课程中,教授可能没有时间回答每个问题或帮助每个学生摆脱灯泡的困扰。这就是为什么导师对学习编程如此重要的部分原因。他们可能需要带有其他类比的个性化指导,以使特定主题具体化。

由于您使用C ++进行教学,因此我可以想象课堂作为一个抽象的话题出现,有些学生难以“获取”。通常,用与某个随机现实世界对象(例如“ ATM机”)相对应的示例来教示类的抽象,并对现实世界对象进行类比。您可能有一些变量来跟踪里面有多少钱,有一些方法,这些方法就像告诉atm机如何对特定条件做出反应的规则,等等。有时一个类比就是“粘”给特定人的类比,而其他学生则更好地掌握了另一种。

尽可能为它们绘制图片。就像时序图一样,随着时间的流逝,可以帮助他们了解正在编写的代码的功能。用户单击此按钮。然后,程序应通过执行x,y和z进行响应。在邮局绘制一个像一堆邮政信箱的数组,每个邮政信箱只能容纳一个数字,并在框的前面画一些指针,如指向“地址”的箭头。等等。


2

在所有编程语言的绝佳选择中,该学院使用C ++作为非CS专业的入门CS课??在才华横溢的讲师手中,这可能遥不可及-但是为什么要这么难呢?

当我在大学CS入门课程中学习“ Pascal”时,我们花了前3周的时间与“ Karel the robot ”一起工作。这是一个非常简单的类似于沙盒徽标的编程环境,在使用Pascal进行编程之前,已对所有基本概念(包括递归)进行了全面研究。在“ Karel the robot”中,您可以使用一小组简单的命令在2D空间中控制机器人。这为学生提供了一个有用的具体基础,他们可以借鉴接下来发生的事情。

也许现在有更多现代的教学编程语言来填补“机器人的卡雷尔”的角色?但是,现在对您的学生来说可能太迟了。


我们有一个类似的程序叫做Alice。
OghmaOsiris


@OghmaOsiris爱丽丝链接已断开。末尾的“”已添加到网址中
。– Zoot

是的,没有它,结尾的')'被切断。
OghmaOsiris 2011年


2

除了说些什么,我还认为,作为初学者,他们只需要刮擦表面,因此可以相应地调整您的课程设置,以避免复杂的事情。

0给他们一个简单的问题(例如,评估一个表达式)。

1-给他们时间解决问题。

2-给他们答案。

3行逐行通过答案

4-询问他们将您的答案与他们的举报进行比较

5,请他们从这个问题中吸取教训

6-对SAME问题再增加一步,例如需要IF语句的条件

7-在几个问题上重复上述任务。届时,他们将已经掌握了该语言的基础知识以及如何使用环境。这将为接下来的事情做好准备。

也,

-有一个简单的奖励问题,让他们每2堂课左右在家尝试

与每个学生互动,看看阻止他继续前进的意义是什么

-提供简单的参考资料,忘记复杂的主题和复杂的书籍

-经常获得他们的反馈并使用

-上课前请他们为下一个主题做准备


2

当我学习CS 101时,对我有帮助的是在甚至没有查看代码之前就学习了逻辑。我们经历了真值表和介词演算,因此我们将开始思考“这是对还是错”,而不是“这等于这个或那个”。

那就是当一切都为我点击的时候。一旦我弄清楚编程基本上只是在其核心上操作true / false值,那么一切都变得相对简单了。

这使得它变得无关紧要,无论我使用哪种语言,逻辑无处不在。语法可能会令人困惑,但是我可以说“ Ok,在Obj CI中将消息发送到这样的类,而在C ++中,消息以这种方式发送。但是算法完全没有改变。” 等等


2

某处有ACM或IEEE文章,其中详细介绍了为什么初学者(甚至是从该领域开始的CS毕业生)需要坐在高级程序员的后面,看着他们编码问题。

专业人士经常结对解决难题。人们经常被告知不要这样做。配对的优点(在键盘上轮流使用):1.立即告知学生他在做什么错。即时反馈。2.当学习者看着老师时,学习者将学习老师从未想到的事情。

与其让学生养成不良习惯,不如将他们扼杀在萌芽状态。(我会在这里将#1和#2翻转,让学生观看讲师/ TA FIRST

用一组静态的PowerPoint幻灯片教CS不太适合编写程序的时间过程。(当然,可以使用一些技巧来逐步增加功能,但是它们通常很尴尬。)

学习者需要知道从哪里开始写作,从哪里停止和编译。我们的大脑大部分是从左到右从上到下阅读的,但是一个程序就像一个整体,将您自己的冒险书塞进一个页面!

初学者通常会复制整个程序,然后进行编译。即使是专业人士,也可能会首先遇到这种情况,在意识到他们应该将所有功能都留空之后,再编译程序,然后迭代地添加到工作框架中。

另外,还有一个荒谬的想法,那就是应该在没有计算机而只有铅笔和纸的情况下教授CS。我想知道有多少受雇的编程专业人员真的认为这是最好的方法,或者这仅仅是CS老师因为他们自己不喜欢使用计算机而做的事情吗?从图片中删除计算机的任何尝试都是卑鄙的。这样做会使编程变得不那么有趣,也缺乏交互性。将数据输入打孔卡并耐心等待的日子已经漫长了。当今的专业开发人员是即时满足的粉丝。幸运的是,大多数学生也是。

显然,在开发过程之前和期间,用铅笔和纸画漂亮的设计图对于专业和初学者来说都是一个强大的工具。像“键盘操作”之类的时间也应该花在配对上!也许在这里让学生在看老师之前尝试第一轮可能是有意义的,尽管即使这样做,也可能值得看一下老师的真实思维过程。

最后,专业开发人员使用的热键和编辑技巧不会对学生的学习造成“干扰”。最重要的是,它们使学生感兴趣。其次,它们提高了对共同发展需求的认识。此外,这些实践中最基础的实践通常易于执行,但一开始并不明显。一个年轻的木工店的学生可以轻松地学习如何用锤子的爪子去除钉子,但是在大多数情况下,必须首先告知这就是该爪子的用途。有些非常容易做的事情在没有被教导的情况下学习起来并不容易。即使是专业的开发人员,也总是会忘记这些“技巧”,而会受益于重构工具(例如重新共享工具)来删除冗余或未到达的代码等。


1
顺便说一句,如果有人能指出我该文章的标题,我将不胜感激!
大卫,

2

计算机程序设计通常是综合认知技能的第一门课程之一必须通过及格分数。这种技能很难传授给其他人。您可以解释他们可以使用的所有组件以及它们如何工作。您可以举很多例子,说明其他人是如何使用综合方法将这些成分组合成一个更有用的整体的,但是在没有学生脑海中“点击”的情况下,您可以做很多事情。

以我的经验,综合技能常常使那些不“了解”程序的人望而却步。他们对零件,变量,函数和循环等都有很好的理解,但是他们提出了这样的问题:“我知道为什么它起作用,但是您怎么知道需要在此处放置循环呢?” 您只需简单地练习即可,直到掌握为止。


2

要错误引用亚伦·希勒加斯(Aaron Hillegass),提醒他们他们并不愚蠢,这很难。编程很难训练您的思维,这是另一种思维方式,尽管他们可能在基础方面苦苦挣扎,但他们可能已经很清楚自己了,这会使他们相当沮丧。

我说这也是因为他也没有通过第一年的CS课程,所以我之前做了很多编程工作,并且掌握了所有概念(VB,是的,宝贝),但是C ++不会满足我的要求。我最终回到最基础的地方,然后从那里开始工作,然后单击它,但是如果有人说“你不是白痴,这很难,”那会让我的生活更轻松。


0

您说过“这些学生可能知道如何学习数学,生物学或物理学,但是编程时这些技术不起作用”。

这是有原因的,编程需要其他学科未必需要的东西:创造力和... 幻想。具有“想象工作中的事物”的能力。我个人发现,这样的要求在来自技术学校(尤其是电子学和机电学)的人们中(当然,除了所有适当的例外)更加迫切:他们必须“想象电流及其相互控制”,因为他们无法看到他们!),而不是“纯科学”(一切似乎都在颠倒数学)。

对于最后一种情况,必须帮助“视觉认知”。重要的是,不仅要专注于概念和文本(如果无法“读取”错误,则类型->编译->看起来错误将无法工作),而且还应提供一种在设计时可视化事物的方式(通过模拟机器上运行的内容:在白板上准备一套彩色的便利贴,并在执行时进行准备。

为了使最后一部分获得成功,必须给出操作系统的基本概念以及“程序如何在计算机中运行”(以及该计算机实际上是什么)。并且必须提供一个不令人生畏的IDE。我通常是一个“定制代码块”,其中删除了许多东西以“不要分散注意力”。在开始谈论一种语言之前,必须先给出由源组成的项目概念,以生成要与库链接的对象。

C ++传统的hello世界需要一个入口点和一个输出设备。学生必须已经熟悉它。这种课程的成功取决于最初的日子。您需要对计算机内部发生的事情进行可视化处理,以使他们了解什么是编程。
其余的是语法(科学)和抽象(幻想)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.