【问题标题】:When teaching C, is it better to teach arrays before or after pointers? [closed]教C时,在指针之前还是之后教数组更好? [关闭]
【发布时间】:2009-03-22 00:50:59
【问题描述】:

对于那些有课程开发经验的人:关于数组的最佳策略是什么?

我见过一些学校在变量和控制结构之后教授数组,通常甚至在教授函数之前。这允许教授一些基本算法等。但是,它带来了如何将数组传递给函数的问题,因此有必要回到数组指针被教授并修补。

另一种选择是从变量和控制结构转到函数,然后教指针,一旦有了指针,就从头开始教数组,然后使用它来进行动态内存分配。

对我来说,第二个选项更有意义,因为与简单的变量不同,数组很容易“越界”,但尚未了解内存和指针的学生可能无法理解这些边界之外的内容。

不过,我很想知道其他人的想法。

【问题讨论】:

    标签: c arrays pointers


    【解决方案1】:

    我认为最好的方法是一次引入 1 个概念。您不需要在第一个模块中 100% 解释数组。您可以通过一次引入 1 个概念来解开几乎任何事情。

    我会按以下顺序教他们:数组、指针、数组+指针、OtherStuff[N]。


    数组:

    您可以先教授简单的数组,以便他们了解从单个变量名访问多个数据槽的能力。

    //The following doesn't need an understanding of pointers
    int x[10];
    x[0] = 5;
    

    指针:

    然后你可以从一些简单的例子开始教授指针及其工作原理:

    int y = 5;
    int *p = &y;
    *p = 6;
    printf("%i\n", y);
    

    请务必特别强调指针与任何其他变量一样。它存储一个内存地址。

    目前还没有必要进入堆栈与堆。


    数组+指针:

    如何用指针遍历数组:

    int x[10];
    x[0] = 5;
    x[1] = 6;
    int *y = x;
    printf("%i\n", *y);//prints the first element
    y++;
    printf("%i\n", *y);//prints the second element
    

    那你就可以教更复杂的东西了……

    在所有示例中都大量使用 sizeof 和打印地址。这真的有助于理解发生了什么。

    【讨论】:

    • 对于高级主题,多维数组可能很有用。当学生准备好时,权衡将 2D 结构表示为具有显式 2D 索引的“int **arr”或具有手动索引的“int *arr”可能会有所帮助。
    • 嘿,这就是我被教导的方式。它工作得很好。
    • @Devin Jeanpierre:是的,如果你下定决心要学习一些东西,你最终还是可以理解的,即使所解释的概念相互交织。但并不是每个人都下定决心学习手头的主题,所以一步一步,线性顺序学习是最简单的。
    • 你把函数放在哪里?如何避免“将数组传递给函数”问题?
    • @Uri: 添加到其他部分
    【解决方案2】:

    我会先教指针。它们可以在不教授数组的情况下进行解释。在教授数组时,我可以在解释表达式a[i] 以及如何将它们传递给函数时引用指针。

    【讨论】:

      【解决方案3】:

      不要想太多。

      尽可能清晰和引人入胜地教授这些概念远比您按什么顺序进行教学更重要。

      我建议先接触数组的基础知识,然后再做指针和重新访问数组(这次更全面)。

      【讨论】:

        【解决方案4】:

        您应该首先教数组,因为它们几乎存在于任何其他语言中,并且更容易理解。指针,或指针的某些方面,建立在对数组的了解之上。这是有机的顺序,恕我直言,以及我在很久以前是如何学会的。

        【讨论】:

          【解决方案5】:

          我假设您正在向已经知道如何用另一种语言(如 Java)编程的学生教授 C(或者回到我的时代,Pascal)。我不认为 C 是一种很好的语言来教授编程以完成新手。

          我会先教指针。这是将在 C 中学习的重要新思想之一。他们已经从其他语言中了解数组的概念,因此没有紧迫性首先教授这一点。因此,当您在 C 中讨论数组时,您可以谈论它们本质上是指针算术的语法糖,这是他们现在熟悉的概念。

          【讨论】:

          • 您似乎在暗示 Pascal 没有指针。我已经很多年没有和 Pascal 一起工作了,但在我的日子里,Pascal 有一些指示。我是在那里第一次了解它们的,因为我已经有几年没有进入 C 了。
          【解决方案6】:

          他们应该同时被教导。

          一个一维数组的例子被访问为指向具有偏移量(类型大小 * 索引)的基数的指针应该会出现。

          a[i] is equivalent to *(a + i)
          

          【讨论】:

          • 这是一个小问题,除非内存是易失性的或者你期待竞争条件。 =]
          • @strager:你愿意解释一下吗?
          • @Mitch,你写了一个作业。也许你的意思是 ==。
          • @Earwicker:谢谢!最近做的数学太多了!
          【解决方案7】:

          在我担心数组之前我会教指针。但是,通常情况下,我看到的学生,他们已经在他们的第一堂 CS 课上接触过其他语言的数组。然而,即使我在第一堂 CS 课上教 C,我也会在数组之前做指针,并用指针来描述数组。仅仅因为现在流行“没有人需要或想知道计算机的实际工作原理”这一想法并不意味着它是正确的。

          【讨论】:

            【解决方案8】:

            如上所述,我认为顺序并不重要, 但这是我希望有人向我展示这些东西的顺序。

            1. 数组
            2. 指针
            3. 数组和指针的相同之处
            4. 为什么数组和指针不一样

            关于第 4 点的更多信息,我真的推荐第 4 章 “令人震惊的事实:C 数组和指针不一样!”在“专家 C,深 C 秘密”中。

            /约翰


            更新

            本书的一些链接,还有本书的预览。 http://books.google.se - Expert C, deep C secrets

            而且用户对这本书的评价是真实的: http://www.amazon.co.uk/Expert-Programming-Peter-van-Linden/dp/0131774298

            【讨论】:

            • 我不熟悉那本书。它强调的主要区别是什么? (我在这方面投入的时间非常有限,但我想证明一个令人信服的论点)
            • 这本书没有魔法,但它给了我一个“大开眼界”的时刻。这本书以另一种方式介绍了数组和指针。
            【解决方案9】:

            如果他们事先接触过汇编程序,请先教指针。

            如果他们接触过更高级的语言(即几乎任何东西),首先教数组。

            根据我的经验,在没有接触过汇编级编程(寄存器、地址、“计算机基础”)的情况下使用 C 语言的人即将进入一个痛苦的世界。恕我直言,您实际上最好先教授汇编级编码,然后将 C 作为更好的汇编程序引入。

            【讨论】:

            • 是的,这更简洁地表达了我的想法。
            【解决方案10】:

            有趣的问题 - 我希望现在回答还为时不晚。

            当我在 80 年代初在波士顿学院教授编程时,我和我的同事每年都在与这些问题作斗争,并且我们不断调整我们的方法。那时 C 是一门新语言,所以我们的发展经历了从 Basic 到 Pascal。我记得当时在想教 C 语言会有多难,因为它比较松散,有更多的方式让学生搞砸了,还有更多真正令人困惑的事情,比如你必须教的数组和指针之间的区别.

            我发现最有用的是尝试具体化,而不是抽象化。例如,在介绍编程课程中,我使用了一个简单的十进制计算机的解释器,你可以用它的十进制“机器语言”进行编程。它的地址从 0 到 999,操作码如 1234,其中“1”表示“添加到累加器”,“234”是找到要添加的数字的地址。学生会编写非常简单的程序,例如将数字列表相加,然后他们会单步执行它们,观察每一步发生的情况。

            我会让他们玩这个大约 3 周,然后开始学习 BASIC。在第二门课程中,他们将进入 Pascal。那台小十进制“计算机”完成的是传达一些具体概念,使“真实”语言中的“抽象”更容易理解,例如:

            • 什么是内存,什么是地址,以及数据和程序如何只是内存地址中的数字。这使得“变量”、“数组”和“指针”的概念在后面更容易解释。
            • 计算的基本模型是按顺序执行非常简单的步骤,并且在每个步骤开始之前,前一个步骤必须完成。我知道现在人们会反对计算机高度并行化和流水线化,但我必须解释一下,你需要从非常简单的开始,因为当新手看到一个程序运行时,它会寻找整个世界,就像它一次完成所有事情一样,然后读取在这个过程中你的想法。
            • 如何通过组合非常少的指令词汇(包括跳转和条件跳转),让计算机执行几乎任何您想做的事情。

            现在,关于 C,我听说它被贬低为超越汇编语言,但我认为这是一件好事。作为专家对专家的语言,它总是让我印象深刻。我认为数组、指针和结构的想法很容易解释,如果你可以回溯到底层机器的话。对于 C++ 和面向对象的编程也是如此。

            因此,总而言之,如果学生了解计算机如何工作的基本概念,即使它是一台真正的人工计算机,那么解释更高级别的数据结构概念也会容易得多。

            【讨论】:

              【解决方案11】:

              取决于他们知道什么。您是在教 C,还是编程和 C?

              我看到后者几乎没有成功。 C 根本不是一种非常直观或宽容的语言。我没有看到学生对开始使用它表示感谢,尽管我看到学生对它的编程感到沮丧。

              无论如何,那些坚持编程的人会在业余时间出去学习 C。没有必要先把它推到他们身上。

              如果您只是在教 C,并且他们已经知道指针和数组,那么可以在一堂课内教指针和数组如何在 C 中工作。

              【讨论】:

                【解决方案12】:

                你会在字符串之前教指针吗?

                可能不会。大多数相同的论点都适用。

                (但总的来说,我同意@legion - 不要想太多。)

                【讨论】:

                  【解决方案13】:

                  我认为最好从数组开始,因为数组的概念简单直观,但在 C 语言中,重要的是在教学后重新访问数组,正如“Legion”之前所建议的那样。

                  【讨论】:

                    【解决方案14】:

                    这个问题真的可以问任何面向对象的语言。

                    当我学习 Java 时,首先向我展示了数组和指针,作为数组的最后一部分,以演示深拷贝和浅拷贝之间的区别。

                    【讨论】:

                      猜你喜欢
                      • 2014-07-30
                      • 2011-01-17
                      • 1970-01-01
                      • 2010-11-07
                      • 1970-01-01
                      • 2015-08-17
                      • 2023-02-15
                      • 1970-01-01
                      • 2010-12-23
                      相关资源
                      最近更新 更多