当前位置: 首页 > news >正文

网站前端设计要做什么的wordpress 文章摘要 插件

网站前端设计要做什么的,wordpress 文章摘要 插件,案例查询网站,邗江区网站建设套餐计算机世界有一个常识——所有的数据和指令必须经由内存才能进入CPU的寄存器进而被CPU使用#xff0c;那么我们程序操作的主战场就是内存#xff0c;内存操作也就顺理成章成为了程序中最高频的操作。为了节目的效果#xff0c;我们先来看一段8086平台下的汇编代码#xff1… 计算机世界有一个常识——所有的数据和指令必须经由内存才能进入CPU的寄存器进而被CPU使用那么我们程序操作的主战场就是内存内存操作也就顺理成章成为了程序中最高频的操作。为了节目的效果我们先来看一段8086平台下的汇编代码 1assume cs:code 2code segment 3  dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h 4  start: mov bx, 0 5        mov ax, 0 6 7        mov cx, 8 8    s:  add ax, cs:[bx] 9        add bx, 210        loop s1112        mov ax, 4c00h13        int 21h14code ends15end start   在说明上面汇编代码的功能之前我们先来介绍一下loop指令loop指令的格式是loop labelCPU在执行loop指令的时候要进行两步操作——1.将cx寄存器中的值减一2.判断cx寄存器中的值不为0则转至标号处执行程序如果为0则不跳转继续向下执行。上面那段代码代码的功能就是计算0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h这8个16进制数的和为了正确加载数据上面的代码中使用了寄存器间接寻址的寻址方式即将寄存器bx中的值作为变址使用而且我们在上面存储数据的时候使用了dw关键字其指出其后的每一个数据的长度为两个字节汇编语言的编译器会负责帮我们组织数据。上面的代码中使用纯粹的偏移量来进行内存访问非常不方便我们也可以使用标号的方式来进行内存的访问如下汇编代码 1assume cs:code, ds:data 2data segment 3  ary db 10, 20, 30, 40, 50 4  ty  db 20 5data ends 6code segment 7start: mov cx, (ty-ary) 8      ... 9code ends10end start上面的代码中我们在数据段中使用了标号 ary和ty而在代码段中使用表达式ty-ary来计算ary所代表的数组(暂且认为它就是一个数组的头指针吧)的长度。而在实际汇编的时候这个表达式会被汇编程序计算最终其实就等价于5-0也就是5.通过上面的汇编代码我们可以知道汇编语言中可以有表达式但是汇编语言中的表达式完全是静态的是由汇编程序计算的而程序所有的运行时行为都是由指令体现出来的。实际上汇编语言中所有的标号都是一种伪指令它们代表的都是某个地址值而已更准确的说是一个地址的偏移量使用标号的目的是使得我们更加方便的引用一个地址值而且这个值是在静态阶段已知的它只是具有辅助作用并不直接参与内存访问。上面的程序中我们使用了伪指令dw来告诉汇编程序我们的数据占用多大的内存空间而我们从内存中读取数据的时候要读取多大的内存空间呢这一部分信息隐藏在了指令的目标寄存器中比如上面的add ax cs:[bx]这行代码的目标寄存器是ax是16位的寄存器我们要从地址cs:[bx]开始读取16位也就是两个字节如果我们把目标寄存器换成ah那么就成了读取8位也就是一个字节了。可以看出我们在使用汇编语言进行内存访问的时候数据应该以怎样的步长读取读取到的数据可以进行什么样的操作语言本身能提供给我们的元数据信息非常有限而且几乎没有对我们进行任何的限制。我们所能依靠的只有代码注释和自己的大脑这样的编程方式就像走钢丝一样稍不留神就会坠入万丈深渊。左值和数据存储区域编程界流传着这样一句话——机器生汇编汇编生BB生CC生万物。在高级程序设计语言领域中很多的高级语言都深受C语言的影响而且很多语言的自举都是从C语言开始的而我这个系列的文章正是谈自己对于高级程序设计语言的理解所以很多的故事都是从C语言开始讲起的。关于自举我们后面的文章会有介绍。在C语言中用于存储值的数据存储区域统称为数据对象但是考虑到数据对象这个术语可能会和面向对象编程中的对象混淆所以我们这里采用数据存储区域这个术语。那么在汇编语言中的内存访问操作在C语言中相对应的就是对数据存储区域的访问。在C语言中对某个数据存储区域的引用被统称为左值(lvalue)意思是它可以出现在赋值操作的左侧(可以是赋值操作的目标操作数)这是很好理解的因为赋值操作的目的是把值存储在某个数据存储区域上这就意味着只有一个数据存储区域的引用也就是左值可以作为赋值操作的目标操作数(左值(lvalue)中的l就是来自于此)其实左值的概念是适用于所有的高级程序设计语言的而且在高级语言中访问某个数据存储区域的唯一方式就是使用左值除此之外别无他法。也就是说左值和数据存储区域存在如下的关系左值和数据存储区域之间的关系我们在代码中使用左值来引用(代表)某个数据存储区域我们可以简单地认为一个左值指向某个数据存储区域它代表的是其引用的数据存储区域的首地址。左值的两种操作——LHS查询和RHS查询我们知道访存操作一共就两种要么读、要么写对应的我们对左值的操作其实一共就两种——分别是LHS(Left Hand Side)查询和RHS(Right Hand Side)查询。L和R的含义它们分别代表左侧和右侧。什么东西的左侧和右侧呢是一个赋值操作的左侧和右侧。LHS和RHS的含义是“赋值操作的左侧或右侧”并不一定意味着就是“赋值操作符的左侧或右侧”。赋值操作还有其他几种形式比如对函数的形式参数的赋值。因此在概念上最好将其理解为“赋值操作的目标是谁(LHS)”以及“谁是赋值操作的源头(RHS)”。当变量出现在赋值操作的左侧的时候编译器或者解释器对其执行LHS查询这个时候我们并不关心这个变量所引用的数据存储区域中的值是什么而是想要找到这个数据存储区域并将赋值操作的源值放到这个数据存储区域中(对其进行赋值操作)所以说LHS查询对应内存访问中的Store(写)操作。如下图所示左值的LHS查询在进行LHS查询的时候lvalue就代表其所引用的数据存储区域这个容器赋值操作的源会直接被写入这个数据存储区域中语言的编译器或者解释器负责实现底层的写内存操作。RHS查询对应的是内存访问中的load(mov/读)操作这个时候我们不关心这个变量所引用的数据存储区域而只是想得到这个数据存储区域中所存储的值。从这个角度来说RHS并不是真正意义上的“赋值操作的右侧”更准确地说应该是非左侧。如下js代码1let obj  {2    say: ()  {3        console.log(Hello World)4    }5}67obj.say()上面的obj.say()这一行代码中obj并不是赋值操作的目标也就是说它出现的位置是赋值操作的非左侧那么这个时候js解释器就会对obj进行RHS查询。如下图左值的RHS查询在进行LHS查询的时候lvalue就代表其所引用的数据存储区域中所存储的值这时候我们相当于直接使用值语言的编译器或者解释器负责实现底层的读内存操作。总而言之RHS查询关心的是变量所引用的数据存储区域中的值它对应的是内存的读操作而LHS查询关心的是变量所引用的数据存储区域其对应的是内存的写操作。左值是类型化的存储区域上文我们介绍了在高级语言中我们通过左值来定位一个数据存储区域对左值进行RHS查询和LHS查询分别对应对数据存储区域的读操作和写操作。但是如何进行读和写应该读或者写多大的区域我们把数据读出来之后又应该怎么使用呢和汇编不同的是高级语言对这方面进行了抽象提供了数据类型的概念数据类型提供了一个值需要占用多大的内存空间、一个值可以进行哪些操作这些元数据信息。语言的编译器或者解释器也正是根据数据类型配合左值来帮我们处理底层的访存操作。也就是说数据类型不仅代表了内存空间的大小同时我们在编码的时候可以施加于其上的操作也受数据类型的限制(根据语言的不同这种限制有可能是在编译时有可能是在运行时或者这两个阶段都存在)而且不同的类型具有不同的语义这样一个内存空间中数据的作用就能在一定程度上通过源代码感知到实现了一定程序上的自文档化。但是在数据类型这个地方产生了两种分化一种是静态数据类型一种是动态数据类型。对于静态数据类型而言左值引用的数据存储区域在语言的编译阶段就能够确认而对于动态类型来说则需要在运行时进行查找。静态类型的语言在编译时左值所引用的数据存储区域中所存储的值的数据类型就是已知的而对于动态类型的语言来说左值所引用的数据存储区域中的值必须在运行时才能确定。但是对于一个值来说它一定是有一个明确且唯一的类型的。语言的类型系统也是构成一门语言的世界观的语言核心特性在下一篇文章中我会详细介绍语言的类型系统这里也就不做过多介绍了。变量实体——左值的诞生在大多数的文献中并不区分左值和变量这两个概念认为这两者是等价的。但是在这篇文章中我们需要一个概念来指明某个变量是我们在编写代码的时候所声明的‘变量’这种程序实体所以这里我们引入一个概念——变量实体用来指代我们在源代码中所声明的‘变量’这种程序实体。如下js代码1let obj  {2    a: 1,3    b: 2,4    c: 35}上面代码中的obj是我们声明的一个变量实体而且是上面代码中唯一的一个变量。obj.a、obj.b、obj.c是变量但是它并不是我们声明的其身份是对象obj的一个属性。在高级语言中获得一个左值的最终方式是声明一个变量实体。左值树为什么上文如此强调变量实体这个概念呢那是因为我们对左值的使用都是从我们声明的某个变量实体开始的而且在引入自定义数据结构之后自定义结构中的属性也是一个左值而最终所有的左值会构成一个逻辑上的树形结构。如下的C语言代码 1#include  2 3typedef struct { 4  char province[32]; 5  char city[32]; 6  char area[32]; 7  char address[128]; 8} Location; 910typedef struct {11  char name[32];12  char header[32];13  Location location;14} School;1516typedef struct {17  int age;18  char name[32];19  School school;20} Student;212223int main() {24  Student laomst  {25    .age24,26    .namelaomst,27    .school{28      .nameqknd,29      .location{30        shandong,31        qingdao,32        chengyang,33        changchenglu 700 hao34      },35      .headersongxiyun36    }37  };38  printf(%s, laomst.school.location.address);39  printf(\n);40  Student *laomst_ptr  laomst;41  printf(%s, laomst_ptr-school.location.address);42}上面的代码中我们声明了一个名为laomst类型为Student的变量实体而其实这个变量实体拉起了如下的一个左值的树形结构左值树这棵树中的每一个节点都是一个左值而我们声明的laomst这个变量实体正是这个左值树的根节点。现在我们来总结一下左值就是变量因为左值引用了一个用来存储数据的数据存储区域而其中存储的值是可以改变的。复合数据结构类型的左值代表了一个左值树而这个树的根最终就是我们在代码中声明的某个变量实体。我强调变量实体这个概念的原因就是其代表的是某个左值树的根节点我们在程序中获得左值的唯一方式是声明一个变量实体同时我们对于某个左值的访问也是从一个变量实体(左值树的根节点)开始的比如上面代码中的printf(%s, laomst.school.location.address);这行代码我们想要访问上图树中最右下角的address节点也是从根laomst开始一层层走下去的。数据结构是逻辑上的概念上文中我们给出了laomst这个左值的内存结构的逻辑图其实在真正存储的时候使用的是一段连续的内存空间其物理图如下所示左值树的物理结构但是这并不影响其逻辑上是一棵树。当然使用连续内存存储的根本原因是C语言是静态数据类型的如果是动态类型的语言可能就真的是一个树形结构了。其实数据结构更多的是一种逻辑上的数据组织而同一个数据结构在物理上可能有多种存储方式比如顺序表可以使用数组存储也可以使用链表存储、完全二叉树也经常使用数组进行存储、图可以使用邻接矩阵(二维数组)也可使用邻接表(链表方式)进行存储…不同的物理存储方式可能决定不同的逻辑特性毕竟逻辑是基于物理的但是根据空间局部性原理来说使用连续的内存来存储数据在时间上可能会更加高效一些。我后面也会有数据结构和算法相关的文章其中我们详细介绍我对数据结构和算法的理解。简单名和限定名我们再次回顾一下在【左值树】小节中的代码中的最后四行如下1  printf(%s, laomst.school.location.address);2  printf(\n);3  Student *laomst_ptr  laomst;4  printf(%s, laomst_ptr-school.location.address);我们访问address这个左值的时候使用了一系列的标识符而不是直接使用address这个标识符。上面代码中的laomst.school.location.address其实也是一个标识符是一个名称其引用一个代码实体而我们称这样的名称为限定名。而laomst_ptr-school.location.address中的形式有所不同laomst_ptr是一个指针类型的变量使用它访问其内部的属性需要使用-操作符但是不管形式如何只要涉及左值树中子节点的访问我们使用的都是限定名称。与限定名对应的是简单名laomst.school.location.address中的laomst就是一个简单名什么是简单名和限定名呢简单名简单名就是指我们在声明一个代码实体的时候分配给代码实体的标识符如下Java代码1public class Test {2    private String foo;3    public String foo() {4        return ;5    }6}上面的代码中存在三个简单名分别是类名Test、类的成员变量foo和类的成员方法foo。限定名限定名就是指我们在引用一个代码实体的时候不能使用它的简单名而是必须用其所属的那个代码实体的简单名对其进行限制最典型的场景就是我们访问自定义类型的内部属性的时候需要用自定义类型的变量名限定其内部属性的简单名如下Java代码所示 1public class Person { 2    private String name; 3    public Person(String name) { 4        this.name  name; 5    } 6    public String getName() { 7        return name; 8    } 9}1011public class Test {12    public static void main(String[] args) {13        Person p  new Person(Tom);14        String pname  p.getName();15    }16}上述代码中的String pname p.getName()在访问Person类型的变量p的getName方法的时候不是直接使用getName这个简单名而是使用p对getName这个简单名进行了限定在面向对象的术语中称我们向p这个Person类型的对象发送了一个消息。对于变量来说不难发现简单名对应的其实就是一个左值树的根也就是我们声明的一个变量实体。需要注意的是上面的类名Person也是一个简单名但是这里我们只讨论变量不讨论其他类型的程序实体其他类型的程序实体需要在具体语言中具体分析。引出简单名和限定名这两个概念是为了方便接下来对变量作用域的介绍。变量的作用域我们讨论作用域的目的是编译器或者解释器是如何搜索也代码实体的它是在什么地方搜索我们所声明的代码实体来构建程序的上下文的呢答案就是——编译器或解释器是在作用域中搜索我们的代码实体的。在计算机编程中作用域是使得名称绑定(一个标识符和代码实体(例如变量)的绑定关系)有效的一块区域在这个区域中名称可以用来引用代码实体。在程序的其他区域中相同的名称可能引用不同的代码实体(在不同的作用域中名称可能具有不同的绑定)也有可能压根不引用任何实体(在这个作用域中没有关于这个名称的绑定关系)。绑定的范围也称为代码实体的可见性我们一定要注意的是标识符的背后一定对应了一个代码实体我们要讨论的是代码实体的可见性而不是这个名称的可见性。对应于代码上作用域是程序的一部分它本身就是或者它可以作为一组绑定的范围。想要给出作用域的一个精确定义是比较困难的但是我们在编码时作用域在很大程度上对应于块、函数或文件具体取决于语言和代码实体的类型。作用域也用来指所有可见的实体的集合或在程序的一部分或程序中给定的点有效的名称更正确的说法为上下文或环境。----- 维基百科对于一个程序实体如果我们能够通过简单名对其进行引用那么我们就称当前的程序上下文处在该程序实体的作用域内而对于限定名所引用的程序实体的绑定可能会涉及其他的规则这里我们不做深入的讨论因为对于所有程序实体的引用都是从一个简单名开始的。同样的为了让内容尽量普适我们这里只介绍变量实体的作用域而且是基于运行时调用栈来进行分析的对于其他类型的实体还是到具体语言中具体分析。作用域共有两种主要的工作模型静态作用域和动态作用域这两种作用域的不同之处在于其对“程序的一部分”的理解方式是不太一样的。静态作用域(词法作用域)静态作用域是被大多数编程语言所采用的作用域规则这时候“程序的一部分”指的是“源代码的一部分(是一个文本区域)”。这时候“程序的一部分”是一个文本属性由语言实现独立于运行时调用栈使得这种名称匹配可以只通过分析静态文本就可以实现。因此静态作用域又被称为“词法作用域”。也就是说在具有词法作用域的语言中名称解析取决于源代码中的位置和词法上下文中的位置静态范围允许程序员将参数、变量、常量、类型、函数等对象引用作为简单的名称替换进行推理。这使得制作模块化代码变得更加容易因为可以隔离地理解本地命名结构。词法作用域中对名称的解析可以在编译时确定也被称为早期绑定。另外即使都是使用词法作用域的工作方式不同语言的作用域规则也是有差别的比如C、JavaScript等语言允许局部变量有“死区”(在子作用域中允许声明和父作用域中同名的变量并且子作用域中的变量声明会覆盖父作用域中的变量声明)而在Java语言中大多数情况下是不允许在子作用域中声明和父作用域中同名的变量的。而且在有的语言中允许在函数中定义函数(支持闭包特性)而有的则不允许。大多数词法作用域语言的词法作用域规则都受到了ALGOL语言的影响遵循层级嵌套的模型我们以一段JavaScript代码为例进行简要的讨论(该例摘自《你不知道的JavaScript 上卷》)js变量作用域在这个例子中有三个逐级嵌套的作用域。为了帮助理解可以将它们想象成几个逐级包含的气泡。气泡1包含着整个全局作用域其中只有一个标识符foo 。气泡2包含着foo 所创建的作用域其中有三个标识符a 、bar 和b 。气泡3包含着bar 所创建的作用域其中只有一个标识符c 。作用域气泡由其对应的作用域块代码写在哪里决定它们是逐级包含的。动态作用域目前来说只有少部分的语言使用动态作用域规则比如Bash脚本、Lisp语言和一些模板语言。这时候“程序的一部分”是指“部分运行时间(执行期间的时间段)”。对于动态作用域全局标识符是指与最新环境关联的标识符。从技术上讲这意味着每个标识符都有一个全局绑定堆栈。引入具有名称的本地变量会将绑定推送到全局堆栈(可能为空)当控制流离开作用域时该变量将弹出该堆栈。这在编译时无法完成因为绑定堆栈仅在运行时存在这就是为什么这种类型的范围范围称为动态范围。也就是说在具有动态作用域的语言中名称解析取决于遇到由执行上下文或调用上下文确定的名称时的程序状态动态范围迫使程序员预测调用模块代码的所有可能的动态上下文分析起来会比较困难。动态作用域的名称解析通常只能在运行时确定因此称为后期绑定(动态绑定)。使用C语言中的预编译指令模拟动态作用域在现代语言中预处理器的宏扩展是事实上动态作用域的一个关键示例。例如C语言中的宏编译指令#define它提供给编译之前运行的预编译器使用只用来转换源代码而不解析名称当时当其定义的宏被展开到源代码中之后其中的名称被解析就像动态范围一样。如下C语言代码1#define ADD_A(x) x  a23void add_one(int *x) {4const int a  1;5*x  ADD_A(*x); // 当宏被展开的时候这行代码变成了 *x  *x  a; 6}  上面的宏中访问了一个表示符a而在*x ADD_A(*x)这行代码被展开之后就变为了*x *x a可以看出其访问到的正是局部变量a这时候对a的访问就和调用ADD_A(x)这个宏的地方有关系了这和动态作用域的行为是非常相似的。同时我们也可以看出对于拥有动态作用域的语言来说对一个子程序的定义需要依赖使用它的上下文这对提高程序的模块化是非常不利的。常量上文中我们聊完了变量(左值)这篇文章中就顺带着介绍一下常量吧。什么是常量呢常量应该具有如下的特征常量具有值常量是只读的即我们只能读取其值而不能修改这个值常量的值在编译期就是可以确定的如果要完全符合上面的特征我们发现只有字面值才能被称为常量。但是有时候我们又需要一种这样的变量它的值在运行时才能被计算出来在它的整个生命周期中只能被赋值一次也就是说其被初始化之后就不能再作为左值使用了。这种机制需要语言提供支持例如C语言中的const变量、Java中的final变量等等。对于这样的变量其本质上还是一个左值但是其符合我们上面的约束——初始化后不能再进行赋值操作所以我们称之为不可变左值。总的来说语言中的常量包括两种类型一种是字面值这是真正意义上的常量另一种是不可变左值不可变左值需要语言提供支持。不可变左值不可变左值还涉及很多的细节比如一些不可变左值的值在编译阶段可能就是可以计算的这个时候语言的编译器可能会对其进行宏编译比如Java中的常量变量对于这些细节问题我们到了具体语言中再具体情况具体分析吧。总结在这篇文章中我们简单介绍了高级语言如何使用数据类型和变量来帮我们进行访存操作而数据类型有动、静之分同时也有其他的维度来描述一门语言的类型系统的特征我们在这篇文章中并没有对这部份内容进行讨论下一篇文章《类型系统》就是对这部份内容的补充。这篇文章中的主角应该是左值有左必有右而我们这篇文章中并没有对右值进行讨论在下下篇文章《函数、表达式和语句》中将会补充对右值的讨论。同时这篇文章比较长感谢你耐心读完。本人深知技术水平和表达能力有限如果文中有什么地方不合理或者你有其他不同的思考和看法欢迎随时和我进行讨论(laomst163.com)。
http://www.yutouwan.com/news/181953/

相关文章:

  • 房屋 哪个网站做的最好公司网站运营维护单位
  • 道滘东莞网站建设网站推广规范
  • 徐闻网站建设公司河南新冠防控
  • 网站组成费用常见的网络推广方式有哪些
  • 生物科技网站模板游戏网站logo制作
  • 关于asp_sql网站开发的书籍设计网页的步骤是什么
  • 848给我做一下88网站建设一个网站流程图
  • 网页设计优秀作品展示旅游网站优化方案
  • 东莞网站建设信科分公司济南电视台鲁中频道莱芜新闻
  • 做暑假工的网站贵阳市建设厅网站
  • 扬中网站推广托管分栏式网站
  • 请问哪个网站可以做二类学分模板网站建设平台
  • 网站设计建网站亚马逊跨境电商平台介绍
  • 交易 网站备案建筑设计网站免费
  • 搬家公司网站制作建什么类型网站好
  • 常用的电子商务网站开发技术北京专业推广公司
  • dz门户网站模板下载免费seo培训
  • 做智能网站平台自己做的网站能上传到凡科吗
  • 一个网站建设花了10万元百度竞价价格查询
  • 网站群发软文软件淘宝运营自学教程入门
  • 南京做企业网站公司网站添加icp备案号
  • 需要建设网站的网站中的二级菜单怎么做23
  • 电脑怎样做轰炸网站安徽做网站哪家好
  • 校园网站建设用什么软件写wordpress cms plugin
  • 做外贸不能访问国外网站怎么办wordpress花钱吗
  • 访问国外网站很慢wordpress ie8不兼容
  • wix如何做网站wordpress 调用分类列表
  • 公司网站 自己是空间服务商 cms珠海网站设计培训学校
  • 我做微信淘宝客网站招聘网站建设方案模板下载
  • 建设定制网站tp框架做餐饮网站