• 【编程漫谈】程序的运行流程


    自动分拣系统

    当我们看到一个程序流程图的时候,这时程序在我们的脑子里是立体的。一条条箭头就像一根根导管,程序就像流水,向着规定的地方流动。程序就像一个自动分拣系统,不同的数据会导致不一样的结果。但无论是哪种系统,都是安照人类的意志,直到结束。

    中国象棋

    再举个下棋的例子。下棋的过程就是一个程序执行的过程,你在决定下一步怎么走的时候,脑子里有很多条件的输入和输出,我走哪个棋会产生哪个结果,对方走哪个棋会产生什么样结果。传统上我们将怎么走棋归于个人的经验,实际是人的大脑在模拟电脑的演算过程。

    程序流程

    上边的流程图中,我们可以把A、B、C……相像成棋子子,不同判定表示你决定下一步怎么走棋。所以宏观上理解一个程序运行过程,其实就是这个样子的。

    程序的执行流程也有点像走迷宫,迷宫只有一个入口,一个出口,走迷宫就是在迷宫里不停地找出口的过程。程序其实也是这样,从程序入口进入,经过各种判定、跳转最后到程序结束。

    但实际上一个应用程序没有相像中那拥有具象,程序实际上一堆线性数据。下图中就是某个程序内容,它们按顺序存放,每一行可能是一条指令或是一条数据。

    二进制数据

    这个静态的顺序数据,就像展开的六面体。同样我们也给六面体编上号,然后安装顺序折起来,于是就得到一个六面体。程序也是这样的,只是六面的展开图还是二维的,而程序的线性表是一维的。

    展开的盒子

    为了方便理解这些十六进制表示的二进制数据,我们可以将这些内容转换成汇编程序。

    反汇编

    这样一个二进制的程序就可以看懂了。不过,这种代码的数据量是非常巨大的,比如一个程序大小为100K,那反编译出的汇编代码可能就有2W5K行,如果是更大的程序,那反编译出来的代码也是海量的。因为太大的程序,阅读汇编是非常不靠谱的。

    但我们可以根据汇编代码看出一些程序的执行过程,比如ret,jmp,call,mov等关键字,就是在线性表中跳来跳去。直到跳到程序的结束。

    因为汇编这种低级语言,没法看到程序的整体面貌,且编写量巨大,所以一般不会用汇编直接去写程序的,更不用说直接编写二进制代码。首先指令啊、asciis值,字符集,各种文件编码,这些对应关系,就是一个非常复杂的工程。所以用低级语言做个系统,等你做出黄花菜都凉了。因而有人就发明了高级语言,将生成二进制的过程用编译器来做。

    有了高级语言之后,我们在写程序的可以忽略底层的机器码。我们将精力放在程序本身要实现的功能上。高级语言发明出来后,人们把一些汇编指令做了一些归纳。

    程序流程图

    如果程序中没有return ,continue,break等关键字,程序就是从上到下依次执行的,如果当中有if,case之类的条件判断,则某些代码块就有准入条件。

    高级语言中肯定什么条件判断的关键字,肯定有上图中的几条执行流程。下边是T-SQL的示例。

    DECLARE My_Cursor CURSOR --定义游标  
    FOR (SELECT * FROM dbo.MemberAccount) --查出需要的集合放到游标中  
    OPEN My_Cursor; --打开游标  
    FETCH NEXT FROM My_Cursor ; --读取第一行数据  
    WHILE @@FETCH_STATUS = 0  --Sql Server中的循环
        BEGIN  
            --UPDATE dbo.MemberAccount SET UserName = UserName + 'A' WHERE CURRENT OF My_Cursor; --更新  
            --DELETE FROM dbo.MemberAccount WHERE CURRENT OF My_Cursor; --删除  
            FETCH NEXT FROM My_Cursor; --读取下一行数据  
        END  
    CLOSE My_Cursor; --关闭游标  
    DEALLOCATE My_Cursor; --释放游标  
    GO
    

    Typescirpt中的循环控制

    for (let index in testArray) {
          console.log("数组的下标:"+index);
        }
    /*
    数组的下标:0
    数组的下标:1
    数组的下标:2
    数组的下标:3
    */
    
    for (let value of testArray) {
          console.log("数组的值:"+value);
        }
    /*
    数组的值:20
    数组的值:string
    数组的值:true
    数组的值:hahha
    */
    
    testArray.forEach((value, index, array)=>{
          console.log("value:"+value+"--index:"+index);
          console.log(array);
        });
    /*
    打印日志:
     value:20--index:0
     (4) [20, "string", true, "hahha"]
     value:string--index:1
     (4) [20, "string", true, "hahha"]
     value:true--index:2
     (4) [20, "string", true, "hahha"]
     value:hahha--index:3
     (4) [20, "string", true, "hahha"]
    */
    
    

    actionscript中的几种循环:

    for同C语言;
    for(...in...)循环访问对象属性或数组元素;
    for each(...in...)循环访问集合中的项目,迭代变量包含属性所保存的值,不含属性的名称;
    while同C;
    do...while同C。

    F#中的循环写法:

    for i = 1 to 5 do
    printfn "%d" i;;
    

    Groovy中的循环

    for(variable in range) { 
       statement #1 
       statement #2 
       … 
    }
    

    从以上的示例可以看出,无论哪种编程语言,总是有相通的地方。也许他们写法各异,但思想方法是接近的。所以说,如果你精通了一门编程语言后,再学其它的编程语言也应该是很轻松的。

  • 相关阅读:
    各省最受考生青睐高职院校TOP10!2021年专科投档分数线大盘点
    Python 下载大文件,哪种方式速度更快
    Idea未识别maven项目
    Disruptor
    原型对象
    线程基础知识18 线程池
    线程基础知识16线程相关类CyclicBarrier、Semaphore、Exchanger
    ES6 01 简介
    线程基础知识17 Quene
    线程基础知识12AQS
  • 原文地址:https://www.cnblogs.com/icoolno1/p/11361833.html
Copyright © 2020-2023  润新知