zoukankan      html  css  js  c++  java
  • [蛙蛙推荐]SICP第一章学习笔记-编程入门

    本书简介

    《计算机程序的构造与解释》这本书是MIT计算机科学学科的入门课程,
    大部分学生在学这门课程前都没有接触过程序设计,也就是说这本书是针对编程新手写的。
    虽然是入门课程,但起点比较高,看懂里面的知识需要比较扎实的数学功底,
    最起码要有高中数学水平,如果高中数学没学好,看起来会比较吃力。

    当然,这本书的目标不是教你去做数学分析,或者让你学会使用LISP,他的目标我理解如下

    • 学会使用编程的一些基本元素,以编程的方式思考问题
    • 学会如何使用抽象和创造抽象来解决复杂问题
    • 学会如何良好的组织代码来编写大型软件系统,控制其中的复杂性
    • 是识别出好的程序设计和差的程序设计

    以数学来示范各种编程原理是因为数学问题比较普遍,好多概念大家都有所接触,
    没有二义性,不需要把时间花在问题描述和需求分析上。以LISP来进行编程原理解
    说是因为LISP语法非常简单,不需要把时间花在讲解语法上。

    程序设计的基本要素

    表达式

    LISP可能不好安装,我们就用Javascript来练习第一章的示范吧,打开Chrome浏览器,
    按F12打开开发人员工具,在Console标签里就可以写代码了。

    如果你还不知道编程能干什么,Javascript是啥东西,没关系,
    我们可以先来实现一些简单的数学计算,在Chrome的Console里输入如下代码

    >128
    128
    >128 + 12
    140
    >128 / 16
    8
    >128 - 28
    100
    >50 * 2
    100
    >3 + 2 * 10
    23
    >2 * 10 * 3.14
    62.800000000000004
    

    上面代码的大于号不用输,表示输入提示符,可以看到输入一些数学式子后Console会自动打印出
    这个式子的求值结果。暂时先不用管背后的原理是什么,你现在已经开始在编程了。

    上面你输入的式子就叫做表达式,里面的数就是普通的数字,+,-,*,/这些叫操作符,
    操作符可以操作数,他操作的是自己两边的数。

    命名和环境

    像上面的例子里2 * 10 * 3.14其实就是在计算一个半径为10的圆的周长,3.14就是圆周率π,
    计算圆的周长的公式不是2πr吗?

    如果我们要计算好多圆的周长,那么每次都要把3.14打出来吗?能不能给3.14起个名字呢?
    能,肯定能。能给某些计算对象命名是所有编程语言里最重要的一个功能,如下。

    >var pi = 3.14
    undefined
    >2 * pi * 10
    62.800000000000004
    >2 * pi * 5
    31.400000000000002
    >2 * pi * 8
    50.24
    

    上面的第一句var pi = 3.14就相当于给3.14起了个名字pi,后面计算周长的表达式都可以用pi来代替3.14。

    这就是一个最简单的抽象手段,你不需要记住pi的值具体是多少,只需要记住pi就表示圆周率就行了。
    这个思路很关键,以后写代码写多了,你会发现你写的代码越来越复杂,能够给你写的部分代码进行命名,
    然后使用的时候不用关心复杂的细节,就可以控制住这种复杂性,写出复杂的大程序来。

    组合式的求值

    3 + 2 * 10这个式子,*会先把2和10进行乘法计算,得到20,然后+会把3和20进行相加,
    得到23,整个过程和数学里的加减乘除运算规律是一样的。如果你想执行(3 + 2) * 10的结果,
    也可以直接把这个式子在Console里输入,也能正确的执行。

    你在写2 * pi * 10时,pi会自动替换成3.14,这说明Javascript解释器帮你存储了pi到3.14
    的对应,这种存储我们叫环境,每个环境里都存储了一些名字和计算对象的对应关系。
    环境是个普遍的概念,它为求值的过程提供了一种上下文,对于我们理解程序
    的执行起着很重要的作用。

    比如你要执行(3 + 2 + 5) * (2 * (1 + 2)),这个表达式的求值过程就稍微复杂点了。
    总体来看呢,这个式子分成两个部分,一个是(3 + 2 + 5),一个是(2 * (1 + 2)),然后
    这两个部分进行想乘。要想得到这两个部分的相乘呢,又要先得到这两个部分的结果,怎么得到呢?
    我们发现这两个部分其实也是表达式,比如(2 * (1 + 2)),其实也有两部分组成,一个
    2,一个是(1 + 2),这两个部分相乘。这样从外到里分析,肯定会分析出最简单的不
    能再分的表达式,可以直接求出结果。

    这个过程就叫做递归,先不用计较复杂的解释,就先理解复杂表达式的求值需要先对子表
    达式进行求值,子表达式的求值需要对子表达式的子表达式求值,这个过程就叫递归

    递归是个刚开始不太好理解的概念,但掌握后用它来理解很多问题就很轻松了,以后会经常
    遇到,加深印象。需要提的就是递归要有几个注意的地方。

    1. 递归分成好多个步骤
    2. 每个步骤要把整个事情向前推进,每次推进都向最终点更近一步。
    3. 整个递归过程要有个最终点,否则整个过程就无法终止了。

    比如复杂表达式的求值过程就分成多个步骤,每个步骤就是把复杂表达式拆成多个子表达式
    ,然后每次拆呢,肯定是拆的越来越小,把整个过程向终点推进一步,然后呢如果拆的不能
    再拆了,比如1 + 2直接就能得到结果了,这就到最重点了。

    以上说的这些规则,就叫做编程的语法,慢慢你会发现有的编程语言的语法特别多,需要记住的东西特别多,比如各种括号,特殊字符,关键字。
    而有的编程语言的语法特别少,基本上不用记,一大屏代码看到的都差不多的格式。刚学编程的时候建议选择后面一种的编程语言,如Javascript, Python,尽量学习一些编程的本质,而不是各种语法。

  • 相关阅读:
    php生成二维码遇到的问题
    ua判断页面在什么终端/系统打开
    js实现复制文字到剪切板
    jquery 实现表单数据转化为对象格式
    [转]关于setTimeout()你所不知道的地方
    关于性能优化
    关于event loop
    JS数据结构与算法--双向链表
    JS数据结构与算法--单向链表
    JS数组去重
  • 原文地址:https://www.cnblogs.com/onlytiancai/p/3632573.html
Copyright © 2011-2022 走看看