Size: px
Start display at page:

Download ""

Transcription

1 华中科技大学计算机科学与技术学院 编译原理 大型项目训练报告 题目 : 一个面向对象的类 java 的编译器 的设计与实现 专业 : 计算机科学与技术 班级 : 计科卓工 1201 学号 : U 姓名 : 朱凡 成绩 : 指导教师 : 徐丽萍 完成日期 : 2015 年 7 月 7 日

2 目录 一. 实验概述 实验要求 实验完成情况概述 分工情况...3 二. 作用域的处理 函数作用域 函数作用域生成汇编代码 局部作用域 三. 变量和常量的定义 全局变量与静态变量的定义 局部变量的定义 临时变量的定义 成员变量的定义 字符串常量的定义 其他常量的定义...23 四. 普通变量和普通函数的使用 普通变量的使用 普通函数的调用...27 五. 成员变量与成员函数的使用以及多态的实现 成员变量的使用 成员函数的调用以及多态的实现 六. 生成汇编代码 new 语句生成汇编 return 语句生成汇编 七. 生成可执行程序 八. 实验感想... 39

3 一. 实验概述 1.1 实验要求 项目内容 : 自定义一个语言的文法规则, 或采用 C 语言 ( 或 C++ 语言或 C# 语言或 JAVA 语言 ), 利用课程实验的结果构造一个 SC 语言的编译程序甚至集成开发环境 任务要求 : 收集与阅读相关文献资料, 确定采用的技术线路, 设计系统方案, 完成系统实 现 ; 提交标准格式打印的 编译原理大型项目训练报告 和包括 编译原理大型 项目训练报告 编译器源程序 编译器目标程序和测试模拟数据文件之光盘 语言要求 : SC 语言可以是 C 语言的子语言, 要求至少包含的语言成分如下, 具体语言范围自行确定 ; 1. 数据类型至少包括 char 类型 int 类型和 float 类型 2. 基本运算至少包括算术运算 比较运算 自增自减运算和复合赋值运算 3. 控制语句至少包括 if 语句和 while 语句 1.2 实验完成情况概述 在本次课程设计中, 我和孟嘉豪同学一起实现了一个 SimpleJava 编译器 我们在 C 语言语法的基础上进行了一些修改, 最终实现了 SimpleJava 的语法, 具体语法如下所示 : 1. 去掉了 C 语言中的指针 2. 去掉了结构和联合 3. 去掉了枚举类型 4. 数组还没来得及实现 5. 增加了类, 可以单继承, 可以多态 成员函数的多态更加类似于 java, 而非 C++, 所有的成员函数都是虚函数, 不需要 virtual 关键字 所有的成员函数和成员变量都是 public, 继承也是 public, 不支持 private 和 protected 6. 普通变量可以使用 static 关键字, 但是成员变量和成员函数不支持 static 关键字 7. 类没有构造函数和析构函数, 对象通过 new 关键字来构造, 通过 delete 关键 1

4 字来释放内存 8. 不支持重载 9. 在 SimpleJava 的程序中可以直接调用 C 语言的库函数, 所以输出可以直接使用 printf 10. 实现了 if 和 while, 没有实现 for 和 switch 11. 浮点运算的支持并不完善 就 SimpleJava 的语法, 我有三个地方需要额外说明 : 1. 关于函数重载的问题函数重载的实现其实是很简单的, 只要在最终的汇编代码中改一改函数的名字即可 但是我们没有实现重载, 这主要是因为我们的编译器最终产生的目标文件要和 C 语言的库函数兼容 如果实现重载的话, 那么最终汇编代码中函数的命名无法兼容 C 语言, 最终会导致没有办法在 SimpleJava 中调用 C 的库函数 2. 关于库函数的问题一般来说, 每一种语言都需要附带一个相应的标准函数库 比如说 C 语言有 glibc,c++ 有 STL 等等 标准函数库封装了一些系统调用, 比如说输入输出, 方便了用户的使用 但是, 由于 SimpleJava 的函数调用方式和 C 语言是兼容的, 所以不需要额外为它去写一个标准函数库, 只需在 SimpleJava 中直接使用 C 语言的库函数, 然后汇编得到目标代码后与 glibc 链接即可 这大大的减轻了我们的工作量 3. 浮点运算的问题对于 gcc 来说,32 位版的 gcc 的浮点运算是通过用整数运算模拟实现的, 这主要是为了兼容 386CPU(386 是没有浮点运算单元的, 浮点预算单元是从 486 以后才开始有的 ), 而 64 位版的 gcc 则是直接使用浮点指令来进行浮点运算, 这毫无疑问大大加快了浮点运算的速度 而对于我们的 SimpleJava 编译器来说, 虽然最终生成的是 32 位的汇编, 但是浮点运算确实用浮点指令实现的, 毕竟我们不用考虑 386 的不兼容问题 但是, 由于我们的中间代码没有设计好, 所以对浮点运算的支持还是有问题 ( 因为浮点寄存器是栈式寄存器, 只能对栈顶的寄存器进行操作, 和普通寄存器不一样 ) 最终, 源文件经过我们的编译器处理后, 会生成汇编文件 out.s 我们使用的是 X86 平台上的 32 位汇编 然后, 使用 gnu 的汇编器 gas 处理汇编文件, 生成目标代码 out.o, 最后用连接器 ld 将 out.o 和 C 语言标准库 glibc 链接即可生成最终的可执行文件 2

5 1.3 分工情况 编译器的标准工作流程如下所示 : 词法分析 语法分析 表格管 理 语义分析 出错处 理 中间代码生成 代码优化 目标代码生成 以上是编译器的标准工作流程, 我们的 SimpleJava 编译器对这个过程做了一 些修改, 工作流程如下所示 : 3

6 Lex 进行词法分 析 Yacc 进行语法分 析, 生成语法树 遍历语法树, 生成符号表数, 同时, 在符号表中插入中间代码 遍历符号表树, 生 成汇编代码 如上所示, 在整个编译过程中, 有两棵树是最为重要的, 贯穿了整个编译过程 : 一棵是 yacc 进行语法分析后生成的语法树, 另一棵是以代码中的作用域为节点, 包含了符号和中间代码的符号表树 关于上述过程, 我有以下几点需要额外说明 : 1. 关于符号表在 SimpleJava 的工作流程中, 只需遍历一遍语法树, 便可同时生成符号表树, 符号表树中的符号, 以及中间代码 至于这是如何做到的, 我将在后面具体叙述 2. 关于语义分析在 yacc 程序中所定义的语法规则其实是相当宽泛的, 如果一个源程序成功的通过了语法分析, 生成了语法树, 那么这个源程序还是不一定正确的, 比如下面这条声明语句 : Int float a; 4

7 这条语句是可以通过语法分析的, 但它依旧还是错误的 所以当源代码通过语法分析生成语法树后, 还需进一步遍历语法树, 对语法树的结构进行检验, 这就是语义分析 在 SimpleJava 的工作流程中, 我们并不会单独的去为语义分析去遍历一边语法树, 而是将语义分析的工作糅杂在了生成符号表和中间代码的过程中 正如前面所说, 我们只需遍历一遍语法树便完成了所有的工作 3. 关于出错处理 我们有单独用于处理错误信息输出的类 LogiMsg, 如下图所示 : 但是却没有一个统一的错误处理表, 错误处理语句分散在整个程序中 这也是 我们不足的一个地方 不过这也是没有办法的事, 毕竟没有做之前我们根本不知 道可能会报怎样的错误 5

8 分工情况 : 由于编译器这个东西具有高度的整体性, 前后过程之间衔接密切, 并不好进行模块的划分, 所以我和孟嘉豪的工作有很多重叠的地方 不过总的来说, 孟嘉豪做的是前端, 我做的是后端 我认为我的工作是如何将 SImpleJava 语言和汇编语言对应起来, 比如说如何为不同类型的变量分配空间, 如何处理普通函数和成员函数, 如何使用成员变量, 如何实现多态 这些其实都要在符号表中进行反映, 最后在遍历符号表时生成对应的汇编语句 我在实验报告接下来的部分将对这些问题进行重点阐述 另外, 我不会按照编译器的工作流程去写这个实验报告 ( 比如说, 先写符号表, 再写汇编的生成 ), 我会分成不同的专题去写, 每一个专题阐述一个重要的问题, 每个专题都会包含编译器工作的不同阶段, 我觉得这样写思路会比较清晰 6

9 二. 作用域的处理 SimpleJava 语言是一个面向对象的语言, 但是首先它一定是一个结构化的语言, 整个源程序都是由一层一层的作用域组成, 所有的可执行语句都一定存在于某个作用域中, 不存在游离的可执行语句 在整个源程序的结构中, 最上层的是全局作用域, 然后是类作用域和和普通函数作用域, 类作用域下面还有成员函数作用域, 然后最下面则是局部作用域, 也就是代码块 整个作用域的结构如下所示 : SCOPE_GLOBAL SCOPE_GLOBALFUNC SCOPE_CLASS SCOPE_CLASSFUNC SCOPE_LOCAL 对于全局作用域来说, 它里面不能有可执行语句, 只有声明语句, 而在全局作用域声明的变量则是全局变量 我把全局变量放在汇编的 bss 段, 然后使用变量名进行访问 对于类作用域来说, 它包括成员变量和成员函数作用域 其实类在汇编代码里并没有直接对应的部分, 因为成员变量不需要在汇编代码里进行额外的表示, 只需在生成对象时预留空间即可, 而成员函数则是当做普通函数进行处理, 只不过命名有所不同 下面我将着重阐述函数作用域和局部作用域 7

10 2.1 函数作用域 前面已经说到, 函数分为成员函数和普通函数, 这两者具有不同的作用域类型 但是对他们的处理基本上是一样的, 所以我把他们放在一起来说 最终生成的汇编代码分为三个段 : 1.data 段 : 放字符串常量 2.bss 段 : 放全局变量和静态变量 3.text 段 : 也就是代码段, 放的是汇编指令 最终, 函数就放在代码段中, 每一个函数对应代码段的一个标号以及该标号后面的语句 例如, 现在有函数 : int func() int a; Int b; a=b+1; return a; 那么他在代码中对应的汇编代码就应该是 : func: pushl %ebp... 在比如说现在有成员函数 : class a int func() int a; Int b; a=b+1; return a; 8

11 那么他在代码段中对应的汇编代码就应该是 : A_func: pushl %ebp... 从上面的例子中, 可以看出两点 : 1. 对于普通函数, 它在汇编中对应的标签名就是函数名, 这同时也是 C 语言的命名规则 在 SimpleJava 编译器中, 函数的命名规则和参数的传递方式都和 C 语言是一样的 这样, 在 SimpleJava 的源程序中就可以直接调用 C 语言的库函数 ( 比如说 printf) 来进行输入输出 2. 对于成员函数, 它在汇编中对应的标签名是类名加下划线加函数名 从例子中 可以看出, 成员函数和普通函数的在汇编中的处理是一样的, 类在汇编代码中并 没有直接的对应关系 当然, 也可以说类反应在了成员函数的名字上 对于下面的函数 : int func(int c, int d) int a; Int b; a=b+1; return a; 它在符号表中生成了两个作用域节点 : 一个普通函数作用域和一个局部作用域, 函数作用域是局部作用域的父节点 ( 符号表的结构由孟嘉豪进行说明, 我在这里就不赘述了 ) 前面已经说过, 符号表是在遍历语法树的过程中生成的, 当遍历语法树时碰到 T_CFUNCDEF_DECTIONSFS_DECTOR_COMPSTM 类型的节点, 就知道这里是一个函数的定义, 然后就在符号表中添加一个函数作用域节点, 代码如下 : Scope::pushScope(Scope::s_curScope, tmpscope); Scope::setCurScope(tmpScope); 至于说局部作用域, 在 SimpleJava 中, 一个花括号就是一个局部作用域, 遍 历语法树时, 碰到一个花括号节点, 即类型为 T_CCOMPSTM_STMLIST 的节点时, 9

12 就会在符号表中添加一个局部作用域节点 也就是说, 一个函数至少对应了一个函数作用域和一个局部作用域 其实可以看到, 函数作用域中存放的仅仅只有该函数的参数, 局部变量以及可执行语句都放在局部作用域中 函数作用域生成汇编代码 函数作用域中存放的符号仅仅只有该函数的参数, 并且没有存放中间代码, 而函数参数属于局部变量, 应在栈中为其分配空间 但是函数作用域对应的汇编代码中是不需要为其分配空间的, 因为在调用函数时会将参数压栈, 此时就已经为函数的参数分配了空间 遍历符号表树生成汇编代码时, 若碰到函数作用域, 只需按照前面的命名规则生成对应的标签即可, 同时, 还需在最后加上 ret 语句, 代码如下所示 : else if (scope_t->scopetype == Scope::SCOPE_GLOBALFUNC) string a = scope_t->getscopename() + ":\n"; addtotextsectionlist(a); vector<scope *>::iterator childitr; for (childitr=scope_t->childs.begin(); childitr!=scope_t->childs.end(); childitr++) Asm::printScopeAsm(*childItr); addtotextsectionlist("\tret\n"); else if (scope_t->scopetype == Scope::SCOPE_GLOBALFUNCCHAN) string a = scope_t->getscopename() + ":\n"; addtotextsectionlist(a); 10

13 vector<scope *>::iterator childitr; for (childitr=scope_t->childs.begin(); childitr!=scope_t->childs.end(); childitr++) Asm::printScopeAsm(*childItr); addtotextsectionlist("\tret\n"); else if (scope_t->scopetype == Scope::SCOPE_CLASSFUNC) if (scope_t->parent == NULL) LogiMsg::logi("error in printscopeasm there is no class \n"); return ; string a = scope_t->parent->getscopename() + "_" + scope_t->getscopename() + ":\n"; addtotextsectionlist(a); vector<scope *>::iterator childitr; for (childitr=scope_t->childs.begin(); childitr!=scope_t->childs.end(); childitr++) Asm::printScopeAsm(*childItr); addtotextsectionlist("\tret\n"); 11

14 2.2 局部作用域 在 SimpleJava 语言中, 局部作用域无处不在, 一对花括号就是一个局部作用域 它可以是函数定义的函数体, 也可以同 if 或者是 while 语句一起使用 局部作用域在语法树中对应的节点类型是 T_CCOMPSTM_STMLIST 所有的局部作用域所对应的汇编代码都是一样的 在进入局部作用域时, 需要保存 ebp 指针, 然后以 ebp 指针为局部变量访问的起始点, 然后移动 esp 指针, 为局部变量留出空间 比如某一局部作用域的局部变量的空间为 12 字节, 那么进入该作用域时对应的汇编代码为 : pushl %ebp movl %esp, %ebp subl $12, %esp 我使用函数 genfuncstart 来生成进入局部作用域时所需要的汇编代码, 如下所示 : void Asm::genFuncStart(Scope *scope_t) //textsection << "\tpushl %ebp\n"; //textsection << "\tmovl %esp, %ebp\n"; //textsection << "\tsubl $" << scope_t->totalbytesize-scope_t->curstartoffset << ", %esp\n"; addtotextsectionlist("\tpushl %ebp\n"); addtotextsectionlist("\tmovl %esp, %ebp\n"); string a; stringstream ss; string b; ss << scope_t->totalbytesize-scope_t->curstartoffset; ss >> b; a = "\tsubl $" + b + ", %esp\n"; addtotextsectionlist(a); 在离开局部作用域时, 则需要回复 esp 指针, 释放为局部变量预留的空间, 然后再回复 ebp, 汇编代码如下 : movl %ebp, %esp popl %ebp 12

15 我使用函数 genfuncend 来生成进入局部作用域时所需要的汇编代码, 如下所示 : void Asm::genFuncEnd(Scope *scope_t) /*textsection << "\tmovl %ebp, %esp\n"; textsection << "\tpopl %ebp\n";*/ addtotextsectionlist("\tmovl %ebp, %esp\n"); addtotextsectionlist("\tpopl %ebp\n"); // addtotextsectionlist("\tsubl $4, %esp\n"); 13

16 三. 变量和常量的定义 在 SimpleJava 的源程序中, 存在着各种各样的量, 有变量也有常量 变量可以分为 : 全局变量, 静态变量, 局部变量, 临时变量, 成员变量 常量可以分为字符串常量, 整形常量, 字符串常量等等 下面我将逐一阐述碰到这些量时如何在符号表中表示它们以及它们对应的汇编代码是怎样的 3.1 全局变量与静态变量的定义 遍历语法树时, 若遇到类型为 T_CDECTION_DECTIONSFS_INITDECTORLIST 的节 点, 则为变量的定义 此时, 若当前作用域为全局作用域, 则说明该变量为全局 变量, 需要对该变量做标记, 然后加入符号表, 代码如下所示 : if (Scope::s_curScope==Scope::s_globalScope) tmpsymbol->isglobal=true; 若是静态变量, 由于最后遍历符号表时可以通过变量类型进行判断, 所以无需 做额外的标记 前面已经说过, 最终的汇编代码分为 3 个段, 全局变量和静态变量全部放在 bss 段里 比如说现在有全局变量 a 和静态变量 b, 如下所示 : int a; int main() static int b; 那么最终生成的汇编代码应该是这样的 :.section.bss.lcomm a, 4.lcomm b, 4 这段代码的意思是在 bss 段中给 a 和 b 各留 4 字节的空间 当最终遍历符号表生成汇编时, 首先遍历全局作用域的符号, 在汇编中生成全 局变量, 然后在遍历各个局部作用域前, 首先遍历该作用域的符号表, 在汇编中 14

17 生成静态变量, 代码如下所示 : 生成全局变量 : list<symbol *>::iterator symitr; stringstream ss; for (symitr=scope::s_globalscope->symbolseqlist.begin(); symitr!=scope::s_globalscope->symbolseqlist.end(); symitr++) string a; ss.clear(); string b; ss << (*symitr)->getbytesize(); ss >> b; a = "\t.lcomm " + (*symitr)->getsymbolname() + ", " + b + "\n"; addtobsssectionlist(a); 生成静态变量 : for (staitr=scope_t->symbolseqlist.begin(); staitr!=scope_t->symbolseqlist.end(); staitr++ ) if ((*staitr)->typeclass.storagetype & TypeClass::STOR_STATIC) string a; ss.clear(); string b; ss << (*staitr)->getbytesize(); ss >> b; a = "\t.lcomm " + (*staitr)->getsymbolname() + ", " + b + "\n"; addtobsssectionlist(a); 15

18 其实, 局部变量和静态变量也可以放在数据段 ( 即 data 段 ) 中, 但是, 我还是把他放在了 bss 段 这是因为, 若放在 bss 段, 那么最终生成可执行文件时, 该数据不会占用空间,bss 段的空间在运行时由操作系统分配 这样一来, 便可以减少可执行文件的大小 3.2 局部变量的定义 在早期的 C 语言中, 局部变量的定义一定要在可执行语句之前, 我们的 SimpleJava 沿用了这种做法 这里的局部变量包含了函数的参数 局部变量的内存空间分配在栈中 在符号表中定义局部变量时, 最重要的是记录该局部变量的偏移量, 因为访问局部变量时是通过偏移量来访问的 由于存在嵌套的问题, 即在内层的作用域中可以访问外层的局部变量, 所以在计算偏移量时一定要考虑这个问题 那么偏移量的计算应当从哪里开始呢? 毫无疑问应当从函数定义开始 因为整个 SimpleJava 的源程序都是由一个一个函数组成, 并且函数外面没有局部变量, 只有全局变量 在描述作用域的 Scope 类中, 我引入了两个变量 curstartoffset 和 totalbytesize curstartoffset 记录该作用域的起始偏移量,totalByteSize 等于 curstartoffset 加上该作用域的所有局部变量的大小的和 对于函数作用域来说,curStartOffset 和 totalbytesize 初始值都为 0, 因为它没有外层作用域 而局部作用域的 curstartoffset 和 totalbytesize 的初始值则需要通过它的上层作用域的 totalbytesize 计算得到 下面我将通过一个例子来说明计算方法 有这样一个函数 : int func(int a, int b) char c; while (1) int d; 这样的一个函数一共有三层作用域 : 最外层的函数作用域, 然后是两层局部作 用域 进入函数时, 栈的分布是这样的 : 16

19 b a esp eip 然后再进入下层的局部作用域, 栈变成了这样 : b a eip esp ebp c ebp 然后再进入下层作用域, 栈变成了这样 : 17

20 b a eip ebp c ebp ebp esp d 从上面的例子中, 我们可以得到两点结论 : 1. 下层作用域的 totalbytesize 和 curstartoffset 等于上层作用域的 totalbytesize 加 4, 这是因为没进入一个作用域都要保存 ebp 指针 2. 每一层作用域中, 都是以 ebp 指针为基址来访问局部变量 确定了每个作用域的 totalbytesize 和 curstartoffset 后, 定义每个变量时 就可以确定该变量的偏移量了 : 首先将该作用域的 totalbytesize 增加变量的大 小, 然后将 totalbytesize 的值赋给该变量的偏移量 代码如下所示 : Scope::s_curScope->incTotalByteSize(tmpsymbol->getByteSiz e()); tmpsymbol->setoffset(scope::s_curscope->gettotalbytesize() ); 特别的, 对于函数作用域中的 Symbol( 即函数参数 ) 的偏移量的计算, 有两个地方需要注意 : 1. 函数参数压栈时是倒着压的, 所以计算偏移量时要倒着算 2. 对于普通函数, 最后 totalbytesize 的值要额外加上 4, 因为调用函数时会自动将 eip 压栈 而对于成员函数, 则最后 totalbytesize 的值要额外加上 8, 因为调用成员函数时还需要将 this 指针压栈 18

21 3.3 临时变量的定义 当调用函数时, 需要将函数的参数的值作为临时变量保存在堆栈中, 方便传递参数时压栈 比如下面这个调用 : a=func(c,b+d); 那么就需要两个 int 型的临时变量 其实临时变量和局部变量是一样的, 它们的偏移量的算法完全是相同的 只不过定义临时变量时, 有可能已经定义了下层作用域, 所以应当修改下层作用域中的局部变量的偏移量, 将它们全部加上该临时变量的大小, 代码如下所示 : void Scope::scopeOffsetChange(Scope *scope_t, int inc_t) if (scope_t) vector<scope *>::iterator childitr; for (childitr=scope_t->childs.begin(); childitr!=scope_t->childs.end(); childitr++ ) (*childitr)->curstartoffset+=inc_t; (*childitr)->totalbytesize+=inc_t; list<symbol *>::iterator symitr; for (symitr=(*childitr)->symbolseqlist.begin(); symitr!=(*childitr)->symbolseqlist.end(); symitr++) (*symitr)->offset+=inc_t; Scope::scopeOffsetChange((*childItr), inc_t); 19

22 3.4 成员变量的定义 对象的引用通过偏移量来访问成员变量, 而计算成员变量的偏移量主要需要考虑的是类之间的继承关系 如果一个类没有父类, 那么它的 totalbytesize 的初始值为 0, 然后每增加一个偏移量,totalByteSize 增加对应的大小 若一个类有父类, 那么它的 totalbytesize 的初始值等于父类的 totalbytesize 的值 这样, 就可以保证子类可以访问父类的成员变量 当然, 若子类的变量和父类的变量同名, 那么子类的变量会覆盖父类的变量 例如现在有两个类 : class A int a; int b; class B char c; int d; 那么偏移量如下表所示 : 变量偏移量 a 0 b 4 c 8 d 7 20

23 3.5 字符串常量的定义 现在有这样一段代码 : printf( %d\n,a); 这里存在字符串常量, 所以需要在符号表和汇编代码中进行表示 在汇编代码中, 符号表放在数据段 ( 即 data 段 ) 中, 并且我还会给每一个字符串常量取一个内部的名字.S1,.S2... 比如上面的字符串, 那么它在汇编代码中的表示就是 :.section.data.s1:.asicz %d\n 这样的话就可以通过名字来访问字符串常量 比如所调用函数时需要将字符 串压栈, 就可以这样 : pushl $.S1 至于将字符串常量加入符号表, 就十分简单了, 直接加入常量的链表即可 代码如下所示 : Symbol *rst = Scope::s_globalScope->resolveSymbol(token, Symbol::SYMBOL_STRING_LITERAL); if (NULL == rst) rst = new Symbol(Symbol::SYMBOL_STRING_LITERAL); static int s_string=0; s_string++; string idstring; string tmpname = ".S"; stringstream ss; ss << s_string; ss >> idstring; tmpname +=idstring; rst->setsymbolname(tmpname); rst->addsymbolvalue(token); rst->typeclass.settypesftype(typeclass::sf_int); rst = (0 == Scope::s_curScope->defineSymbol(rst))? NULL : rst; 21

24 s_context->clearcontext(); s_context->tmpoptype = ItmCode::OPR_SYMBOL; s_context->tmpexpsymbol = rst; 在遍历符号表树时, 首先就要将所有的字符串常量转化为汇编代码, 对应的代 码如下所示 : for (constitr=scope::s_constmap.begin(); constitr!=scope::s_constmap.end(); constitr++) if (constitr->second->symboltype==symbol::symbol_string_lite RAL) if (constitr->second->symbolvalue.size()!= 1) LogiMsg::logi("error in printallasm, the size of symbolvalue is not 1\n"); return ; string a = constitr->second->getsymbolname() + ":\n\t.asciz " + constitr->second->symbolvalue.at(0) + "\n"; addtodatasectionlist(a); 22

25 3.6 其他常量的定义 对于整型常量和字符常量, 遍历语法树时若遇到它们直接加入符号表即可 又因为是常量, 所以不需要为它们分配空间, 在汇编代码中可以直接拿来用 例如 : 使用整数 : movl $0, %eax 使用字符 : movl $ a, %eax 23

26 四. 普通变量和普通函数的使用 本节我将阐述如何在汇编中使用普通变量和调用普通函数 成员变量和成员 变量的使用将放到下一节 4.1 普通变量的使用 如果是使用全局变量或者是静态变量, 由于它们都放在 bss 段, 所以可以直接通过名字来访问 例如现在有全局变量 a 和静态变量 b: int a; int main() static int b; 那么最终生成的汇编代码应该是这样的 :.section.bss.lcomm a, 4.lcomm b, 4 访问 a 和 b 的汇编代码是这样的 : movl a, %eax movl b, %ebx 生成汇编的代码 : if (symbol_t->typeclass.storagetype & TypeClass::STOR_STATIC) symstr = symbol_t->getsymbolname(); else if (symbol_t->isglobal) symstr = symbol_t->getsymbolname(); 24

27 如果变量是局部变量和临时变量, 则它们都放在栈中 需要通过偏移量来访问 在第三节中, 我已经叙述了栈的结构 可以看到, 每一个域中, 都是以 ebp 指针为基地址进行访问 对于没一个 Symbol, 都有一个偏移量属性 :offset 当前作用域的 curstartoffset 减去该变量的 offset 就可以得到该变量相对于 ebp 指针的偏移量 比如现在有局部变量 t: while(1) int t; t=1; t 所在的局部作用域的 curstartoffset 为 4,t 的 offset 为 8, 那么 t 相对于 ebp 指针的偏移量就是 -4, 访问 t 的汇编代码 : mvol $1, -4(%ebp) 可以看到, 这个地方使用的是寄存器间接寻址的寻址方式 对于局部变量的访问, 还有一点很重要, 那就是内层作用域访问外层变量的情 况 此时存在同名变量覆盖的问题, 比如下面这段代码 : Int func() int a; While (1) Int a; Int b; a=1; 当访问局部变量 a 时, 实际上访问的是内层的 a 也就是说内层的变量覆盖了外层的同名变量 要做到这一点, 只需在查找变量时做一些处理即可 查找变量时, 先在当前域中查找, 若当前域中查找不到, 则在 parent 域中查找, 代码如下所示 : 25

28 Symbol* Scope::searchDownUpSymbolVarMap(Scope *curscope_t, const string& symbolname_t) if (NULL == curscope_t) return NULL; Symbol *result = curscope_t->searchsymbolvarmap(symbolname_t); if (NULL!= result) return result; if (NULL == result) if ( (Scope::SCOPE_CLASS == curscope_t->scopetype) && (NULL!= curscope_t->superclass) ) result = searchdownupsymbolvarmap(curscope_t->superclass, symbolname_t); if (NULL!= result) return result; if (NULL!= curscope_t->parent) result = searchdownupsymbolvarmap(curscope_t->parent, symbolname_t); if (NULL!= result) return result; return NULL; 26

29 这里有一点需要注意 : 无论访问哪一个作用域的局部变量, 偏移量都等于访问该变量的作用域的 curstartoffset 减去该变量的 offset, 生成访问汇编代码的代码如下 : else stringstream ss; ss << scope_t->curstartoffset-symbol_t->offset << "(%ebp)"; ss >> symstr; 4.2 普通函数的调用 调用普通的函数一共有五个步骤 : 参数压栈, 保护现场, 根据函数名调用函数, 清理栈中的变量, 恢复现场 比如现在有一个声明如下的函数 : int func(int a, int b); 现在需要调用这个函数 : c=func(2, 4); 那么调用函数的汇编代码 : pushl -4(%ebp) pushl -8(%ebp) Movl %ebx,.bxbuff Call func Movl.bxbuff, %ebx addl $8, %esp 27

30 首先是函数参数压栈 对于 C 语言来说, 若是生成 32 位的汇编, 那么参数是通过栈来传递, 并且是倒着压栈的 所以这里应当先压 4 再压 2. 前面已经说过, 函数参数作为临时变量保存在栈中, 所以访问函数参数和访问临时变量是一样的, 都是寄存器间接寻址 然后是保护现场 保护现场就是在调用函数前将一些寄存器的值保存起来, 然后函数返回后在恢复它们的值 在我们生成的汇编代码中, 只需要保存 ebx 寄存器 保护现场可以将寄存器保存在栈中, 也可以保存在其他段中 我选择将寄存器保存在 bss 段中 因为若是将寄存器保存在栈中, 会使临时变量的偏移量发生变化 故要在 bss 段中为 ebx 寄存器预留空间, 汇编代码如下所示 :.section.bss.lcomm.bxbuff, 4 然后是函数的调用, 直接 call 函数名即可 最后来说一说清楚参数所占用的栈空间 在压入参数前, 栈中的数据是这样的 : esp 然后压入参数后, 栈空间变成了这个样子 : 4 esp 2 28

31 最后调用函数, 然后函数返回后, 栈还是这个样子 现在, 参数已经没用了, 但是还是存在于栈中, 所以需要将 esp 指针向上移动 8 个字节, 清空堆栈, 汇 编如下 : addl $8, %esp 生成函数调用的汇编的代码 : int bytesize=0; if (code_t->t2 == ItmCode::OPR_ARGLIST) bytesize = Asm::genPushArgu(code_t->v2, false, scope_t, ""); addtotextsectionlist("\tmovl %ebx,.bxbuff\n"); string a = "\tcall " + ((Scope *)(code_t->v1))->getscopename() + "\n"; addtotextsectionlist(a); if (code_t->t2 == ItmCode::OPR_ARGLIST) string a; stringstream ss; string b; ss << bytesize; ss >> b; a = "\taddl $" + b + ", %esp\n"; addtotextsectionlist(a); addtotextsectionlist("\tmovl.bxbuff, %ebx\n"); 29

32 五. 成员变量与成员函数的使用以及多态的实现 本节主要叙述如何使用成员变量与成员函数, 以及如何使用多态 在最开始, 我要首先叙述一下为一个类的实例申请空间后, 如何分配空间 比如说有这样的一个类 : class A int a; int b; int func1() int func2() 现在有一个类 A 的实例 : class A t=new A(); 为 t 分配空间后, 首先在最前面放的是成员变量 a 和 b, 然后放 func1 和 func2 的地址 空间分布如下所示 : a b... func1 func2 30

33 这里需要注意的是, 为了实现多态, 同一继承链上的所有的类的成员函数的初 始偏移量都要一样 所以, 在一个类中定义一个成员变量后, 它的所有子类的成 员变量的总大小都要增加, 代码如下 : void Scope::scopeIncSuperTotalByte(Scope *scope_t, int inc_t) if (scope_t) if (scope_t->superclass) scope_t->superclass->totalbytesize+=inc_t; Scope::scopeIncSuperTotalByte(scope_t->superClass, inc_t); 5.1 成员变量的使用 要使用成员变量, 首先要找到成员变量 成员变量的查找和普通变量的查找 不太一样 成员变量的查找首先是在本作用域里找, 本作用域里找不到再到 super 作用域 ( 即父类的作用域 ) 中找, 不需要去在上层作用域中找, 代码如下 : Symbol* Scope::resolveSymbolMemVar(Scope* classscope_t, const string &symbolname_t) if (NULL == classscope_t ) return NULL; Symbol *result = classscope_t->searchsymbolvarmap(symbolname_t); if (NULL!= result) return result; else 31

34 if ( (Scope::SCOPE_CLASS == classscope_t->scopetype) && (NULL!= classscope_t->superclass) ) result = resolvesymbolmemvar(classscope_t->superclass, symbolname_t); if (NULL!= result) return result; return NULL; 找到成员变量后, 就可以得到它的偏移量, 然后就可以对他进行访问 成员变量的偏移量是相对于类的实例的指针来说的 这样以来又要分两种情况 : 1. 在成员函数里访问成员变量, 此时 this 指针作为参数压进了堆栈中 首先要将 this 指针赋给 ecx 寄存器 2. 以 a.b 的形式访问成员变量, 类的实例的指针以局部变量的形式存放在栈中 ( 即变量 a), 所以需要把变量 a 移到 ecx 寄存器 无论如何, 现在类的实例的指针都已经移动到了 ecx 寄存器中, 那么就可以根 据偏移量来访问成员变量了, 比如说 : a.b=5; 现在 b 的偏移量是 4, 那么生成的汇编为 : movl $5, 4(%ecx) 和局部变量一样都是采用的寄存器间接寻址, 只不过寄存器从 ebx 变成了 ecx 而已 生成汇编代码的代码为 : 32

35 addtotextsectionlist("\tmovl 8(%ebp), %ecx\n"); stringstream ss; ss << symbol_t->getoffset() << "(%ecx)" ; ss >> symstr; 5.2 成员函数的调用以及多态的实现 成员函数的调用与普通函数的调用是一样的, 都是分为五个步骤, 但是注意, 函数调用时要将 this 指针压栈 而函数调用时并不是直接通过函数的名字来直接调用, 而是通过成员函数的偏移量来间接的调用 正确计算成员函数的偏移量是实现多态的关键 下面我将着重讲述如何计算偏移量 定义一个成员函数时, 首先在父类中查找有无同名的成员函数, 若有, 则子类的成员函数的偏移量等于父类的成员函数的偏移量 若没有, 则子类的成员函数的偏移量要在总偏移量的基础上加 4. 这样, 就保证了同一继承连上的同名成员函数的偏移量相同 偏移量相同, 但是里面存放的函数地址不同, 这样就实现了多态 计算成员函数偏移量的代码如下 ; Scope *tmpvirfunc=scope::s_curscope->resolvememfunbyname(tmpsco pe->getscopename()); if (tmpvirfunc) tmpscope->setfuncoffest(tmpvirfunc->getfuncoffset()); tmpscope->classname = Scope::s_curScope->getScopeName(); else tmpscope->setfuncoffest(scope::s_curscope->gettotalfuncby tesize()); tmpscope->classname = Scope::s_curScope->getScopeName(); Scope::s_curScope->incTotalFuncByteSize(4); 33

36 例如, 现在需要调用成员函数 : a.func() 已知 func 的偏移量为 4, 而 a 的地址已经移动到了 ecx 中, 那么就可以间接 调用 : call *4(%ebx) 生成间接调用汇编的代码 : stringstream ss; string b; ss << offset; ss >> b; a = "\tcall *" + b + "(%ecx)\n"; 34

37 六. 生成汇编代码 由中间代码生成汇编代码大部分是照着葫芦画瓢, 没什么好说的 我这里只说 两条语句, 一条是 new 语句, 一条是如 return 语句 6.1new 语句生成汇编 New 语句用于为对象申请空间, 例如 : Class A a = new A(); 它需要做的工作有 : 为对象申请空间, 然后将成员函数的地址按偏移量移动到 相应的内存位置 内存的申请可以直接调用 C 标准库中的 malloc 函数, 比如下面这个类 : Class A int a; int b; int func(); 假设需要申请 12 字节的空间那么汇编代码 : pushl $12 call malloc addl $4, %esp 现在, 申请的内存的首地址放在了 eax 寄存器中, 然后就可以根据偏移量将 成员函数的地址移动到相应的位置 : movl $A_func, %eax 35

38 生成对应汇编代码的代码为 : Scope *tmpscope = (Scope *)(code_t->v1); string a; stringstream ss; string b; ss << tmpscope->totalbytesize+tmpscope->totalfuncbytesize; ss >> b; a = "\tpushl $" + b + "\n"; addtotextsectionlist(a); addtotextsectionlist("\tcall malloc\n"); addtotextsectionlist("\taddl $4, %esp\n"); for (int i=0; i < tmpscope->totalfuncbytesize; i+=4) Scope *tmpmemfunc = tmpscope->resolvememfunbyoffset(i); if (tmpmemfunc) string a; ss.clear(); string b; ss << i+tmpscope->totalbytesize; ss >> b; a = "\tmovl $" + tmpmemfunc->classname + "_" + tmpmemfunc->getscopename() + ", " + b + "(%eax) \n"; addtotextsectionlist(a); 36

39 6.2return 语句生成汇编 Return 语句只需做两件事 : 恢复 esp 和 ebp 寄存器, 然后返回 但是, 由于 return 语句可能在内层作用域出现, 所以有可能会回复多次 否则 ret 时会找 不到 ip 地址 生成汇编的代码为 : while ((scope_t->scopetype!= Scope::SCOPE_GLOBALFUNC) && (scope_t->scopetype!= Scope::SCOPE_GLOBALFUNCCHAN) && (scope_t->scopetype!= Scope::SCOPE_CLASSFUNC)) Asm::genFuncEnd(scope_t); scope_t = scope_t->parent; string tmpreg =Asm::genReg(((Reg *)(code_t->v3))->regindex, TypeClass::SF_INT); string a = "\tmovl " + tmpreg + ", %eax\n"; addtotextsectionlist(a); addtotextsectionlist("\tret\n"); 37

40 七. 生成可执行程序 生成汇编代码后, 还需要使用 gas 汇编器进行汇编, 然后用 ld 链接最终生成可执行程序 由于生成的是 32 位的汇编, 而操作系统是 64 位, 故需要加一些参数, 命令如下 : as o out.o out.s ld -melf_i386 --dynamic-linker /lib/ld-linux.so.2 out.o -lc 38

41 八. 实验感想 在这次实验中, 我感觉收获还是很多的, 首先我学会了如何去做一个编译器, 这在以前是不可想象的 其次, 整个代码的工程量有一万五千多行代码, 这对于我来说也是一次很好的锻炼 再者, 在这次实验中, 我第一次使用了 git 来进行多人协作 这也是我第一次和其他人一起写代码, 不过, 我认为最重要的收获是对编程语言的结构和多态有了更深刻的了解, 毕竟自己亲手做了一个, 这对我编程水平的提高有很大的帮助 这次实验也有一些不足, 我认为首先符号表设计的有些不合理, 应该将 Scope 也当做 Symbol 来处理, 这样后面的工作可以简化不少 其次就是没有进行代码优化 39

OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数

OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double

More information

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double x) { d

More information

Microsoft PowerPoint - 3. 函数Functionl.ppt [兼容模式]

Microsoft PowerPoint - 3. 函数Functionl.ppt [兼容模式] 函数 Function 如何重用代码 How to reuse code 3 4 = 3*3*3*3 3 4,6 5 : 拷贝 - 粘帖代码 (Copy-paste code) 3 4,6 5,12 10 : 拷贝 - 粘帖代码 (Copy-paste code) Bad! 使用函数 (with a function) 使用函数 (with a function) 使用函数 (with a function)

More information

OOP with Java 通知 Project 3: 3 月 29 日晚 9 点 4 月 1 日上课

OOP with Java 通知 Project 3: 3 月 29 日晚 9 点 4 月 1 日上课 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 3: 3 月 29 日晚 9 点 4 月 1 日上课 复习 Java 包 创建包 : package 语句, 包结构与目录结构一致 使用包 : import restaurant/ - people/ - Cook.class - Waiter.class - tools/ - Fork.class

More information

chap07.key

chap07.key #include void two(); void three(); int main() printf("i'm in main.\n"); two(); return 0; void two() printf("i'm in two.\n"); three(); void three() printf("i'm in three.\n"); void, int 标识符逗号分隔,

More information

OOP with Java 通知 Project 4: 5 月 2 日晚 9 点

OOP with Java 通知 Project 4: 5 月 2 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 5 月 2 日晚 9 点 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double x) { d =

More information

Microsoft PowerPoint - string_kruse [兼容模式]

Microsoft PowerPoint - string_kruse [兼容模式] Strings Strings in C not encapsulated Every C-string has type char *. Hence, a C-string references an address in memory, the first of a contiguous set of bytes that store the characters making up the string.

More information

NOWOER.OM m/n m/=n m/n m%=n m%n m%=n m%n m/=n 4. enum string x1, x2, x3=10, x4, x5, x; 函数外部问 x 等于什么? 随机值 5. unsigned char *p1; unsigned long *p

NOWOER.OM m/n m/=n m/n m%=n m%n m%=n m%n m/=n 4. enum string x1, x2, x3=10, x4, x5, x; 函数外部问 x 等于什么? 随机值 5. unsigned char *p1; unsigned long *p NOWOER.OM /++ 程师能 评估. 单项选择题 1. 下 描述正确的是 int *p1 = new int[10]; int *p2 = new int[10](); p1 和 p2 申请的空间 的值都是随机值 p1 和 p2 申请的空间 的值都已经初始化 p1 申请的空间 的值是随机值,p2 申请的空间 的值已经初始化 p1 申请的空间 的值已经初始化,p2 申请的空间 的值是随机值 2.

More information

Microsoft Word - 新1-12.doc

Microsoft Word - 新1-12.doc 实训 5 面向对象编程练习 实训 5 面向对象编程练习 5.1 实训目的 通过编程和上机实验理解 Java 语言是如何体现面向对象编程基本思想 以及如何创建类 和对象 了解成员变量和成员方法的特性 5.2 实训要求 编写一个体现面向对象思想的程序 编写一个创建对象和使用对象的方法的程序 5.3 实训内容 5.3.1 创建对象并使用对象 1 定义一个 Person 类 可以在应用程序中使用该类 成员属性

More information

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 odps-sdk 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基 开放数据处理服务 ODPS SDK SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基础功能的主体接口, 搜索关键词 "odpssdk-core" 一些

More information

OOP with Java 通知 Project 2 提交时间 : 3 月 14 日晚 9 点 另一名助教 : 王桢 学习使用文本编辑器 学习使用 cmd: Power shell 阅读参考资料

OOP with Java 通知 Project 2 提交时间 : 3 月 14 日晚 9 点 另一名助教 : 王桢   学习使用文本编辑器 学习使用 cmd: Power shell 阅读参考资料 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 2 提交时间 : 3 月 14 日晚 9 点 另一名助教 : 王桢 Email: 51141201063@ecnu.cn 学习使用文本编辑器 学习使用 cmd: Power shell 阅读参考资料 OOP with Java Java 类型 引用 不可变类型 对象存储位置 作用域 OOP

More information

<4D6963726F736F667420506F776572506F696E74202D20332D322E432B2BC3E6CFF2B6D4CFF3B3CCD0F2C9E8BCC6A1AAD6D8D4D8A1A2BCCCB3D0A1A2B6E0CCACBACDBEDBBACF2E707074>

<4D6963726F736F667420506F776572506F696E74202D20332D322E432B2BC3E6CFF2B6D4CFF3B3CCD0F2C9E8BCC6A1AAD6D8D4D8A1A2BCCCB3D0A1A2B6E0CCACBACDBEDBBACF2E707074> 程 序 设 计 实 习 INFO130048 3-2.C++ 面 向 对 象 程 序 设 计 重 载 继 承 多 态 和 聚 合 复 旦 大 学 计 算 机 科 学 与 工 程 系 彭 鑫 pengxin@fudan.edu.cn 内 容 摘 要 方 法 重 载 类 的 继 承 对 象 引 用 和 拷 贝 构 造 函 数 虚 函 数 和 多 态 性 类 的 聚 集 复 旦 大 学 计 算 机 科 学

More information

Microsoft PowerPoint - 5. 指针Pointers.ppt [兼容模式]

Microsoft PowerPoint - 5. 指针Pointers.ppt [兼容模式] 指针 Pointers 变量指针与指针变量 Pointer of a variable 变量与内存 (Variables and Memory) 当你声明一个变量时, 计算机将给该变量一个内存, 可以存储变量的值 当你使用变量时, 计算机将做两步操作 : - 根据变量名查找其对应的地址 ; - 通过地址对该地址的变量内容进行读 (retrieve) 或写 (set) 变量的地址称为变量的指针! C++

More information

Microsoft PowerPoint - 4. 数组和字符串Arrays and Strings.ppt [兼容模式]

Microsoft PowerPoint - 4. 数组和字符串Arrays and Strings.ppt [兼容模式] Arrays and Strings 存储同类型的多个元素 Store multi elements of the same type 数组 (array) 存储固定数目的同类型元素 如整型数组存储的是一组整数, 字符数组存储的是一组字符 数组的大小称为数组的尺度 (dimension). 定义格式 : type arrayname[dimension]; 如声明 4 个元素的整型数组 :intarr[4];

More information

CC213

CC213 : (Ken-Yi Lee), E-mail: feis.tw@gmail.com 49 [P.51] C/C++ [P.52] [P.53] [P.55] (int) [P.57] (float/double) [P.58] printf scanf [P.59] [P.61] ( / ) [P.62] (char) [P.65] : +-*/% [P.67] : = [P.68] : ,

More information

Microsoft Word - ch04三校.doc

Microsoft Word - ch04三校.doc 4-1 4-1-1 (Object) (State) (Behavior) ( ) ( ) ( method) ( properties) ( functions) 4-2 4-1-2 (Message) ( ) ( ) ( ) A B A ( ) ( ) ( YourCar) ( changegear) ( lowergear) 4-1-3 (Class) (Blueprint) 4-3 changegear

More information

软件工程文档编制

软件工程文档编制 实训抽象类 一 实训目标 掌握抽象类的定义 使用 掌握运行时多态 二 知识点 抽象类的语法格式如下 : public abstract class ClassName abstract void 方法名称 ( 参数 ); // 非抽象方法的实现代码 在使用抽象类时需要注意如下几点 : 1 抽象类不能被实例化, 实例化的工作应该交由它的子类来完成 2 抽象方法必须由子类来进行重写 3 只要包含一个抽象方法的抽象类,

More information

OOP with Java 通知 Project 4: 推迟至 4 月 25 日晚 9 点

OOP with Java 通知 Project 4: 推迟至 4 月 25 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 推迟至 4 月 25 日晚 9 点 复习 Protected 可以被子类 / 同一包中的类访问, 不能被其他类访问 弱化的 private 同时赋予 package access class MyType { public int i; public double d; public

More information

untitled

untitled 1 Outline 數 料 數 數 列 亂數 練 數 數 數 來 數 數 來 數 料 利 料 來 數 A-Z a-z _ () 不 數 0-9 數 不 數 SCHOOL School school 數 讀 school_name schoolname 易 不 C# my name 7_eleven B&Q new C# (1) public protected private params override

More information

c_cpp

c_cpp C C++ C C++ C++ (object oriented) C C++.cpp C C++ C C++ : for (int i=0;i

More information

Microsoft Word - 《C语言开发入门》课程教学大纲-2.doc

Microsoft Word - 《C语言开发入门》课程教学大纲-2.doc C 语言开发入门 课程教学大纲 ( 课程英文名称 ) 课程编号 :201409210011 学分 :5 学分学时 :60 学时 ( 其中 : 讲课学时 :37 学时上机学时 :23 学时 ) 先修课程 : 计算机导论后续课程 :C++ 程序设计适用专业 : 信息及其计算机相关专业开课部门 : 计算机系 一 课程的性质与目标 C 语言开发入门 是计算机各专业必修的基础课程, 是数据结构 C++ Java

More information

教学输入与学习者的语言输出 温晓虹 本文从三个方面探讨了语言的输入与输出的关系 首先从理论研究的角度讨 论了从语言输入到语言输出的习得过程 实验研究表明 输入的语言素材必须被学习者所接收 即使接收了的内容也并不会自动进入中介语的体系 而是需要进一步对输入语言进行 分解 归类等分析性与综合性的处理 在语言 内化 的基础上 学习者的中介语系统才能 够不断地得到重新组合 趋于目的语 另外 学习者在语言输出前和输出时需要调节

More information

.size main,.lfe1-main.local b.comm b,4,4.comm c,4,4.ident "GCC: (GNU) egcs /Linux (egcs release)" 修改图 6.5 中计算声明名字

.size main,.lfe1-main.local b.comm b,4,4.comm c,4,4.ident GCC: (GNU) egcs /Linux (egcs release) 修改图 6.5 中计算声明名字 实验 : 1 阅读并理解 PL/0 语言前端编译器中的词法分析器, 扩展 PL/0 语言及其编译器, 以增加对上述多行注释的支持 2 [11 月 8 日开始检查 ] 参考 flex-examples, 将 PL/0 编译器中的词法分析部分的实现改造成两种构造方式 : 手工构造 ( 即使用原先在 pl0.c 中定义的 getch 和 getsym 函数 ) 用 flex 自动生成词法分析程序 ( 即编写描述

More information

全国计算机技术与软件专业技术资格(水平)考试

全国计算机技术与软件专业技术资格(水平)考试 全 国 计 算 机 技 术 与 软 件 专 业 技 术 资 格 ( 水 平 ) 考 试 2008 年 上 半 年 程 序 员 下 午 试 卷 ( 考 试 时 间 14:00~16:30 共 150 分 钟 ) 试 题 一 ( 共 15 分 ) 阅 读 以 下 说 明 和 流 程 图, 填 补 流 程 图 中 的 空 缺 (1)~(9), 将 解 答 填 入 答 题 纸 的 对 应 栏 内 [ 说 明

More information

<4D F736F F D E4345C6BDCCA84323B1E0B3CCD2AAB5E3D6AED2BB2E646F63>

<4D F736F F D E4345C6BDCCA84323B1E0B3CCD2AAB5E3D6AED2BB2E646F63> 基于 WINCE 平台 C# 编程要点之一 本文主要介绍在基于 Windows CE 平台的英创嵌入式主板下进行 C#(Microsoft Visual Stdio.Net 2005) 应用程序开发时会常常用到的一些功能函数以及开发方法, 这些方法适用于英创采用 WinCE 平台的所有型号嵌入式主板, 包括 EM9000 EM9260 EM9160 等 本文要点包括 : 文件的删除和复制 如何获取存取设备的空间大小

More information

Microsoft PowerPoint - 8. 运算符重载 Operator Overloading.pptx

Microsoft PowerPoint - 8. 运算符重载 Operator Overloading.pptx 运算符重载 Operator Overloading class Point { public: ; double x_, y_; Why Operator Overloading? Point (double x =0, double y = 0):x_(x),y_(y) { int main(){ Point a(1., 2), b(3,4); Point c = a + b; return 0;

More information

Microsoft Word - 01.DOC

Microsoft Word - 01.DOC 第 1 章 JavaScript 简 介 JavaScript 是 NetScape 公 司 为 Navigator 浏 览 器 开 发 的, 是 写 在 HTML 文 件 中 的 一 种 脚 本 语 言, 能 实 现 网 页 内 容 的 交 互 显 示 当 用 户 在 客 户 端 显 示 该 网 页 时, 浏 览 器 就 会 执 行 JavaScript 程 序, 用 户 通 过 交 互 式 的

More information

<4D F736F F D20B5DAC8FDCBC4D5C2D7F7D2B5B4F0B0B82E646F63>

<4D F736F F D20B5DAC8FDCBC4D5C2D7F7D2B5B4F0B0B82E646F63> 第三章 Q3 1 1. 省略了 I/O 操作的复杂逻辑, 易实现, 耗费低 ; 2. 可以利用丰富的内存寻址模式实现灵活的 I/O 操作 Q3 2 假设存储单元 ds1 处寄存器地址为 0x2000, 代码如下 #define ds1 0x2000 while ( *ds1 == 0 ) ; Q3 3 假设设备 (dev1) 中有两个寄存器 ds1 和 dd1,dev1 的地址为 0x1000,ds1

More information

1 CPU interrupt INT trap CPU exception

1 CPU interrupt INT trap CPU exception 1 CPU interrupt INT trap CPU exception 2 X86 CPU gate 64 16 1 2 5 8 16 16 P DPL 00101 TSS 101 DPL P 1 64 16 1 2 1 1 3 3 5 16 16 16 P DPL 0 D 000 16 110 111 100 D 1=32 0=16 DPL P 1 INT DPL1>=CPL>=DPL CPU

More information

C 1

C 1 C homepage: xpzhangme 2018 5 30 C 1 C min(x, y) double C // min c # include # include double min ( double x, double y); int main ( int argc, char * argv []) { double x, y; if( argc!=

More information

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 复习 Protected 可以被子类 / 同一包中的类访问, 不能被其他类访问 弱化的 private 同时赋予 package access class MyType { public int i; public double d; public char

More information

詞 彙 表 編 號 詞 彙 描 述 1 預 約 人 資 料 中 文 姓 名 英 文 姓 名 身 份 證 字 號 預 約 人 電 話 性 別 2 付 款 資 料 信 用 卡 別 信 用 卡 號 信 用 卡 有 效 日 期 3 住 房 條 件 入 住 日 期 退 房 日 期 人 數 房 間 數 量 入

詞 彙 表 編 號 詞 彙 描 述 1 預 約 人 資 料 中 文 姓 名 英 文 姓 名 身 份 證 字 號 預 約 人 電 話 性 別 2 付 款 資 料 信 用 卡 別 信 用 卡 號 信 用 卡 有 效 日 期 3 住 房 條 件 入 住 日 期 退 房 日 期 人 數 房 間 數 量 入 100 年 特 種 考 試 地 方 政 府 公 務 人 員 考 試 試 題 等 別 : 三 等 考 試 類 科 : 資 訊 處 理 科 目 : 系 統 分 析 與 設 計 一 請 參 考 下 列 旅 館 管 理 系 統 的 使 用 案 例 圖 (Use Case Diagram) 撰 寫 預 約 房 間 的 使 用 案 例 規 格 書 (Use Case Specification), 繪 出 入

More information

提问袁小兵:

提问袁小兵: C++ 面 试 试 题 汇 总 柯 贤 富 管 理 软 件 需 求 分 析 篇 1. STL 类 模 板 标 准 库 中 容 器 和 算 法 这 部 分 一 般 称 为 标 准 模 板 库 2. 为 什 么 定 义 虚 的 析 构 函 数? 避 免 内 存 问 题, 当 你 可 能 通 过 基 类 指 针 删 除 派 生 类 对 象 时 必 须 保 证 基 类 析 构 函 数 为 虚 函 数 3.

More information

FY.DOC

FY.DOC 高 职 高 专 21 世 纪 规 划 教 材 C++ 程 序 设 计 邓 振 杰 主 编 贾 振 华 孟 庆 敏 副 主 编 人 民 邮 电 出 版 社 内 容 提 要 本 书 系 统 地 介 绍 C++ 语 言 的 基 本 概 念 基 本 语 法 和 编 程 方 法, 深 入 浅 出 地 讲 述 C++ 语 言 面 向 对 象 的 重 要 特 征 : 类 和 对 象 抽 象 封 装 继 承 等 主

More information

Microsoft PowerPoint - 6. 用户定义类型User-defined Datatypes.ppt [兼容模式]

Microsoft PowerPoint - 6. 用户定义类型User-defined Datatypes.ppt [兼容模式] 用户定义类型 User-defined Datatypes classes and structs 几何向量 (Geometry Vector) 二维平面上的向量由起点和终点构成 每个点包含两个坐标 (x, y), 因此一个向量需要四个实数表示 Start= (0.9,1.5) Start= (0.4,0.8) int main() { double xstart = 0.4; double xend

More information

2015年计算机二级(C语言)模拟试题及答案(三)

2015年计算机二级(C语言)模拟试题及答案(三) 2016 年计算机二级 (C 语言 ) 模拟试题及答案 (3) 1.( A ) 是构成 C 语言程序的基本单位 A 函数 B 过程 C 子程序 D 子例程 2.C 语言程序从 ( C ) 开始执行 A 程序中第一条可执行语句 B 程序中第一个函数 C 程序中的 main 函数 D 包含文件中的第一个函数 3 以下说法中正确的是( C ) A C 语言程序总是从第一个定义的函数开始执行 B 在 C 语言程序中,

More information

_汪_文前新ok[3.1].doc

_汪_文前新ok[3.1].doc 普 通 高 校 本 科 计 算 机 专 业 特 色 教 材 精 选 四 川 大 学 计 算 机 学 院 国 家 示 范 性 软 件 学 院 精 品 课 程 基 金 青 年 基 金 资 助 项 目 C 语 言 程 序 设 计 (C99 版 ) 陈 良 银 游 洪 跃 李 旭 伟 主 编 李 志 蜀 唐 宁 九 李 涛 主 审 清 华 大 学 出 版 社 北 京 i 内 容 简 介 本 教 材 面 向

More information

1 LINUX IDE Emacs gcc gdb Emacs + gcc + gdb IDE Emacs IDE C Emacs Emacs IDE ICE Integrated Computing Environment Emacs Unix Linux Emacs Emacs Emacs Un

1 LINUX IDE Emacs gcc gdb Emacs + gcc + gdb IDE Emacs IDE C Emacs Emacs IDE ICE Integrated Computing Environment Emacs Unix Linux Emacs Emacs Emacs Un Linux C July 27, 2016 Contents 1 Linux IDE 1 2 GCC 3 2.1 hello.c hello.exe........................... 5 2.2............................... 9 2.2.1 -Wall................................ 9 2.2.2 -E..................................

More information

《大话设计模式》第一章

《大话设计模式》第一章 第 1 章 代 码 无 错 就 是 优? 简 单 工 厂 模 式 1.1 面 试 受 挫 小 菜 今 年 计 算 机 专 业 大 四 了, 学 了 不 少 软 件 开 发 方 面 的 东 西, 也 学 着 编 了 些 小 程 序, 踌 躇 满 志, 一 心 要 找 一 个 好 单 位 当 投 递 了 无 数 份 简 历 后, 终 于 收 到 了 一 个 单 位 的 面 试 通 知, 小 菜 欣 喜

More information

运算符重载 为什么要 运算符重载 那些运算符可以重载, 哪些不可以 如何实现运算符重载 实现方式 : 成员函数与非成员函数 类型转换 怎样实现对象与基本数据类型数据的运算 2

运算符重载 为什么要 运算符重载 那些运算符可以重载, 哪些不可以 如何实现运算符重载 实现方式 : 成员函数与非成员函数 类型转换 怎样实现对象与基本数据类型数据的运算 2 第十一讲 运算符重载 与类型转换 运算符重载 为什么要 运算符重载 那些运算符可以重载, 哪些不可以 如何实现运算符重载 实现方式 : 成员函数与非成员函数 类型转换 怎样实现对象与基本数据类型数据的运算 2 为什么要运算符重载 预定义的运算符只针对基本数据类型, 若要对类的对象进行类似的运算, 需要重新定义运算符的功能 运算符重载实质就是函数重载 : 对已有的运算符赋予多重含义, 使得同一个运算符作用于不同类型的数据时导致不同的行为

More information

python内存管理

python内存管理 Python 级内存管理 - xiaorui.cc Object-specific allocators [ int ] [ dict ] [ list ]... [ string ] Python core +3 [ Python's object allocator ]

More information

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.06.doc

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.06.doc 2 5 8 11 0 13 1. 13 2. 15 3. 18 1 23 1. 23 2. 26 3. 28 2 36 1. 36 2. 39 3. 42 4. 44 5. 49 6. 51 3 57 1. 57 2. 60 3. 64 4. 66 5. 70 6. 75 7. 83 8. 85 9. 88 10. 98 11. 103 12. 108 13. 112 4 115 1. 115 2.

More information

OOP with Java 通知 Project 4: 5 月 2 日晚 9 点

OOP with Java 通知 Project 4: 5 月 2 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 5 月 2 日晚 9 点 复习 Protected 可以被子类 / 同一包中的类访问, 不能被其他类访问 弱化的 private 同时赋予 package access class MyType { public int i; public double d; public char

More information

1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10

1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10 Java V1.0.1 2007 4 10 1 4 1.1 4 1.2..4 2..4 2.1..4 3.4 3.1 Java.5 3.1.1..5 3.1.2 5 3.1.3 6 4.6 4.1 6 4.2.6 5 7 5.1..8 5.1.1 8 5.1.2..8 5.1.3..8 5.1.4..9 5.2..9 6.10 6.1.10 6.2.10 6.3..10 6.4 11 7.12 7.1

More information

第 14 行调用 of_demo_controller_register 注册 demo controller 驱动,xlate 函数设置的都是 of_demo_simple_xlate, 这个函数完成对 user 传来的参数的处理 1. int of_demo_controller_registe

第 14 行调用 of_demo_controller_register 注册 demo controller 驱动,xlate 函数设置的都是 of_demo_simple_xlate, 这个函数完成对 user 传来的参数的处理 1. int of_demo_controller_registe 作者 彭东林 pengdonglin137@163.com 平台 TQ2440 Linux 4.10.17 概述 上一篇大概介绍了一下 demo controller 的结构, 下面结合驱动分析 正文 一 demo controller 驱动 这里主要分析 probe 函数 demo_controller_probe: 1. static int demo_controller_probe(struct

More information

Microsoft PowerPoint - 05-第五讲-寻址方式.pptx

Microsoft PowerPoint - 05-第五讲-寻址方式.pptx 第五讲 授课教师 : 陆俊林王箫音 2012 年春季学期 主要内容 一 寻址方式概述 二 数据的寻址方式 三 转移地址的寻址方式 教材相关章节 : 微型计算机基本原理与应用 ( 第二版 ) 第 4 章寻址方式与指令系统 1 主要内容 一 寻址方式概述 二 数据的寻址方式 三 转移地址的寻址方式 2 指令的组成 指令由操作码和操作数两部分组成 操作码操作数 MOV AX, 8726H ADD AX,

More information

2013 C 1 # include <stdio.h> 2 int main ( void ) 3 { 4 int cases, a, b, i; 5 scanf ("%d", & cases ); 6 for (i = 0;i < cases ;i ++) 7 { 8 scanf ("%d %d

2013 C 1 # include <stdio.h> 2 int main ( void ) 3 { 4 int cases, a, b, i; 5 scanf (%d, & cases ); 6 for (i = 0;i < cases ;i ++) 7 { 8 scanf (%d %d 2013 18 ( ) 1. C pa.c, pb.c, 2. C++ pa.cpp, pb.cpp, Compilation Error cin scanf Time Limit Exceeded 1: A 5 B 5 C 5 D 5 E 5 F 5 1 2013 C 1 # include 2 int main ( void ) 3 { 4 int cases, a, b,

More information

OOP with Java 通知 Project 4: 5 月 2 日晚 9 点

OOP with Java 通知 Project 4: 5 月 2 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 5 月 2 日晚 9 点 复习 Java 包 创建包 : package 语句, 包结构与目录结构一致 使用包 : import restaurant/ - people/ - Cook.class - Waiter.class - tools/ - Fork.class - Table.class

More information

38 47995529 威 福 髮 藝 店 桃 園 市 蘆 竹 區 中 山 里 福 祿 一 街 48 號 地 下 一 樓 50,000 獨 資 李 依 純 105/04/06 府 經 登 字 第 1059003070 號 39 47995534 宏 品 餐 飲 桃 園 市 桃 園 區 信 光 里 民

38 47995529 威 福 髮 藝 店 桃 園 市 蘆 竹 區 中 山 里 福 祿 一 街 48 號 地 下 一 樓 50,000 獨 資 李 依 純 105/04/06 府 經 登 字 第 1059003070 號 39 47995534 宏 品 餐 飲 桃 園 市 桃 園 區 信 光 里 民 1 08414159 惠 鴻 眼 鏡 行 桃 園 市 中 壢 區 福 德 里 中 華 路 一 段 186 號 1 樓 30,000 獨 資 宋 耀 鴻 105/04/27 府 經 登 字 第 1059003866 號 2 17891110 承 元 冷 氣 空 調 工 程 行 桃 園 市 桃 園 區 中 德 里 國 際 路 1 段 98 巷 50 號 2 樓 之 4 200,000 獨 資 詹 安 平

More information

JavaIO.PDF

JavaIO.PDF O u t p u t S t ream j a v a. i o. O u t p u t S t r e a m w r i t e () f l u s h () c l o s e () public abstract void write(int b) throws IOException public void write(byte[] data) throws IOException

More information

第3章.doc

第3章.doc 3 3 3 3.1 3 IT Trend C++ Java SAP Advantech ERPCRM C++ C++ Synopsys C++ NEC C C++PHP C++Java C++Java VIA C++ 3COM C++ SPSS C++ Sybase C++LinuxUNIX Motorola C++ IBM C++Java Oracle Java HP C++ C++ Yahoo

More information

今天刚发现的, 比较简单, 于是就来简单分析下吧 该感染样本很简单, 新加了个区段放病毒执行代码, 执行病毒代码, 最后跳回原入口点来执行原文件 下面就是感染后的代码的简单分析 : ; =============== S U B R O U T I N E =====================

今天刚发现的, 比较简单, 于是就来简单分析下吧 该感染样本很简单, 新加了个区段放病毒执行代码, 执行病毒代码, 最后跳回原入口点来执行原文件 下面就是感染后的代码的简单分析 : ; =============== S U B R O U T I N E ===================== 吾爱破解论坛 [LCG] [LSG] 立足软件安全和病毒分析最前端, 丰富的技术版块交相辉映, 由无数加密解密及反病毒爱好者共同维护, 留给世界一抹值得百年回眸的惊 艳, 沉淀百年来计算机应用之精华与优雅, 信息线条与生活质感淡定交融, 任岁月流转, 低调而奢华的技术交流与研究却是亘古不变 标题 : 一个感染样本的简单分析 作者 :ximo 今天刚发现的, 比较简单, 于是就来简单分析下吧 该感染样本很简单,

More information

fvalue = (pdata[y][i] + pdata[y][i + 1]) / 2; pdata[y][nhalfw + i] -= fvalue; fvalue = (pdata[y][nhalfw - 1] + pdata[y][nhalfw - 2]) / 2; pdata[y][nwi

fvalue = (pdata[y][i] + pdata[y][i + 1]) / 2; pdata[y][nhalfw + i] -= fvalue; fvalue = (pdata[y][nhalfw - 1] + pdata[y][nhalfw - 2]) / 2; pdata[y][nwi #include #include #include // 二维离散小波变换 ( 单通道浮点图像 ) void DWT(IplImage *pimage, int nlayer) // 执行条件 if (pimage) if (pimage->nchannels == 1 && pimage->depth == IPL_DEPTH_32F

More information

绘制OpenCascade中的曲线

绘制OpenCascade中的曲线 在 OpenSceneGraph 中绘制 OpenCascade 的曲线 Draw OpenCascade Geometry Curves in OpenSceneGraph eryar@163.com 摘要 Abstract: 本文简要说明 OpenCascade 中几何曲线的数据, 并将这些几何曲线在 OpenSceneGraph 中绘制出来 关键字 KeyWords:OpenCascade Geometry

More information

06-statement

06-statement PHP 基本语法 条件 循环 函数杨亮 程序的基本结构 程序 输 入 运算 (+ - x / &! ) 逻辑 ( 条件 循环 递归 ) 输出 辅助 ( 变量 数组 函数 ) 小测验 用你熟悉的程序找出 1~1000 中的所有质数 我们直接看代码好了 if else elseif 1

More information

untitled

untitled 1 Outline 料 類 說 Tang, Shih-Hsuan 2006/07/26 ~ 2006/09/02 六 PM 7:00 ~ 9:30 聯 ives.net@gmail.com www.csie.ntu.edu.tw/~r93057/aspnet134 度 C# 力 度 C# Web SQL 料 DataGrid DataList 參 ASP.NET 1.0 C# 例 ASP.NET 立

More information

三种方法实现Hadoop(MapReduce)全局排序(1)

三种方法实现Hadoop(MapReduce)全局排序(1) 三种方法实现 Hadoop(MapReduce) 全局排序 () 三种方法实现 Hadoop(MapReduce) 全局排序 () 我们可能会有些需求要求 MapReduce 的输出全局有序, 这里说的有序是指 Key 全局有序 但是我们知道,MapReduce 默认只是保证同一个分区内的 Key 是有序的, 但是不保证全局有序 基于此, 本文提供三种方法来对 MapReduce 的输出进行全局排序

More information

int *p int a 0x00C7 0x00C7 0x00C int I[2], *pi = &I[0]; pi++; char C[2], *pc = &C[0]; pc++; float F[2], *pf = &F[0]; pf++;

int *p int a 0x00C7 0x00C7 0x00C int I[2], *pi = &I[0]; pi++; char C[2], *pc = &C[0]; pc++; float F[2], *pf = &F[0]; pf++; Memory & Pointer trio@seu.edu.cn 2.1 2.1.1 1 int *p int a 0x00C7 0x00C7 0x00C7 2.1.2 2 int I[2], *pi = &I[0]; pi++; char C[2], *pc = &C[0]; pc++; float F[2], *pf = &F[0]; pf++; 2.1.3 1. 2. 3. 3 int A,

More information

领导,我不想写CSS代码.key

领导,我不想写CSS代码.key 领导 我不想写 CSS 张鑫旭 25MIN 2018-03-31 YUEWEN USER EXPERIENCE DESIGN 01 1 YUEWEN USER EXPERIENCE DESIGN 砖家 02 CSS - 艺术家 YUEWEN USER EXPERIENCE DESIGN 03 CSS - 砖家 艺术家 YUEWEN USER EXPERIENCE DESIGN 04 领导, 我不想写

More information

class sometimes { int naive; void make_money() { this.naive++; int main() { sometimes keep = new sometimes; keep.naive = 0; while (getint() < Wallace)

class sometimes { int naive; void make_money() { this.naive++; int main() { sometimes keep = new sometimes; keep.naive = 0; while (getint() < Wallace) Mx* Language Reference Manual 2017 年 3 月 8 日 1 用词说明 未定义 指中央还没有表态指规范并没有定义该情况发生时语言的表现 初衷是为了给同学们提供一些自己发挥的空间, 在测试数据里, 这些没有定义的情况是不会发生的 例 : 术语 : 编译器接受源代码长度如果超过 1M, 结果是未定义的 解释 : 我们测试用的源代码长度不会超过 1M, 可以假设测试数据不会出现这种情况

More information

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.07.doc

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.07.doc 2 5 8 11 0 1. 13 2. 15 3. 18 1 1. 22 2. 25 3. 27 2 1. 35 2. 38 3. 41 4. 43 5. 48 6. 50 3 1. 56 2. 59 3. 63 4. 65 5. 69 13 22 35 56 6. 74 7. 82 8. 84 9. 87 10. 97 11. 102 12. 107 13. 111 4 114 1. 114 2.

More information

<4D6963726F736F667420576F7264202D20C8EDC9E82DCFC2CEE7CCE22D3039C9CF>

<4D6963726F736F667420576F7264202D20C8EDC9E82DCFC2CEE7CCE22D3039C9CF> 全 国 计 算 机 技 术 与 软 件 专 业 技 术 资 格 ( 水 平 考 试 2009 年 上 半 年 软 件 设 计 师 下 午 试 卷 ( 考 试 时 间 14:00~16:30 共 150 分 钟 请 按 下 述 要 求 正 确 填 写 答 题 纸 1. 在 答 题 纸 的 指 定 位 置 填 写 你 所 在 的 省 自 治 区 直 辖 市 计 划 单 列 市 的 名 称 2. 在 答

More information

1 1 大概思路 创建 WebAPI 创建 CrossMainController 并编写 Nuget 安装 microsoft.aspnet.webapi.cors 跨域设置路由 编写 Jquery EasyUI 界面 运行效果 2 创建 WebAPI 创建 WebAPI, 新建 -> 项目 ->

1 1 大概思路 创建 WebAPI 创建 CrossMainController 并编写 Nuget 安装 microsoft.aspnet.webapi.cors 跨域设置路由 编写 Jquery EasyUI 界面 运行效果 2 创建 WebAPI 创建 WebAPI, 新建 -> 项目 -> 目录 1 大概思路... 1 2 创建 WebAPI... 1 3 创建 CrossMainController 并编写... 1 4 Nuget 安装 microsoft.aspnet.webapi.cors... 4 5 跨域设置路由... 4 6 编写 Jquery EasyUI 界面... 5 7 运行效果... 7 8 总结... 7 1 1 大概思路 创建 WebAPI 创建 CrossMainController

More information

Microsoft PowerPoint - 第06讲_继承.ppt [兼容模式]

Microsoft PowerPoint - 第06讲_继承.ppt [兼容模式] 程序设计实习 (I): C++ 程序设计 第六讲继承 上节内容回顾 三种运算符重载的实现方式 重载为普通函数 重载为成员函数 重载为友元 常见的运算符重载 流运算符 (>>

More information

Microsoft PowerPoint - ch1.ppt [兼容模式]

Microsoft PowerPoint - ch1.ppt [兼容模式] 编译原理和技术 中国科学技术大学计算机科学与技术学院张昱 0551-3603804 yuzhang@ustc.edu.cn 致谢 本系列讲稿是在陈意云教授撰写的 编译原理和技术 讲稿之上完成, 特此感谢陈老师! 课程简介 课程内容 介绍编译器构造的一般原理和基本实现方法 包括的理论知识 : 形式语言和自动机理论 语法制导的定义和属性文法 类型论与类型系统 程序分析原理, 等等 强调形式描述技术和自动生成技术

More information

用户大会 论文集2.2.doc

用户大会 论文集2.2.doc MagGis MapGis GIS MagGis API DLL MapGis VC++ VB BC++ Delphi., Windows API MapGis VC++V Delphi Delphi Delphi MapGis Delphi Delphi Windows Delphi Delphi MapGis MapGis DLL API MapGis function _InitWorkArea(HINST:Integer):Integer;

More information

// HDevelopTemplateWPF projects located under %HALCONEXAMPLES%\c# using System; using HalconDotNet; public partial class HDevelopExport public HTuple

// HDevelopTemplateWPF projects located under %HALCONEXAMPLES%\c# using System; using HalconDotNet; public partial class HDevelopExport public HTuple halcon 与 C# 混合编程之 Halcon 代码调用 写在前面 完成 halcon 与 C# 混合编程的环境配置后, 进行界面布局设计构思每一个按钮所需要实现 的功能, 将 Halcon 导出的代码复制至相应的 C# 模块下即可 halcon 源程序 : dev_open_window(0, 0, 512, 512, 'black', WindowHandle) read_image (Image,

More information

Chapter12 Derived Classes

Chapter12   Derived Classes 继 承 -- 派 生 类 复 习 1. 有 下 面 类 的 说 明, 有 错 误 的 语 句 是 : class X { A) const int a; B) X(); C) X(int val) {a=2 D) ~X(); 答 案 :C 不 正 确, 应 改 成 X(int val) : a(2) { 2. 下 列 静 态 数 据 成 员 的 特 性 中, 错 误 的 是 A) 说 明 静 态 数

More information

C++ 程式設計

C++ 程式設計 C C 料, 數, - 列 串 理 列 main 數串列 什 pointer) 數, 數, 數 數 省 不 不, 數 (1) 數, 不 數 * 料 * 數 int *int_ptr; char *ch_ptr; float *float_ptr; double *double_ptr; 數 (2) int i=3; int *ptr; ptr=&i; 1000 1012 ptr 數, 數 1004

More information

礼仪玉和葬玉

礼仪玉和葬玉 http://shop33322103.taobao.com 1 http://shop33322103.taobao.com 2 http://shop33322103.taobao.com 3 http://shop33322103.taobao.com 4 http://shop33322103.taobao.com 5 http://shop33322103.taobao.com 6 http://shop33322103.taobao.com

More information

ROP_bamboofox.key

ROP_bamboofox.key ROP Return Oriented Programming Lays @ BambooFox Who Am I Lays / L4ys / 累死 - l4ys.tw Reverse Engineering BambooFox / HITCON Outline Buffer Overflow ret2libc / ret2text Return Oriented Programming Payload

More information

第四章 102 图 4唱16 基于图像渲染的理论基础 三张拍摄图像以及它们投影到球面上生成的球面图像 拼图的圆心是相同的 而拼图是由球面图像上的弧线图像组成的 因此我 们称之为同心球拼图 如图 4唱18 所示 这些拼图中半径最大的是圆 Ck 最小的是圆 C0 设圆 Ck 的半径为 r 虚拟相机水平视域为 θ 有 r R sin θ 2 4畅11 由此可见 构造同心球拼图的过程实际上就是对投影图像中的弧线图像

More information

untitled

untitled 1 5 IBM Intel 1. IBM 第 1/175 页 第 2/175 页 第 3/175 页 80 第 4/175 页 2. IBM 第 5/175 页 3. (1) 第 6/175 页 第 7/175 页 第 8/175 页 = = 第 9/175 页 = = = = = 第 10/175 页 = = = = = = = = 3. (2) 第 11/175 页 第 12/175 页 第 13/175

More information

C++ Programming Style.docx

C++ Programming Style.docx C++ Programming Style (C++ 编码规范 ) Last Modified: 2014-11-18 Hongfei Yan 目的 书写格式规范 标示符命名规范 文档规范 模块组织规范 一般性原则 = 目的 = 增强代码的可读性, 从而使得系统具有更少的 Bug 和更高的健壮性 涉及到程序的书写格式 (Code appearance/layout) 标示符命名 (Naming) 文档规范

More information

幻灯片 1

幻灯片 1 信息科学技术学院 程序设计实习 郭炜微博 http://weibo.com/guoweiofpku http://blog.sina.com.cn/u/3266490431 刘家瑛微博 http://weibo.com/pkuliujiaying 1 信息科学技术学院 程序设计实习 郭炜刘家瑛 继承和派生 ( 教材 P215) 2 继承和派生的概念 继承 : 在定义一个新的类 B 时, 如果该类与某个已有的类

More information

Linux kernel exploit研究和探索

Linux kernel exploit研究和探索 Linux kernel exploit DOC alert7 PPT e4gle 2002-12-2 1 2002-12-2 2 Linux kernel exploit kernel exploit exploit exploit exploit (Kernel Buffer Overflow) (Kernel

More information

Microsoft PowerPoint - plan06.ppt

Microsoft PowerPoint - plan06.ppt 程 序 设 计 语 言 原 理 Principle of Programming Languages 裘 宗 燕 北 京 大 学 数 学 学 院 2012.2~2012.6 6. 基 本 控 制 抽 象 子 程 序 抽 象 子 程 序 活 动 和 局 部 环 境 静 态 实 现 模 型 一 般 实 现 模 型 调 用 序 列 和 在 线 展 开 参 数 机 制 泛 型 子 程 序 异 常 处 理 其

More information

2009年3月全国计算机等级考试二级Java语言程序设计笔试试题

2009年3月全国计算机等级考试二级Java语言程序设计笔试试题 2009 年 3 月 全 国 计 算 机 等 级 考 试 笔 试 试 卷 二 级 Java 语 言 程 序 设 计 ( 考 试 时 间 90 分 钟, 满 分 100 分 ) 一 选 择 题 ( 每 题 2 分, 共 70 分 ) 下 列 各 题 A) B) C) D) 四 个 选 项 中, 只 有 一 个 选 项 是 正 确 的 请 将 正 确 选 项 填 涂 在 答 题 卡 相 应 位 置 上,

More information

Microsoft PowerPoint - L17_Inheritance_v4.pptx

Microsoft PowerPoint - L17_Inheritance_v4.pptx C++ Programming Lecture 17 Wei Liu ( 刘 威 ) Dept. of Electronics and Information Eng. Huazhong University of Science and Technology May. 2015 Lecture 17 Chapter 20. Object-Oriented Programming: Inheritance

More information

Microsoft Word - 逆向C++.doc

Microsoft Word - 逆向C++.doc 逆向 C++ 这些年来, 逆向工程分析人员一直是凭借着汇编和 C 的知识对大多数软件进行逆向工程的, 但是, 现在随着越来越多的应用程序和恶意软件转而使用 C++ 语言进行开发, 深入理解 C++ 面向对象方式开发的软件的反汇编技术就显得越发的必要 本文试图通过分析在反汇编时如何手工识别 C++ 对象, 进而讨论如何自动完成这一分析过程最终介绍我们自己开发的自动化工具, 一步一步的帮助读者掌握逆向

More information

教案模板4-2

教案模板4-2 传智播客 Java 基础入门 教学设计 课程名称 : Java 基础入门 授课年级 : 2014 年级 授课学期 : 2014 学年第一学期 教师姓名 : 某某老师 2014 年 02 月 09 日 课题名称第 3 章面向对象上 计划学时 6 课时 Java 是一种面向对象的语言, 认识面向对象的编程思想对于 Java 学习至关重 内容分析 要 在面向对象中, 有两个重要的概念, 分别是类和对象,

More information

华恒家庭网关方案

华恒家庭网关方案 LINUX V1.5 1 2 1 2 LINUX WINDOWS PC VC LINUX WINDOWS LINUX 90% GUI LINUX C 3 REDHAT 9 LINUX PC TFTP/NFS http://www.hhcn.com/chinese/embedlinux-res.html minicom NFS mount C HHARM9-EDU 1 LINUX HHARM9-EDU

More information

51 C 51 isp 10 C PCB C C C C KEIL

51 C 51 isp 10   C   PCB C C C C KEIL http://wwwispdowncom 51 C " + + " 51 AT89S51 In-System-Programming ISP 10 io 244 CPLD ATMEL PIC CPLD/FPGA ARM9 ISP http://wwwispdowncom/showoneproductasp?productid=15 51 C C C C C ispdown http://wwwispdowncom

More information

MSP430µ¥Æ¬»úCÓïÑԺͻã±àÓïÑÔ»ìºÏ±à³Ì.doc

MSP430µ¥Æ¬»úCÓïÑԺͻã±àÓïÑÔ»ìºÏ±à³Ì.doc MSP430 单片机 C 语言和汇编语言混合编程 Mixing C and Assembler With the MSP430 刘玉宏 Liu,Yuhong 摘要 : 为了发挥 C 语言和汇编语言各自的优点, 二者需要相互调用函数 本文首先介绍了 MSP430 单片机的 C 语言函数的参数传递规则, 然后对 C 语言和汇编语言的混合编程进行了详细描述, 最后给出应用实例 关键字 :MSP430 单片机

More information

Ps22Pdf

Ps22Pdf y X DN A DNA A B C D A B C D A B C D Party Nike A B Yes A B C A B C A B C A B C A B C A B C D A B C E l A A B C A B C A B C A B C A B C A B C D A B C D E F AB AB AB AB AB

More information

Microsoft Word - CPE考生使用手冊160524.docx

Microsoft Word - CPE考生使用手冊160524.docx 大 學 程 式 能 力 檢 定 (CPE) 考 生 使 用 手 冊 2016 年 5 月 24 日 這 份 手 冊 提 供 給 參 加 CPE 檢 定 考 試 的 考 生 內 容 包 含 考 試 環 境 的 使 用, 以 及 解 題 時 所 使 用 I/O 的 基 本 知 識 1. 如 欲 報 名 參 加 CPE 考 試, 請 先 於 CPE 網 站 完 成 帳 號 註 冊, 然 後 再 報 名 該

More information

<4D F736F F F696E74202D20B5DA3032BDB25FC0E0BACDB6D4CFF3312E BBCE6C8DDC4A3CABD5D>

<4D F736F F F696E74202D20B5DA3032BDB25FC0E0BACDB6D4CFF3312E BBCE6C8DDC4A3CABD5D> 程序设计实习 (I): C++ 程序设计 第二讲类和对象 (1) 面向对象的程序设计 面向对象的程序设计方法, 能够较好解决结构化程序设计中出现的问题 面向对象的程序 = 类 + 类 + + 类 设计程序的过程, 就是设计类的过程 2 面向对象的程序设计 面向对象的程序设计方法 : 将某类客观事物共同特点 ( 属性 ) 归纳出来, 形成一个数据结 构 ( 可以用多个变量描述事物的属性 ); 将这类事物所能进行的行为也归纳出来,

More information

電機工程系認可證照清單 2011/7/1

電機工程系認可證照清單                  2011/7/1 南 台 科 技 大 學 電 機 工 程 系 專 業 證 照 課 程 實 施 要 點 96 年 10 月 05 日 系 務 會 議 通 過 100 年 06 月 30 日 系 務 會 議 修 正 通 過 101 年 06 月 21 日 系 務 會 議 修 正 通 過 一 本 系 為 提 升 學 生 的 專 業 技 能, 特 訂 定 本 辦 法 二 實 施 對 象 : 本 系 日 間 部 96 學 年

More information

[obj2 hello]; [obj2 release]; [obj1 release] 之后,obj2 依然是个无效指针 问题依然没有解决 解决方法见下一条 4 Objective-C 指针赋值时,retain count 不会自动增加, 需要手动 retain ClassA *obj1 = [[

[obj2 hello]; [obj2 release]; [obj1 release] 之后,obj2 依然是个无效指针 问题依然没有解决 解决方法见下一条 4 Objective-C 指针赋值时,retain count 不会自动增加, 需要手动 retain ClassA *obj1 = [[ Objective-C 内存管理教程 初学 objectice-c 的朋友都有一个困惑, 总觉得对 objective-c 的内存管理机制琢磨不透, 程 序经常内存泄漏或莫名其妙的崩溃 我在这里总结了自己对 objective-c 内存管理机制的研究 成果和经验, 写了这么一个由浅入深的教程 希望对大家有所帮助, 也欢迎大家一起探讨 此文涉及的内存管理是针对于继承于 NSObject 的 Class

More information

使 用 Java 语 言 模 拟 保 险 箱 容 量 门 板 厚 度 箱 体 厚 度 属 性 锁 具 类 型 开 保 险 箱 关 保 险 箱 动 作 存 取 款

使 用 Java 语 言 模 拟 保 险 箱 容 量 门 板 厚 度 箱 体 厚 度 属 性 锁 具 类 型 开 保 险 箱 关 保 险 箱 动 作 存 取 款 JAVA 程 序 设 计 ( 肆 ) 徐 东 / 数 学 系 使 用 Java 语 言 模 拟 保 险 箱 容 量 门 板 厚 度 箱 体 厚 度 属 性 锁 具 类 型 开 保 险 箱 关 保 险 箱 动 作 存 取 款 使 用 Java class 代 表 保 险 箱 public class SaveBox 类 名 类 类 体 实 现 封 装 性 使 用 class SaveBox 代 表 保

More information

3.1 num = 3 ch = 'C' 2

3.1 num = 3 ch = 'C' 2 Java 1 3.1 num = 3 ch = 'C' 2 final 3.1 final : final final double PI=3.1415926; 3 3.2 4 int 3.2 (long int) (int) (short int) (byte) short sum; // sum 5 3.2 Java int long num=32967359818l; C:\java\app3_2.java:6:

More information

Microsoft PowerPoint - ds-1.ppt [兼容模式]

Microsoft PowerPoint - ds-1.ppt [兼容模式] http://jwc..edu.cn/jxgl/ HomePage/Default.asp 2 说 明 总 学 时 : 72( 学 时 )= 56( 课 时 )+ 16( 实 验 ) 行 课 时 间 : 第 1 ~14 周 周 学 时 : 平 均 每 周 4 学 时 上 机 安 排 待 定 考 试 时 间 : 课 程 束 第 8 11 12 章 的 内 容 为 自 学 内 容 ; 目 录 中 标 有

More information

Microsoft Word - 物件導向編程精要.doc

Microsoft Word - 物件導向編程精要.doc Essential Object-Oriented Programming Josh Ko 2007.03.11 object-oriented programming C++ Java OO class object OOP Ruby duck typing complexity abstraction paradigm objects objects model object-oriented

More information

<4D F736F F F696E74202D20B5DA31D5C220D2FDC2DB2E BD6BBB6C15D205BBCE6C8DDC4A3CABD5D>

<4D F736F F F696E74202D20B5DA31D5C220D2FDC2DB2E BD6BBB6C15D205BBCE6C8DDC4A3CABD5D> 编译原理与技术 中国科学技术大学 计算机科学与技术学院 张昱 陈意云 0551-3603804, 3607043 yuzhang, yiyun@ustc.edu.cn cn 课程简介 课程内容 介绍编译器构造的一般原理和基本实现方法 包括的理论知识 : 形式语言和自动机理论 语法制导的定义等 课程特点 强调对编译原理和技术的宏观理解, 不把注意力引导到理论和一些枝节算法上 不偏向于任何源语言或目标机器

More information

1 Project New Project 1 2 Windows 1 3 N C test Windows uv2 KEIL uvision2 1 2 New Project Ateml AT89C AT89C51 3 KEIL Demo C C File

1 Project New Project 1 2 Windows 1 3 N C test Windows uv2 KEIL uvision2 1 2 New Project Ateml AT89C AT89C51 3 KEIL Demo C C File 51 C 51 51 C C C C C C * 2003-3-30 pnzwzw@163.com C C C C KEIL uvision2 MCS51 PLM C VC++ 51 KEIL51 KEIL51 KEIL51 KEIL 2K DEMO C KEIL KEIL51 P 1 1 1 1-1 - 1 Project New Project 1 2 Windows 1 3 N C test

More information

除 :/ 余 :mod, (3) 关系运算 : 小于 :< 小于等于 :<= 大于 :> 大于等于 : >= 等于 : == 不等于 : <> (4) 逻辑运算 : 逻辑于 :And 逻辑或 :Or 逻辑 Xor 逻辑非 :Not (5) 位运算 : (a) 移位运算左移 : << 右移 : >>

除 :/ 余 :mod, (3) 关系运算 : 小于 :< 小于等于 :<= 大于 :> 大于等于 : >= 等于 : == 不等于 : <> (4) 逻辑运算 : 逻辑于 :And 逻辑或 :Or 逻辑 Xor 逻辑非 :Not (5) 位运算 : (a) 移位运算左移 : << 右移 : >> EasyBuilder 500 Macro 使用说明一 : 文档说明 作者 : 程志刚时间 : 2003 年 1 月版权所有 : 台湾威纶科技有限公司概要 : 此文档为宏指令功能模块的使用文档, 说明宏语言的语法, 宏语言的使用, 宏指令源程序编写的操作方法与操作顺序, 使用文档包含以下几个部分 : 宏语言文本说明 : 宏语言使用说明宏指令程序与 PLC 的通信 ( 包括本地地址 LocalBit,LocalWord):

More information

第三章 基本的类、字符串、描述符

第三章 基本的类、字符串、描述符 第四章基本类型 描述符和动态数组 邹仕洪, 博士 网络与交换国家重点实验室 宽带网研究中心 zoush@bupt.edu.cn http://bnrc.cs.bupt.cn/~zoushihong 网络与交换国家重点实验室 2005--10 10-- 1 宽带网研究中心 C++ 回顾 对象, 类 方法 属性 访问控制 :public, private, protect 构造函数 析构函数 动态对象创建

More information

Ioncube Php Encoder 8 3 Crack 4. llamaba octobre traslado General Search colony

Ioncube Php Encoder 8 3 Crack 4. llamaba octobre traslado General Search colony Ioncube Php Encoder 8 3 Crack 4 ->>->>->> DOWNLOAD 1 / 5 2 / 5 Press..the..General..Tools..category4Encrypt..and..protect..files..with..PHP..encoding,..encryption,..ob fuscation..and..licensing... 2016

More information

长 安 大 学 硕 士 学 位 论 文 基 于 数 据 仓 库 和 数 据 挖 掘 的 行 为 分 析 研 究 姓 名 : 杨 雅 薇 申 请 学 位 级 别 : 硕 士 专 业 : 计 算 机 软 件 与 理 论 指 导 教 师 : 张 卫 钢 20100530 长安大学硕士学位论文 3 1 3系统架构设计 行为分析数据仓库的应用模型由四部分组成 如图3 3所示

More information