漫谈 Linux ,龙芯及其软件开发 陈华才2010.03. 目录 Linux 及相关概念 Linux 及相关概念 Linux 开发者初步教程 Linux 开发者初步教程.

Slides:



Advertisements
Similar presentations
纺纱学. 2 绪 论 基本要求:了解纺纱系统的类别 重点掌握:棉纺系统的工艺流程 3 一、纺纱原理与设备 纺纱:用物理或机械的方法将纺织纤维纺成纱 线的过程。 纺纱原理:初加工、原料的选配、开松除杂、 混和、梳理、精梳、并合、牵伸、加捻、卷绕等。 纺纱方法:传统纺纱方法、新型纺纱方法。 纺纱设备:开清棉联合机、梳棉机、精梳机、
Advertisements

Nutch 二次开发介绍.  1.Nutch 二次开发中重点环节介绍 1.1 信息源选择及规范制定 1.2 信息预处理 1.3 索引构建 1.4 排序规则制定 1.5 查询系统及用户界面  2.Nutch 中的 plugin 介绍 2.1 Plugin 介绍 2.2 页面解析.
一、统计范围 注册地在湖里区的具有房地产开发资质的 房地产开发企业 无论目前是否有开发项目 无论开发的项目是在湖里区还是在其他区 没有开发项目的企业需要报送年报和月报 中的资金表(空表)。 新成立的项目公司,要先入库,再报报表。
第十二章 常微分方程 返回. 一、主要内容 基本概念 一阶方程 类 型 1. 直接积分法 2. 可分离变量 3. 齐次方程 4. 可化为齐次 方程 5. 全微分方程 6. 线性方程 类 型 1. 直接积分法 2. 可分离变量 3. 齐次方程 4. 可化为齐次 方程 5. 全微分方程 6. 线性方程.
第 12 章位运算 C 语言兼具高级语言及低级语言的特性,因此 适合编写系统软件。 C 语言具备低级语言的特性 就在于它能直接对硬件进行操作,即位运算。 所谓位运算是指,按二进制位进行的运算。 例如,将一个存储单元中各二进位左移或右移一 位等。
第二节 Flash 动态按钮的制作 铁王中学 王东强 学习目标: 1 、了解 ActionScript 在交互动画中的重要作 用 2 、知道 ActionsScript 程序的组成 3 、熟练使用按钮中的 ActionScript 控制动画 播放的操作,掌握按钮的创建和使用方法,
HistCite 结果分析示例 罗昭锋. By:SC 可能原因:文献年度过窄,少有相互引用.
细分曲面 傅孝明 SA 目录 细分曲面的基本思想 两个关键问题 一些基本概念 几种简单的细分曲面算法 细分曲面方法分类.
计算机 在分析化学的应用 ( 简介 ) 陈辉宏. 一. 概述 信息时代的来临, 各门学科的研究方法都 有了新的发展. 计算机的介入, 为分析化学的进展提供了 一种更方便的研究方法.
Linux 下驱动程序简介 —USB 摄像头 CWY-CTS-SA117L 袁师盛 柴佳杰 孙融 王磊.
嵌入式操作系统 陈香兰 助教:王振明 Spring 2006.
编译程序 构造原理和实现技术 授课教师:吕江花. 第一章 编译程序概述 主要内容: 几个基本概念 编译器的工作过程概述 编译器各个阶段的功能描述 编译程序的实现途径.
嵌入式操作系统 陈香兰 Fall 系统调用 10/27/09 嵌入式 OS 3/12 系统调用的意义  操作系统为用户态进程与硬件设备进行交互提供 了一组接口 —— 系统调用  把用户从底层的硬件编程中解放出来  极大的提高了系统的安全性  使用户程序具有可移植性.
地理信息系统概述. 数据和信息 (Data & Information) 数据 原始事实 如:员工姓名, 数据可以有数值、图形、声音、视觉数据等 信息 以一定规则组织在一起的事实的集合。
吉林大学远程教育课件 主讲人 : 杨凤杰学 时: 64 ( 第六十二讲 ) 离散数学. 最后,我们构造能识别 A 的 Kleene 闭包 A* 的自动机 M A* =(S A* , I , f A* , s A* , F A* ) , 令 S A* 包括所有的 S A 的状态以及一个 附加的状态 s.
1 为了更好的揭示随机现象的规律性并 利用数学工具描述其规律, 有必要引入随 机变量来描述随机试验的不同结果 例 电话总机某段时间内接到的电话次数, 可用一个变量 X 来描述 例 检测一件产品可能出现的两个结果, 也可以用一个变量来描述 第五章 随机变量及其分布函数.
C 语言程序设计 2008 版. C 语言程序设计 教学要求  掌握程序设计语言的基本知识  常用算法  初步的程序设计能力 学习方法  自主学习  重视上机实践.
主讲教师:陈殿友 总课时: 124 第八讲 函数的极限. 第一章 机动 目录 上页 下页 返回 结束 § 3 函数的极限 在上一节我们学习数列的极限,数列 {x n } 可看作自变量 为 n 的函数: x n =f(n),n ∈ N +, 所以,数列 {x n } 的极限为 a, 就是 当自变量 n.
吉林大学远程教育课件 主讲人 : 杨凤杰学 时: 64 ( 第三十八讲 ) 离散数学. 第八章 格与布尔代数 §8.1 引 言 在第一章中我们介绍了关于集 合的理论。如果将 ρ ( S )看做 是集合 S 的所有子集组成的集合, 于是, ρ ( S )中两个集合的并 集 A ∪ B ,两个集合的交集.
嵌入式操作系统 陈香兰 助教:毛熠璐、吴昊 Spring 2008.
Lei Zhao, USTC Gzip 编译及调试 Speaker: Lei Zhao ( 赵雷 ) Department of Computer Science & Technology University of Science & T echnology of China September 13,
协同工作环境研究中心 协同共享 助力科研. 主要内容  认识协同及协同软件  协同科研软件 duckling 介绍.
线性代数习题课 吉林大学 术洪亮 第一讲 行 列 式 前面我们已经学习了关 于行列式的概念和一些基本 理论,其主要内容可概括为:
第二章 随机变量及其分布 第一节 随机变量及其分布函数 一、随机变量 用数量来表示试验的基本事件 定义 1 设试验 的基本空间为 , ,如果对试验 的每一个基 本事件 ,规定一个实数记作 与之对应,这样就得到一个定义在基本空 间 上的一个单值实函数 ,称变量 为随机变量. 随机变量常用字母 、 、 等表示.或用.
第 4 章 过程与变量的作用范围. 4.1 Visual Basic 的代码模块 Visual Basic 的应用程序是由过程组成的, 过程代码存放在模块中。 Visual Basic 提供了 三类模块,它们是窗体模块、标准模块和类 模块。 窗体模块 窗体模块是大多数 Visual Basic.
实验三: 用双线性变换法设计 IIR 数字滤波器 一、实验目的 1 熟悉用双线性变换法设计 IIR 数字滤波器的原理与方法。 2 掌握数字滤波器的计算机仿真方法。 3 通过观察对实际心电图信号的滤波作用, 获得数字滤波的感性知 识。
OS 进程调度模拟演示 制作人: 钱晶 高上上. OS 进程调度模拟-实验原理 静态优先级原理 在这种方式下,系统一旦把处理机分配给就绪队 列中的优先权最高的进程后,该进程便一直执行下去, 直至完成。或因为发生某事件使该进程放弃处理机,系 统方可再将处理机分配给另一优先级最高的进程。这些 事件包括有优先级更高的进程进入,或是因为某些原因.
信息利用与学术论文写作 Library of Jiangsu University, Zhenjiang Sha Zhenjiang
操作系统原理课程设计指南 姜海燕 设计考核幻灯制作  1.1 封皮:系统名称,研制人员  1.2 目的及意义  1.3 功能设计:功能框图、用例图  1.4 结构设计:系统结构  1.5 核心技术及技术路线:画图  1.6 进度安排  1.7 人员安排  1.8.
UML 对象设计与编程 主 讲 : 董兰芳 副教授 Dept. of Computer Science,USTC
主讲教师:陈殿友 总课时: 124 第十一讲 极限的运算法则. 第一章 二、 极限的四则运算法则 三、 复合函数的极限运算法则 一 、无穷小运算法则 机动 目录 上页 下页 返回 结束 §5 极限运算法则.
在发明中学习 线性代数 概念的引入 李尚志 中国科学技术大学. 随风潜入夜 : 知识的引入 之一、线性方程组的解法 加减消去法  方程的线性组合  原方程组的解是新方程的解 是否有 “ 增根 ” ?  互为线性组合 : 等价变形  初等变换  高斯消去法.
嵌入式操作系统 陈香兰 助教:王振明 Spring 2007.
9的乘法口诀 1 .把口诀说完全。 二八( ) 四六( ) 五八( ) 六八( ) 三七( ) 三八( ) 六七( ) 五七( ) 五六( ) 十六 四十八 四十二 二十四 二十一 三十五 四十 二十四 三十 2 .口算, 并说出用的是哪句口诀。 8×8= 4×6= 7×5= 6×8= 5×8=
第 3 章 控制流分析 内容概述 – 定义一个函数式编程语言,变量可以指称函数 – 以 dynamic dispatch problem 为例(作为参数的 函数被调用时,究竟执行的是哪个函数) – 规范该控制流分析问题,定义什么是可接受的控 制流分析 – 定义可接受分析在语义模型上的可靠性 – 讨论分析算法.
吉林大学远程教育课件 主讲人 : 杨凤杰学 时: 64 ( 第五十三讲 ) 离散数学. 定义 设 G= ( V , T , S , P ) 是一个语法结构,由 G 产生的语言 (或者说 G 的语言)是由初始状态 S 演绎出来的所有终止符的集合, 记为 L ( G ) ={w  T *
编译原理总结. 基本概念  编译器 、解释器  编译过程 、各过程的功能  编译器在程序执行过程中的作用  编译器的实现途径.
 符号表  标识符的作用: 声明部分:定义了各种对象及对应的属性和 使用规则。 程序体:对所定义的对象进行各种操作。 $ididname IdnameAttributeIR  必要性 Token : 新表-符号表(种类、类型等信息):
Department of Mathematics 第二章 解析函数 第一节 解析函数的概念 与 C-R 条件 第二节 初等解析函数 第三节 初等多值函数.
1 第 7 章 存储过程、触发器和程序包 在很多时候,都需要保存 PL/SQL 程序块,以便 随后可以重新使用。这也意味着,程序块需要一个名 称,这样需才可以调用或者引用它。命名的 PL/SQL 程序块可被独立编译并存储在数据库中,任何与数据 库相连接的应用程序都可以访问这些存储的 PL/SQL 程序块。
网上预约集港操作指南 一、登录系统 登陆下面图片显示网址:输入堆场用户名、密码和校验码登陆系统.
首 页 首 页 上一页 下一页 本讲内容本讲内容 视图,剖视图(Ⅰ) 复习: P107 ~ P115 作业: P48(6-2,6-4), P49( 去 6-6) P50, P51(6-13), P52 P50, P51(6-13), P52 P53 (6-18,6-20) P53 (6-18,6-20)
《 UML 分析与设计》 交互概述图 授课人:唐一韬. 知 识 图 谱知 识 图 谱知 识 图 谱知 识 图 谱.
如何注册报名? “ 一师一优课、一课一名师 ” 操作解读 如何晒课? 如何注册报名?
常州机电职业技术学院 数控编程与加工技术 精品课程 项目 3 加工中心程序编制 模块 2 方形型腔类零件 上饶职业技术学院 课程负责人:罗根云 2011 年 5 月
华南师范大学教育科学学院 第二步:明确小组成员分工 选举 “ 常任组长 ” 1 名。 所有组员以个人姓名笔画排序 1 、 2 、 3 、 4 、 5 号,轮流担任 “ 轮值组长 ” ,每一周进行轮换。 本次课的轮值组长为 1 号。
读秀学术搜索 是什么? 能够为我们解决 什么问题? 读秀.
1 、如果 x + 5 > 4 ,那么两边都 可得 x >- 1 2 、在- 3y >- 4 的两边都乘以 7 可得 3 、在不等式 — x≤5 的两边都乘以- 1 可得 4 、将- 7x — 6 < 8 移项可得 。 5 、将 5 + a >- 2 a 移项可得 。 6 、将- 8x < 0.
新一代移动物联系统 MC MOBILE CONTROL 开启办公物联网时代 Product Promotion.
项目七: PLC 功能指令应用 带进位循环左移指令 XXXXX. 项目七: PLC 功能指令应用 FX2 系列可编程控制器移位控制指令有移位、循环移位、字移位 及先进先出 FIFO 指令等 10 条指令。 带进位循环右移指令 RCR 带进位循环左移指令 RCL 字右移位指令 WSFR 先入先出读出指令.
第四章 计算机数控( CNC )系统  本章重点:  1 计算机数控系统构成及其结构特点  2 运动轨迹插补原理  3 刀具补偿.
EC 营客通产品操作(九) EC 营客通产品操作(九) 400 电话 400 电话. 400 电话有助于提升企业形象,无论企业地址变更、机构 变化、人员变动,联系方式永远不变。且在 EC 上申请的 400 电话可以在 EC 平台上进行统一的 400 电话接听及 400 电话客服的管理。
超星数字图书馆 一、页面的使用 进入数字图书馆网页 下载超星阅读器 查找图书.
企业产品标准信息公共服务平台 操作介绍 目录 一 、系统架构介绍 二 、企业产品标准自我声明填报系统 三 、企业产品标准公示系统.
表单自定义 “ 表单自定义 ” 功能是用于制作表单的 工具,用数飞 OA 提供的表单自定义 功能能够快速制作出内容丰富、格 式规范、美观的表单。
7 生产费用在完工产品与在产 品之间分配的核算. 2 第七章 生产费用在完工产品与在产品之 间的分配  知识点 :  理解在产品的概念  掌握生产费用在完工产品与在产品之间的分 配.
力的合成 力的合成 一、力的合成 二、力的平行四边形 上一页下一页 目 录 退 出. 一、力的合成 O. O. 1. 合力与分力 我们常常用 一个力来代替几个力。如果这个 力单独作用在物体上的效果与原 来几个力共同作用在物体上的效 果完全一样,那么,这一个力就 叫做那几个力的合力,而那几个 力就是这个力的分力。
算得清写的准 —— 物业费公示报告的编写 讲师:朱芸 物业费的 构成? 哪些是管 理人员工 资呢? 哪些算工程费 用? 怎样才能核 算的清楚呢?
逻辑设计基础 1 第 7 章 多级与(或)非门电路 逻辑设计基础 多级门电路.
“ 百链 ” 云图书馆. 什么是百链云图书馆?1 百链云图书馆的实际效果?2 百链云图书馆的实现原理?3 百链云图书馆的价值?44 图书馆要做什么?55 提 纲.
参考文献管理软件. 常见参考文献管理软件 : 中文 : CNKI E-learning (目前免费) NoteExpress NoteFirst 英文: Refworks Endnote (网络版免费) Mendeley……
开放教育学员入学须知 第一部分:浏览山东理工大学远程与继续 教育学院网站浏览山东理工大学远程与继续 教育学院网站 第二部分:浏览中央电大教学平台浏览中央电大教学平台 第三部分:浏览山东电大教学平台浏览山东电大教学平台 第四部分:浏览淄博电大教学平台浏览淄博电大教学平台 第五部分:淄博电大教学平台使用淄博电大教学平台使用.
八. 真核生物的转录 ㈠ 特点 ① 转录单元为单顺反子( single cistron ),每 个蛋白质基因都有自身的启动子,从而造成在功能 上相关而又独立的基因之间具有更复杂的调控系统。 ② RNA 聚合酶的高度分工,由 3 种不同的酶催化转 录不同的 RNA 。 ③ 需要基本转录因子与转录调控因子的参与,这.
如何开展新学期 “ 导学课 ”. 如何组织 导学课 遇到问题 联系谁 导学课 基本内容 123 目录.
张勤 人大报刊复印资料 专题全文数据库 简 介简 介 《人大报刊资料全文数据库》是中国人民大 学书报资料中心与北京博利群电子信息有限 公司联合开发研制的大型数据库光盘。它涵 盖面广、信息量大、分类科学、筛选严谨、 结构合理,是国内最具权威的社会科学、人.
1 第三章 数列 数列的概念 考点 搜索 ●数列的概念 ●数列通项公式的求解方法 ●用函数的观点理解数列 高考 猜想 以递推数列、新情境下的 数列为载体, 重点考查数列的通 项及性质, 是近年来高考的热点, 也是考题难点之所在.
韩文数据库使用说明 鲁锦松. 主要内容 一、为什么要用数据库 二、怎样利用中文数据库 三、怎样利用韩文数据库.
目录 上页 下页 返回 结束 二、无界函数反常积分的审敛法 * 第五节 反常积分 无穷限的反常积分 无界函数的反常积分 一、无穷限反常积分的审敛法 反常积分的审敛法  函数 第五章 第五章.
SCI 数据库检索练习参考 本练习完全依照 SCI 数据库实际检索过程而 实现。 本练习完全依照 SCI 数据库实际检索过程而 实现。 练习中,选择了可以举一反三的题目,读 者可以根据题目进行另外的检索练习,如: 可将 “ 与 ” 运算检索改为 “ 或 ” 、 “ 非 ” 运算检索 等等。 练习中,选择了可以举一反三的题目,读.
§7.2 估计量的评价标准 上一节我们看到,对于总体 X 的同一个 未知参数,由于采用的估计方法不同,可 能会产生多个不同的估计量.这就提出一 个问题,当总体的一个参数存在不同的估 计量时,究竟采用哪一个好呢?或者说怎 样评价一个估计量的统计性能呢?下面给 出几个常用的评价准则. 一.无偏性.
Presentation transcript:

漫谈 Linux ,龙芯及其软件开发 陈华才

目录 Linux 及相关概念 Linux 及相关概念 Linux 开发者初步教程 Linux 开发者初步教程

Linux 及相关概念 软件 硬件 操作系统 CPU DOS , Windows Linux , Unix X86 , IA64 MIPS , ARM

Linux 及相关概念(续) X86 Linux DOS Windows FreeBSD X86 是使用最广泛的 CPU , Linux 是使用最广泛的 操作系统 X86 是使用最广泛的 CPU , Linux 是使用最广泛的 操作系统 FreeBSD 是 Unix 的一种,可以跑在 X86 PC 上 FreeBSD 是 Unix 的一种,可以跑在 X86 PC 上 龙芯( Godson , Loongson )是 MIPS 的一种 龙芯( Godson , Loongson )是 MIPS 的一种 X86IA64PowerPC 龙芯 Linux

Linux 及相关概念(续) Q : Windows 和 Linux 啥关系? Q : Windows 和 Linux 啥关系? A :决定于在什么平台上: 如果同在 X86 上, Windows 和 Linux 好比是中国人和美国人 的关系(近)。但 X86 上的 Windows 和龙芯上的 Linux 则如 同地球人和火星人的关系(远) 在 Linux/X86 上,可以用 Wine 来运行 Windows 程序,但 Linux/Loongson 上则不行 A :决定于在什么平台上: 如果同在 X86 上, Windows 和 Linux 好比是中国人和美国人 的关系(近)。但 X86 上的 Windows 和龙芯上的 Linux 则如 同地球人和火星人的关系(远) 在 Linux/X86 上,可以用 Wine 来运行 Windows 程序,但 Linux/Loongson 上则不行 Q : Linux/X86 与 Linux/Loongson 啥关系? Q : Linux/X86 与 Linux/Loongson 啥关系? A :一样的皮肤(表象),不一样的基因(本质) 从应用层面和源代码的高级语言层面看来,几乎完全一样。 从编译后的二进制代码看来,完全不同。 A :一样的皮肤(表象),不一样的基因(本质) 从应用层面和源代码的高级语言层面看来,几乎完全一样。 从编译后的二进制代码看来,完全不同。

Linux 与龙芯 龙芯 CPU 系列 龙芯 CPU 系列 – 龙芯一号: 32 位嵌入式 MIPS CPU – 龙芯二号: 64 位通用 MIPS CPU ,有 2A 、 2B 、 2C 、 2D 、 2E 和 2F 等型号(从 2E 开始进入实用阶段) – 龙芯三号: 64 位多核 MIPS CPU ,目前只有 3A Linux 最初只支持 X86 ,后来扩展到其他平台 Linux 最初只支持 X86 ,后来扩展到其他平台 –Linux :开始支持龙芯 2E –Linux :开始支持龙芯 2F

Linux 开发者初步教程 Q : Linux 有没有 VC ?有没有 Java ?有没有 …… ? Q : Linux 有没有 VC ?有没有 Java ?有没有 …… ? A : Linux 支持 C , C++ , Java , Pascal , ADA …… 几乎地球上的每一种编程语言。 但, Linux 不支持 VC ,因为 VC 不是语言,是 IDE (集成开发环境) A : Linux 支持 C , C++ , Java , Pascal , ADA …… 几乎地球上的每一种编程语言。 但, Linux 不支持 VC ,因为 VC 不是语言,是 IDE (集成开发环境) Q : Linux 有没有 IDE ? Q : Linux 有没有 IDE ? A :有。 Qt Creator , KDevelop , Glade …… A :有。 Qt Creator , KDevelop , Glade ……

Linux 开发者初步教程(续) 如果不用 IDE …… 如果不用 IDE …… – 编辑器 + 编译器 + 调试器 – 编辑器: Vim , Emacs , KEdit , GEdit …… Vim 插件,如 cscope , ctags 可用于函数定位 Vim 插件,如 cscope , ctags 可用于函数定位 如果不用插件,文件内用 / 命令搜索,目录内用 grep 命令搜索, find 用于文件名搜索 …… 如果不用插件,文件内用 / 命令搜索,目录内用 grep 命令搜索, find 用于文件名搜索 …… – 编译器: gcc , jdk …… gcc = GNU C Compiler  GNU Compiler Collector gcc = GNU C Compiler  GNU Compiler Collector – 调试器: gdb , ddd …… Linux 可以在纯文本环境下开发任意程序,包括 GUI 程序! Linux 可以在纯文本环境下开发任意程序,包括 GUI 程序!

Linux 开发者初步教程(续) 关于跨平台 关于跨平台 – 源代码跨平台 vs. 目标代码跨平台 前者是一次编写,处处编译( Qt/C++ ) 前者是一次编写,处处编译( Qt/C++ ) 后者是一次编译,处处运行( Java ) 后者是一次编译,处处运行( Java ) – 跨操作系统 vs. 跨硬件平台 Wine , Cygwin 等 API 模拟器即可实现跨操作系统 (硬件平台相同) Wine , Cygwin 等 API 模拟器即可实现跨操作系统 (硬件平台相同) Java , Python 脚本语言才可以跨硬件平台 Java , Python 脚本语言才可以跨硬件平台

如何参与 Linux 软件开发? Linux User 当久了,想成为一个 Linux Developer Linux User 当久了,想成为一个 Linux Developer –1 ,作为用户,给开发者提需求 –2 ,作为测试员,给开发者反映 Bug –3 ,包装开发,如制作 RPM 、 DEB 等软件包 –4 ,直接参与代码编写

如何阅读代码? 参与代码编写第一步,阅读已有的代码 参与代码编写第一步,阅读已有的代码 一个动辄上万行代码的工程,如何读懂, 从哪里读起? 一个动辄上万行代码的工程,如何读懂, 从哪里读起? –1 ,如果有文档 / 书籍,参照阅读 –2 ,如果没有文档(自由软件大都文档不全) 找准入口点 找准入口点 理清主脉络 理清主脉络 顾名思义看功能 顾名思义看功能

如何阅读代码?(续) 找准入口点 找准入口点 – 高级语言( C 语言) 应用程序:从 main() 开始 应用程序:从 main() 开始 内核模块:从 XXX_init() 开始 搜索关键语句 module_init(XXX_init); 内核模块:从 XXX_init() 开始 搜索关键语句 module_init(XXX_init); 内核本身: Linux 内核从 __start_kernel() 开始 Xen 内核从 __start_xen() 开始 内核本身: Linux 内核从 __start_kernel() 开始 Xen 内核从 __start_xen() 开始 – 汇编语言 可能从 start/_start 等类似词汇的标号处开始,大多 会用.global/.globl 伪指令标识 可能从 start/_start 等类似词汇的标号处开始,大多 会用.global/.globl 伪指令标识

如何阅读代码?(续) 理清主脉络 理清主脉络 – 去粗取精,眼不见为净,去掉没用的,留下有用的。 1 ,代码 vs. 注释 1 ,代码 vs. 注释 – 去掉 // … /* … */ #if 0 … #endif 2 ,程序流程 vs. 变量声明 2 ,程序流程 vs. 变量声明 – 去掉变量声明,简单赋值 3 ,功能语句 vs. 调试语句 3 ,功能语句 vs. 调试语句 – 去掉 printf(), printk(), debug() … 4 ,正常流程 vs. 异常流程 4 ,正常流程 vs. 异常流程 – 去掉返回值检查, try-catch 中的 catch 子句 …… 5 ,常见路径 vs. 罕见路径 5 ,常见路径 vs. 罕见路径 –Switch , if-else 结构等只保留最常见的一种情况

如何阅读代码?(续) 举例: Gxemul 举例: Gxemul – 一个运行在 X86 上的龙芯模拟器 – 入口点是 main() 函数

int main(int argc, char *argv[]) { /* Setting constants: */ const int constant_yes = 1; const int constant_true = 1; const int constant_no = 0; const int constant_false = 0; struct emul **emuls; char **diskimages = NULL; int n_diskimages = 0; int n_emuls; int i; progname = argv[0]; /* Initialize all emulator subsystems: */ console_init(); cpu_init(); device_init(); machine_init(); timer_init(); useremul_init(); emuls = malloc(sizeof(struct emul *)); if (emuls == NULL) { fprintf(stderr, "out of memory\n"); exit(1); } /* Allocate space for a simple emul setup: */ n_emuls = 1; emuls[0] = emul_new(NULL); if (emuls[0] == NULL) { fprintf(stderr, "out of memory\n"); exit(1); } get_cmd_args(argc, argv, emuls[0], &diskimages, &n_diskimages); if (!skip_srandom_call) { struct timeval tv; gettimeofday(&tv, NULL); srandom(tv.tv_sec ^ getpid() ^ tv.tv_usec); } /* Print startup message: */ debug("GXemul"); debug(" Copyright (C) Anders Gavare\n"); debug("Read the source code and/or documentation for other Copyright messages.\n\n"); if (emuls[0]->machines[0]->machine_type == MACHINE_NONE) { n_emuls --; } else { for (i=0; i machines[0], diskimages[i]); } /* Simple initialization, from command line arguments: */ if (n_emuls > 0) { /* Make sure that there are no configuration files as well: */ for (i=1; i<argc; i++) if (argv[i][0] == { fprintf(stderr, "You can either start one " "emulation with one machine directly from " "the command\nline, or start one or more " "emulations using configuration files." " Not both.\n"); exit(1); } /* Initialize one emul: */ emul_simple_init(emuls[0]); } /* Initialize emulations from config files: */ for (i=1; i<argc; i++) { if (argv[i][0] == { char tmpstr[50]; char *s = argv[i] + 1; if (strlen(s) == 0 && i+1 < argc && argv[i+1][0] != { i++; s = argv[i]; } n_emuls ++; emuls = realloc(emuls, sizeof(struct emul *) * n_emuls); if (emuls == NULL) { fprintf(stderr, "out of memory\n"); exit(1); } /* Always allow slave xterms when using multiple emulations: */ console_allow_slaves(1); /* Destroy the temporary emuls[0], since it will be overwritten: */ if (n_emuls == 1) { emul_destroy(emuls[0]); } emuls[n_emuls - 1] = emul_create_from_configfile(s); snprintf(tmpstr, sizeof(tmpstr), "emul[%i]", n_emuls-1); } if (n_emuls == 0) { fprintf(stderr, "No emulations defined. Maybe you forgot to " "use -E xx and/or -e yy, to specify\nthe machine type." " For example:\n\n %s -e 3max -d disk.img\n\n" "to boot an emulated DECstation 5000/200 with a disk " "image.\n", progname); exit(1); } device_set_exit_on_error(0); console_warn_if_slaves_are_needed(1); /* Run all emulations: */ emul_run(emuls, n_emuls); /* * Deinitialize everything: */ console_deinit(); for (i=0; i<n_emuls; i++) emul_destroy(emuls[i]); return 0; } int main(int argc, char *argv[]) { const int constant_yes = 1; const int constant_true = 1; const int constant_no = 0; const int constant_false = 0; struct emul **emuls; char **diskimages = NULL; int n_diskimages = 0; int n_emuls; int i; progname = argv[0]; console_init(); cpu_init(); device_init(); machine_init(); timer_init(); useremul_init(); emuls = malloc(sizeof(struct emul *)); if (emuls == NULL) { fprintf(stderr, "out of memory\n"); exit(1); } n_emuls = 1; emuls[0] = emul_new(NULL); if (emuls[0] == NULL) { fprintf(stderr, "out of memory\n"); exit(1); } get_cmd_args(argc, argv, emuls[0], &diskimages, &n_diskimages); if (!skip_srandom_call) { struct timeval tv; gettimeofday(&tv, NULL); srandom(tv.tv_sec ^ getpid() ^ tv.tv_usec); } debug("GXemul"); debug(" Copyright (C) Anders Gavare\n"); debug("Read the source code and/or documentation for other Copyright messages.\n\n"); if (emuls[0]->machines[0]->machine_type == MACHINE_NONE) { n_emuls --; } else { for (i=0; i machines[0], diskimages[i]); } if (n_emuls > 0) { for (i=1; i<argc; i++) if (argv[i][0] == { fprintf(stderr, "You can either start one " "emulation with one machine directly from " "the command\nline, or start one or more " "emulations using configuration files." " Not both.\n"); exit(1); } emul_simple_init(emuls[0]); } for (i=1; i<argc; i++) { if (argv[i][0] == { char tmpstr[50]; char *s = argv[i] + 1; if (strlen(s) == 0 && i+1 < argc && argv[i+1][0] != { i++; s = argv[i]; } n_emuls ++; emuls = realloc(emuls, sizeof(struct emul *) * n_emuls); if (emuls == NULL) { fprintf(stderr, "out of memory\n"); exit(1); } console_allow_slaves(1); if (n_emuls == 1) { emul_destroy(emuls[0]); } emuls[n_emuls - 1] = emul_create_from_configfile(s); snprintf(tmpstr, sizeof(tmpstr), "emul[%i]", n_emuls-1); } if (n_emuls == 0) { fprintf(stderr, "No emulations defined. Maybe you forgot to " "use -E xx and/or -e yy, to specify\nthe machine type." " For example:\n\n %s -e 3max -d disk.img\n\n" "to boot an emulated DECstation 5000/200 with a disk " "image.\n", progname); exit(1); } device_set_exit_on_error(0); console_warn_if_slaves_are_needed(1); emul_run(emuls, n_emuls); console_deinit(); for (i=0; i<n_emuls; i++) emul_destroy(emuls[i]); return 0; } 去掉注释 105 行变 92 行

int main(int argc, char *argv[]) { const int constant_yes = 1; const int constant_true = 1; const int constant_no = 0; const int constant_false = 0; struct emul **emuls; char **diskimages = NULL; int n_diskimages = 0; int n_emuls; int i; progname = argv[0]; console_init(); cpu_init(); device_init(); machine_init(); timer_init(); useremul_init(); emuls = malloc(sizeof(struct emul *)); if (emuls == NULL) { fprintf(stderr, "out of memory\n"); exit(1); } n_emuls = 1; emuls[0] = emul_new(NULL); if (emuls[0] == NULL) { fprintf(stderr, "out of memory\n"); exit(1); } get_cmd_args(argc, argv, emuls[0], &diskimages, &n_diskimages); if (!skip_srandom_call) { struct timeval tv; gettimeofday(&tv, NULL); srandom(tv.tv_sec ^ getpid() ^ tv.tv_usec); } debug("GXemul"); debug(" Copyright (C) Anders Gavare\n"); debug("Read the source code and/or documentation for other Copyright messages.\n\n"); if (emuls[0]->machines[0]->machine_type == MACHINE_NONE) { n_emuls --; } else { for (i=0; i machines[0], diskimages[i]); } if (n_emuls > 0) { for (i=1; i<argc; i++) if (argv[i][0] == { fprintf(stderr, "You can either start one " "emulation with one machine directly from " "the command\nline, or start one or more " "emulations using configuration files." " Not both.\n"); exit(1); } emul_simple_init(emuls[0]); } for (i=1; i<argc; i++) { if (argv[i][0] == { char tmpstr[50]; char *s = argv[i] + 1; if (strlen(s) == 0 && i+1 < argc && argv[i+1][0] != { i++; s = argv[i]; } n_emuls ++; emuls = realloc(emuls, sizeof(struct emul *) * n_emuls); if (emuls == NULL) { fprintf(stderr, "out of memory\n"); exit(1); } console_allow_slaves(1); if (n_emuls == 1) { emul_destroy(emuls[0]); } emuls[n_emuls - 1] = emul_create_from_configfile(s); snprintf(tmpstr, sizeof(tmpstr), "emul[%i]", n_emuls-1); } if (n_emuls == 0) { fprintf(stderr, "No emulations defined. Maybe you forgot to " "use -E xx and/or -e yy, to specify\nthe machine type." " For example:\n\n %s -e 3max -d disk.img\n\n" "to boot an emulated DECstation 5000/200 with a disk " "image.\n", progname); exit(1); } device_set_exit_on_error(0); console_warn_if_slaves_are_needed(1); emul_run(emuls, n_emuls); console_deinit(); for (i=0; i<n_emuls; i++) emul_destroy(emuls[i]); return 0; } int main(int argc, char *argv[]) { console_init(); cpu_init(); device_init(); machine_init(); timer_init(); useremul_init(); emuls = malloc(sizeof(struct emul *)); if (emuls == NULL) { fprintf(stderr, "out of memory\n"); exit(1); } emuls[0] = emul_new(NULL); if (emuls[0] == NULL) { fprintf(stderr, "out of memory\n"); exit(1); } get_cmd_args(argc, argv, emuls[0], &diskimages, &n_diskimages); if (!skip_srandom_call) { gettimeofday(&tv, NULL); srandom(tv.tv_sec ^ getpid() ^ tv.tv_usec); } debug("GXemul"); debug(" Copyright (C) Anders Gavare\n"); debug("Read the source code and/or documentation for other Copyright messages.\n\n"); if (emuls[0]->machines[0]->machine_type == MACHINE_NONE) { n_emuls --; } else { for (i=0; i machines[0], diskimages[i]); } if (n_emuls > 0) { for (i=1; i<argc; i++) if (argv[i][0] == { fprintf(stderr, "You can either start one " "emulation with one machine directly from " "the command\nline, or start one or more " "emulations using configuration files." " Not both.\n"); exit(1); } emul_simple_init(emuls[0]); } for (i=1; i<argc; i++) { if (argv[i][0] == { if (strlen(s) == 0 && i+1 < argc && argv[i+1][0] != { i++; s = argv[i]; } n_emuls ++; emuls = realloc(emuls, sizeof(struct emul *) * n_emuls); if (emuls == NULL) { fprintf(stderr, "out of memory\n"); exit(1); } console_allow_slaves(1); if (n_emuls == 1) { emul_destroy(emuls[0]); } emuls[n_emuls - 1] = emul_create_from_configfile(s); snprintf(tmpstr, sizeof(tmpstr), "emul[%i]", n_emuls-1); } if (n_emuls == 0) { fprintf(stderr, "No emulations defined. Maybe you forgot to " "use -E xx and/or -e yy, to specify\nthe machine type." " For example:\n\n %s -e 3max -d disk.img\n\n" "to boot an emulated DECstation 5000/200 with a disk " "image.\n", progname); exit(1); } device_set_exit_on_error(0); console_warn_if_slaves_are_needed(1); emul_run(emuls, n_emuls); console_deinit(); for (i=0; i<n_emuls; i++) emul_destroy(emuls[i]); return 0; } 去掉变量声明 92 行变 76 行

int main(int argc, char *argv[]) { console_init(); cpu_init(); device_init(); machine_init(); timer_init(); useremul_init(); emuls = malloc(sizeof(struct emul *)); if (emuls == NULL) { fprintf(stderr, "out of memory\n"); exit(1); } emuls[0] = emul_new(NULL); if (emuls[0] == NULL) { fprintf(stderr, "out of memory\n"); exit(1); } get_cmd_args(argc, argv, emuls[0], &diskimages, &n_diskimages); if (!skip_srandom_call) { gettimeofday(&tv, NULL); srandom(tv.tv_sec ^ getpid() ^ tv.tv_usec); } debug("GXemul"); debug(" Copyright (C) Anders Gavare\n"); debug("Read the source code and/or documentation for other Copyright messages.\n\n"); if (emuls[0]->machines[0]->machine_type == MACHINE_NONE) { n_emuls --; } else { for (i=0; i machines[0], diskimages[i]); } if (n_emuls > 0) { for (i=1; i<argc; i++) if (argv[i][0] == { fprintf(stderr, "You can either start one " "emulation with one machine directly from " "the command\nline, or start one or more " "emulations using configuration files." " Not both.\n"); exit(1); } emul_simple_init(emuls[0]); } for (i=1; i<argc; i++) { if (argv[i][0] == { if (strlen(s) == 0 && i+1 < argc && argv[i+1][0] != { i++; s = argv[i]; } n_emuls ++; emuls = realloc(emuls, sizeof(struct emul *) * n_emuls); if (emuls == NULL) { fprintf(stderr, "out of memory\n"); exit(1); } console_allow_slaves(1); if (n_emuls == 1) { emul_destroy(emuls[0]); } emuls[n_emuls - 1] = emul_create_from_configfile(s); snprintf(tmpstr, sizeof(tmpstr), "emul[%i]", n_emuls-1); } if (n_emuls == 0) { fprintf(stderr, "No emulations defined. Maybe you forgot to " "use -E xx and/or -e yy, to specify\nthe machine type." " For example:\n\n %s -e 3max -d disk.img\n\n" "to boot an emulated DECstation 5000/200 with a disk " "image.\n", progname); exit(1); } device_set_exit_on_error(0); console_warn_if_slaves_are_needed(1); emul_run(emuls, n_emuls); console_deinit(); for (i=0; i<n_emuls; i++) emul_destroy(emuls[i]); return 0; } int main(int argc, char *argv[]) { console_init(); cpu_init(); device_init(); machine_init(); timer_init(); useremul_init(); emuls = malloc(sizeof(struct emul *)); emuls[0] = emul_new(NULL); get_cmd_args(argc, argv, emuls[0], &diskimages, &n_diskimages); if (!skip_srandom_call) { gettimeofday(&tv, NULL); srandom(tv.tv_sec ^ getpid() ^ tv.tv_usec); } if (emuls[0]->machines[0]->machine_type == MACHINE_NONE) { n_emuls --; } else { for (i=0; i<n_diskimages; i++) diskimage_add(emuls[0]->machines[0], diskimages[i]); } if (n_emuls > 0) { for (i=1; i<argc; i++) if (argv[i][0] == { exit(1); } emul_simple_init(emuls[0]); } for (i=1; i<argc; i++) { if (argv[i][0] == { if (strlen(s) == 0 && i+1 < argc && argv[i+1][0] != { i++; s = argv[i]; } n_emuls ++; emuls = realloc(emuls, sizeof(struct emul *) * n_emuls); console_allow_slaves(1); if (n_emuls == 1) { emul_destroy(emuls[0]); } emuls[n_emuls - 1] = emul_create_from_configfile(s); } if (n_emuls == 0) { exit(1); } device_set_exit_on_error(0); console_warn_if_slaves_are_needed(1); emul_run(emuls, n_emuls); console_deinit(); for (i=0; i<n_emuls; i++) emul_destroy(emuls[i]); return 0; } 去掉调试语句 76 行变 53 行

int main(int argc, char *argv[]) { console_init(); cpu_init(); device_init(); machine_init(); timer_init(); useremul_init(); emuls = malloc(sizeof(struct emul *)); emuls[0] = emul_new(NULL); get_cmd_args(argc, argv, emuls[0], &diskimages, &n_diskimages); if (!skip_srandom_call) { gettimeofday(&tv, NULL); srandom(tv.tv_sec ^ getpid() ^ tv.tv_usec); } if (emuls[0]->machines[0]->machine_type == MACHINE_NONE) { n_emuls --; } else { for (i=0; i<n_diskimages; i++) diskimage_add(emuls[0]->machines[0], diskimages[i]); } if (n_emuls > 0) { for (i=1; i<argc; i++) if (argv[i][0] == { exit(1); } emul_simple_init(emuls[0]); } for (i=1; i<argc; i++) { if (argv[i][0] == { if (strlen(s) == 0 && i+1 < argc && argv[i+1][0] != { i++; s = argv[i]; } n_emuls ++; emuls = realloc(emuls, sizeof(struct emul *) * n_emuls); console_allow_slaves(1); if (n_emuls == 1) { emul_destroy(emuls[0]); } emuls[n_emuls - 1] = emul_create_from_configfile(s); } if (n_emuls == 0) { exit(1); } device_set_exit_on_error(0); console_warn_if_slaves_are_needed(1); emul_run(emuls, n_emuls); console_deinit(); for (i=0; i<n_emuls; i++) emul_destroy(emuls[i]); return 0; } int main(int argc, char *argv[]) { console_init(); cpu_init(); device_init(); machine_init(); timer_init(); useremul_init(); emuls = malloc(sizeof(struct emul *)); emuls[0] = emul_new(NULL); get_cmd_args(argc, argv, emuls[0], &diskimages, &n_diskimages); if (!skip_srandom_call) { gettimeofday(&tv, NULL); srandom(tv.tv_sec ^ getpid() ^ tv.tv_usec); } if (emuls[0]->machines[0]->machine_type == MACHINE_NONE) { n_emuls --; } else { for (i=0; i<n_diskimages; i++) diskimage_add(emuls[0]->machines[0], diskimages[i]); } if (n_emuls > 0) { emul_simple_init(emuls[0]); } for (i=1; i<argc; i++) { if (argv[i][0] == { if (strlen(s) == 0 && i+1 < argc && argv[i+1][0] != { i++; s = argv[i]; } n_emuls ++; emuls = realloc(emuls, sizeof(struct emul *) * n_emuls); console_allow_slaves(1); if (n_emuls == 1) { emul_destroy(emuls[0]); } emuls[n_emuls - 1] = emul_create_from_configfile(s); } emul_run(emuls, n_emuls); console_deinit(); for (i=0; i<n_emuls; i++) emul_destroy(emuls[i]); return 0; } 去掉异常处理 53 行变 44 行

int main(int argc, char *argv[]) { console_init(); cpu_init(); device_init(); machine_init(); timer_init(); useremul_init(); emuls = malloc(sizeof(struct emul *)); emuls[0] = emul_new(NULL); get_cmd_args(argc, argv, emuls[0], &diskimages, &n_diskimages); if (!skip_srandom_call) { gettimeofday(&tv, NULL); srandom(tv.tv_sec ^ getpid() ^ tv.tv_usec); } if (emuls[0]->machines[0]->machine_type == MACHINE_NONE) { n_emuls --; } else { for (i=0; i<n_diskimages; i++) diskimage_add(emuls[0]->machines[0], diskimages[i]); } if (n_emuls > 0) { emul_simple_init(emuls[0]); } for (i=1; i<argc; i++) { if (argv[i][0] == { if (strlen(s) == 0 && i+1 < argc && argv[i+1][0] != { i++; s = argv[i]; } n_emuls ++; emuls = realloc(emuls, sizeof(struct emul *) * n_emuls); console_allow_slaves(1); if (n_emuls == 1) { emul_destroy(emuls[0]); } emuls[n_emuls - 1] = emul_create_from_configfile(s); } emul_run(emuls, n_emuls); console_deinit(); for (i=0; i<n_emuls; i++) emul_destroy(emuls[i]); return 0; } int main(int argc, char *argv[]) { console_init(); cpu_init(); device_init(); machine_init(); timer_init(); useremul_init(); emuls = malloc(sizeof(struct emul *)); emuls[0] = emul_new(NULL); get_cmd_args(argc, argv, emuls[0], &diskimages, &n_diskimages); for (i=0; i<n_diskimages; i++) diskimage_add(emuls[0]->machines[0], diskimages[i]); if (n_emuls > 0) { emul_simple_init(emuls[0]); } emul_run(emuls, n_emuls); console_deinit(); for (i=0; i<n_emuls; i++) emul_destroy(emuls[i]); return 0; } 去掉罕见路径 44 行变 24 行

最终处理 去掉参数处理,内存分配 / 释放操作 … 去掉参数处理,内存分配 / 释放操作 … 顾名思义看功能 顾名思义看功能 int main(int argc, char *argv[]) { console_init(); // 控制台初始化 cpu_init(); //CPU 初始化 device_init(); // 设备初始化 machine_init(); // 机器架构初始化 timer_init(); // 时钟初始化 useremul_init(); // 用户模拟器初始化 emuls[0] = emul_new(NULL); // 构建模拟的机器 diskimage_add(emuls[0]->machines[0], diskimages[i]); // 给机器添加磁盘 emul_simple_init(emuls[0]); // 模拟机器初始化 emul_run(emuls, n_emuls); // 运行模拟机器 console_deinit(); // 控制台销毁 emul_destroy(emuls[i]); // 模拟机器销毁 return 0; // 返回 } 是不是很 简单?

几点看法 学习 Linux ≠ 仇视 Windows 学习 Linux ≠ 仇视 Windows – 存在的就是合理的, Windows 有其优点 – 仇视微软是一种病态 -- Linus Torvalds –Linux 要吸收 Windows 的优点 学习 Linux ≠ 抛弃 Windows 学习 Linux ≠ 抛弃 Windows – 各取所需,要什么用什么 – 和谐共处,双系统并不丢人 学习 Linux ≠ 抛弃 GUI 学习 Linux ≠ 抛弃 GUI – 爱美之心人皆有之, KDE/Gnome 有功无罪 – 命令行不是拿来炫耀的,而是给人多一种选择 学习 Linux ≠ 人云亦云 学习 Linux ≠ 人云亦云 – 真正的高手大都低调,哗众取宠的大都是半吊子 – 谁用谁知道,没有调查就没有发言权

谢谢! 欢迎提问