课程咨询 :13623629309

太原PHP培训 > 达内新闻 > 太原php培训班:寻址野史
  • 太原php培训班:寻址野史

    发布:太原PHP培训      来源:伯乐在线      时间:2016-06-17

  • 太原php培训班

    蓦然回首,那人却在,灯火阑珊处。

    1 众里寻她

    后花园三千佳丽,身处在如此众多的美人之中,作为后花园之主,该如何寻找心仪的美人度此良宵呢?

    历代君主想出了很多方法来寻找今夜伴侣,比如,晋武帝司马炎发明了“骑羊找美人”的方法,羊之去处便是今夜留宿之处;唐玄宗李隆基则提出了“掷骰子”法,谁掷骰的大就跟谁睡啦。

    虽有各种“寻美人”之法,但是大多是君主的一时兴起之选,没有制度化,不够规范。为博龙颜悦,管理好君主的夜生活,“翻牌子”制度应运而生。每一个美人会对应一张“名牌”,君主从中名牌中选择今夜侍寝之人。这种方法非常类似现在的O2O和各种到家服务,线上寻找服务,线下享受服务,棒!

    太原达内PHP培训

    何谓“翻”?何谓“牌子”?先说“牌子”,牌子与美人是一一对应的关系,每一张名牌对应唯一的一个美人,每一个美人对应唯一的一张名牌。“翻”的目的在于找到心仪的美人,“翻”的方法却有很多,比如,可以从牌子中选择,也可以直接喊美人过来(“小雁子,昨天的美人不错,让她再来一次”),甚至都无需说话,一个手势便明了了,就是她!

    太原PHP培训

    2 寻址

    CPU拥有计算机硬件资源的绝对控制权,对于一台8GB内存的计算机,即$8*1024^3B$=80多亿个内存单元,相当于有80多亿个佳丽啊,突然觉得我的后花园弱爆了!

    如何定位内存单元?只有定位到心仪的内存单元,才能够写入和读取数据。CPU为了享受到这些内存单元,必须解决这个问题。否则的话,很有可能翻的是嬛嬛却召见了皇后,多桑心啊。

    历史总是惊人的相似。CPU也使用类似“翻牌子”的方法寻找数据。CPU的体系结构规定,每一个内存单元都有一张名牌,通过名牌可定位到存储数据的地方,数据的写入和读取便容易了许多。

    为了让学习各种高级语言的人搞不懂这些概念,搞CPU的人给名牌起了一个抽象的名字——地址(Address)。CPU翻牌子(定位内存单元)的方法被称作寻址方式(Addressing Modes),寻址方式是CPU控制内存的基石。(明明寻找的是内存单元,是数据,为啥叫做“寻址”呢!)

    2.1 寻址方式

    不同的CPU可能使用不同的体系结构,这就导致其指令集、寻址方式有所不同。总的来说,数据寻址方式主要有以下7种:

    注:DS=2000H, BX=1234H, SI=1234H, (28054H)=3050H, (21234H)=6789H, (22234H)=7000H, (22468H)=8000H, (22478H)=9000H。[X]表示内存数据段(DS)中偏移地址X位置所存储的数据, (X)表示地址X中存储的数据。

    立即寻址方式 MOV AX, 1234H,则AX=1234H

    寄存器寻址方式 MOV AX, BX,则AX=1234H

    直接寻址方式 MOV AX, [8054H],则AX=(20000H+8054H)=(28054H)=3050H

    寄存器间接寻址方式 MOV AX, [SI],则AX=(20000H+1234H)=(21234H)=6789H

    寄存器相对寻址方式 MOV AX, [SI+1000H],则AX=(20000H+1234H+1000H)=(22234H)=7000H

    基址加变址寻址方式 MOV AX, [BX][SI],则AX=(20000H+1234H+1234H)=(22468H)=8000H

    相对基址加变址寻址方式 MOV AX, [BX+SI+10H],则AX=(20000H+1234H+1234H+10H)=(22478H)=9000H

    可以看到,对于要寻址的数据,可能来自指令(立即数)、寄存器(CPU)、内存;当数据来自内存的时候,我们需要指定内存的地址,而内存地址可能来自指令(立即数)、寄存器;当数据来自寄存器的时候,我们需要指定寄存器名称,而寄存器名称来自指令。有一种万剑归宗的感觉啊哈,源头便是指令。

    还有一种寻址方式——指令寻址。指令寻址与数据寻址不同,前者是寻找指令并执行,后者是寻找数据并计算。

    2.2 指令与数据

    指令,数据,还有那漆黑的未知,他们都静静躺在内存中。以开关的形式,安逸习惯,沉睡麻木,半生半死。指令可以改变数据,数据可以作为指令,指令与数据本一物,或者说根本就没有指令和数据,不过是一堆开开关关的门电路。本来无一物,何必惹尘埃。

    太原达内PHP培训机构

    3 指针

    内存地址不过是各个内存单元所拥有的名牌,他们无父无母,无名无姓,只有那一串地址。把玩地址,着实不是高级语言的使用者的爱好。我们不关注28054H这个地址里放的是什么,更关心对数据结构的操作和使用。

    3.1 变量与指针

    高级语言里的名牌不是地址,而是变量。除了对这些变量的写入和读取,我们还时常会发个快递,把一些变量传递给其他函数使用,比如这样:

    太原达内php培训

    有时候我们传的数据会很大,比如这样:

    太原达内php培训

    这样是OK的,但是有点笨拙。怎么说呢,就像我有一本书,你想看,然后我就把每一页都抄了下来,制作了一本新的书,给你了。我可以直接把原始的书给你的嘛!

    任何数据都是有地址的,所以,一个很自然的想法是把数据的地址传过去,这样就快多了。

    太原达内php培训机构

    其中,特别需要介绍pBook,即指针。其实这不过是玩高级语言的人为了报复搞CPU搞汇编的那帮人而提出的概念。高级语言的指针、内存中的地址,不过是内存单元的名牌罢了。

    不过,还是有些许不同。高级语言的名牌(指针)具有类型的概念,这样不仅可以定位内存单元,还可以知道需要使用几个内存单元。比如,int* age;是一个整数类型的指针,指针指向的内存区域使用了4个内存单元来存储整型数据(32位机器)。

    3.2 深拷贝、浅拷贝

    指针使用不当也会带来一些问题,比如拷贝问题。如果你执意要制作一本新书,然后可以做笔记啊什么的,比如这样:

    太原php培训

    这样按理说应该没事啊。但是,如果我们的Book是这样定义的时候就容易引发一些问题:

    太原达内php培训

    注意到Book有一个成员变量是pNote,表示这本书对应的笔记。如果使用copy来获取一本新书,这会导致name、content、pNote在拷贝之后存储的数据完全一样。pNote存储的是一个地址,这意味着我们都拥有了我所写的笔记的地址,你我都可以修改我的笔记。有时候,有某个变量的地址是件很危险的事情,因为你的初衷可能是复制一份自己用,但是当你修改这个地址所存储的数据的时候,将会影响其他使用该数据的人。因此,我们是需要知道拷贝的深不深,即深拷贝和浅拷贝。

    浅拷贝是复制一个副本,指针还是指向原始的数据;深拷贝是每一个部分都要是全新的,对其作出的任何修改都不会影响原始数据。当我们需要修改拷贝出的数据时,就需要考虑是否该进行深拷贝了。

    太原达内php培训

    3.3 引用

    指针比直接使用内存地址要方便的多,但是太过灵活了,只要你开心,可以有多级指针,即指针的指针。C++还提供了“引用”,比如这样:

    达内php培训

    与指针不同,指针需要调用者和被调用者协商好,调用者要取地址needBook(&book);,被调用者要指明指针类型的参数void eedBook(Book* pBook);。而对于引用来说,调用者再也不用考虑要不要取地址了,被调用者可以选择接受的是变量还是变量的地址,void eedBook(Book book);或void needBook(Book& book);。

    3.4 再看变量

    C++中的变量和Python中的变量可以代表变量的两大派系,前者需由程序员完成内存管理和垃圾回收工作,后者则由Python自己搞定,这便导致了不同的变量管理方案。

    对于C++来说,int a=1;表示把数字1放到a盒子里面;当继续执行a=2;的时候,会把数字2放到a盒子,而其原来的内容会被清空。对于int b=a;来说,会把a盒子的内容复制到b盒子中。

    而对于Python来说,a=1表示数字1被贴上了a标签;当继续执行a=2的时候,数字2会被贴上a标签,因为a标签只有一个,所以在贴到数字2之前会先从数字1上撕下来。对于b=a;来说,会把b标签贴到a标签贴的数字上面,即数字2。

    太原PHP培训

    此时,再看以下Python代码便不再会那么惊讶。x本来贴在数字1上,change把局部变量x贴到了数字2上,但是x还是贴在数字1上:

    太原达内php培训

    x本来贴在某一个列表上,起初列表中只有一个数字1,change把修改了局部变量x所贴的列表(增加了数字2),由于x和局部变量x都贴到了同一个列表,所以列表的元素被修改了:

    php培训班

    通过以上两个栗子可以看到,Python的等号并不是赋值,而是重新贴标签。而重新贴标签意味着失去对原始数据的控制,不能进行修改了。所以,第一个栗子不能够修改x,第二个栗子则可以修改x。如果我们硬要修改第一个栗子中的x,可以这样:

    坏消息是,整数类型的x并没有assign这个方法,好消息是,我们可以让他有(尽管不怎么优雅):

    太原php培训机构

上一篇:太原php培训:一个屌丝程序猿的人生(26)

下一篇:太原PHP培训机构:PHP 的变量实现

最新开班日期  |  更多

php高级开发名企定制班(剩2个名额)

php高级开发名企定制班(剩2个名额)

开班日期:12-30

php高级开发周末班(剩5个名额)

php高级开发周末班(剩5个名额)

开班日期:12-30

php高级开发免费试听(剩5个名额)

php高级开发免费试听(剩5个名额)

开班日期:12-30

更多高级开发工程师精品班

更多高级开发工程师精品班

开班日期:12-30

  • 地址:山西省太原市小店区学府街长治路高新国际A座24层
  • 课程培训电话:13623629309     全国服务监督电话:400-827-0010
  • 服务邮箱 ts@tedu.cn
  • 2001-2016 达内国际公司(TARENA INTERNATIONAL,INC.) 版权所有 京ICP证08000853号-56

    在线客服系统