ENGG1340 Computer Programming II
课程内容笔记,自用,不涉及任何 assignment,exam 答案
Notes for self use, not included any assignments or exams
Module 0
主要介绍了几种远程登录 CS department 主机的方式
\(SSH\) (安全外壳协议, Secure shell)
先使用 SSH 登入gatekeeper
服务器,再登入academy
服务器
若使用 HKUVPN 可直接 SSH 登入 academy 服务器
SSH 连接在命令提示符中进行,因此只能通过指令交互,无 GUI (图形界面,Graphical User Interface)X2Go Client
\(SFTP\) (SSH 文件传输协议,SSH File Transfer Protocol)
与 SSH 相同,无法直接登入academy
服务器且无 GUI
适合进行远端与近端的文件传输FileZilla (一种 SFTP Client)
Module 1
Why Linux?
- 开源 (open-source software)
- 海量的软件开发工具 (software development tools)
- 免费
Using Linux Shell
Linux 中的 Shell 是一种基于文本的程序 (text-based program),其接受用户的指令并执行相应的任务 (类似 win 中的命令提示符 cmd)
本课程中使用的 Shell 为 Bash Shell
Shell commands:
- directory management
- file management
- a special use for cat command
- other useful commands
有关这些命令的 flag 以及详细用法查阅原 pdf
需要重点认识文件比较命令diff file1 file2
的原理:它给出了一个将file1
按行转化为file2
的方案
Use of vi editor:
vi 编辑器是 unix/linux 系统中的一种基于命令行的文本编辑器 (command-line text editor),没有图形用户界面
在 shell 中使用 vi filename
来用 vi 编辑器打开文件 filename,如果没有这个名字的文件,vi 编辑器将会新建一个
vi 编辑器有两种模式:
- 插入模式 Insert mode: 编辑文本所用的模式,按 \(I\) 启用
- 命令模式 Command mode:执行命令所用的模式,按 \(Esc\) 启用。首次打开某个文件 vi 编辑器将会处于命令模式
File permission:
intro
Linux 系统中,每个文件与目录都被赋予了两个属性,所有者 (ownership) 与访问权限 (permission, or access rights)
所有者属性分为三种:- 用户 User:用户 User 是文件的所有者
- 组 Group:一个组 Group 包含很多用户,同组的用户对某文件的访问权限是相同的
- 其他用户 Other
对于每类所有者,文件与目录访问权限也分为三种:
- 读 Read:文件的可读权限意味着允许打开并浏览文件,目录的可读权限意味着允许浏览目录中的内容
- 写 Write:文件的可写权限意味着可以对一个文件进行修改,目录的可写权限意味着可以添加,删除或重命名目录中的文件
- 执行 Execute
display permission
使用ls -l
命令可以显示文件或目录的 permission indicator
第一个字符 (\(-/d\)):\(-\) 代表文件 file,\(d\) 代表目录 directory
后九个字符分为三组,分别指示用户/组/其他用户的读/写/执行权限change permission
使用命令chmod
来改变文件/目录的权限,具体格式为chmod [who][operator][permissions] filename
[who]
代表修改的所有者
[operator]
代表改变的操作 (add/remove/set permission)
[permission]
代表需要添加/去除的权限
下例描述了给文件file
的 其他用户 (other) 添加 读写 (read & write) 权限的过程
Standard I/O, file redirection & Pipe
file descriptor
Shell 中的命令经常关联一些开放文件。我们使用 文件标识符 file descriptor 来标记这些文件的类型。具体来说
标准错误 (stderr) 文件用来储存命令执行失败弹出的错误信息redirection operator
通常来讲,当我们执行命令的时候,输出会在屏幕上显示。我们可以使用 重定向符 redirection operator>
将输出重定向至文件 file.txt 中
例如,我们想将命令ls -l
的结果输出至文件 file.txt 中,可以如下例使用重定向符
以下是几个重定向符>
,>>
,<
, 与<<
的含义与它们的常见用法
将标准输出与标准错误重定向至同一个文件 result.txt
对于 a.cpp,先使用命令g++ a.cpp -o a
编译为可执行文件 a,再使用./a < in.txt > out.txt
文件输入输出。这样就不用在程序内部使用freopen
重定向了pipe
有时我们想将某个程序的输出重定向作为另一个程序的输入:例如
此时,Shell 将会打印出所有包含 Jan 26 的行
然而,这个方法创建了一个中介文件 file.txt。有什么方法可以直接将ls
的结果重定向至grep
中而不用创建一个临时文件进行存储呢
我们可以用管道 pipe|
来做到
Searching for files/directories (find)
命令 find
的格式如下
例:我们想由 当前目录 (current directory) 开始寻找所有前缀为 hello. 的 文件
$ find . -name "hello.*" -type f
(注意:.
代表的是当前目录 current directory)
Searching inside a file (grep) and regular expression
grep using regular expression
之前我们介绍了grep
命令:grep 'abc' file
即搜索并打印文件 file 中所有包含字符串 abc 的行
而grep
命令的全称为 全局正则表达式打印 (Global regular expression print),其参数是可以使用正则表达式表示的,具体格式为
(不使用 flag-E
时使用的是原始的根据给出字符串搜索打印)正则表达式中的特殊字符
.
字符.
匹配任意的单个字符 (any single character)
例:'n..d' 匹配 'nMMd'^
与$
字符^
必须匹配行首,字符$
必须匹配行尾
例:'^apple' 不能匹配 '* apple*' 因为行首字符是空格而不是 'a'?
,+
与*
例:
'abc?' 匹配 'abc' 或者 'ab'
'abc+' 匹配 'abc' 或者 'abccccc'
'abc*' 匹配 'ab', 'abc' 或者 'abcccccccc'
也可以配合使用,如 'a.*c' 可以匹配任意由 'a' 开头,'c' 结尾的字符串- 小括号
()
代表一串字串,例:
'(co)+' 匹配 'co' 或者 'coco' 或者 'cocococo',字符+
对子串 'co' 起效果
若不加小括号,'co+' 中的字符+
就只对字母 'o' 起效果了 - 中括号
[]
中括号匹配中括号中的字符集中的任意一个字符,例:
'[0123456789]' 或 '[0-9]' 匹配 \(0\) 到 \(9\) 中的任意一个整数
'[A-Z]' 匹配任意一个大写字母
'[A-Za-z]' 匹配任意一个字母 (大小写都有) - 大括号
{}
大括号用于表示某个模式重复的次数 (更加精确的?
,+
与*
)
'a' 可以匹配 'a' 或 'aa'
'a' 可以匹配 'aaa' 或 'aaaa' 或 'aaaaaaa'
extension of 2
Module 2
介绍了 编写 .sh
脚本的方法与 Git (一种分散式版本控制系统,distributed version control system)
Module 3
C++ 基础,这个就是小 case 了,在这里记录一些边边角角
编译命令 g++ -pedantic-errors -std=c++11 hello.cpp -o hello
identifier 即变量名 variable name
operator 运算符 & operand 运算数
Division By Zero
错误是 runtime error,并不会产生编译错误信息
运算符的 precedence (优先级) 与 associativity (结合律)
使用 ()
来 override precedence & associativity
逻辑运算中的 short-circuit evaluation (短路求值)
类型转换 Type Conversion:
- lower type promoted to higher type
例:3(int, lower type)/2.0 (double, higher type)
,operand \(3\) 类型由int
转为double
,此时 operator/
执行双精浮点数除法 - In assignment statements, the value of the right side is converted to the type of the left
例:int x = 2.5
等号右边的 \(2.5\) 因为被赋给int
型变量,其类型由double(2.5)
转化为int(2)
escape sequence
控制流 (flow of control)
Specifying Block statement : C/C++ V.S. Python
Python : 缩进 Indentation
C/C++ : {}
switch-case statement:
见该例,着重注意 break
在 switch 语句中的处理
当 case
中的 expression 与 switch
中的 expression 匹配时,将会执行该 case 下的所有语句,直至遇到 break
(缺少 break
的 switch
语句,case 7:
下的所有语句都被执行)
Module 4
这一章还是挺重要的,之前没有接触过
主要介绍了 Multiple Source File,File Dependency 文件依赖 与 makefile
Separate Compilation
Multiple Source Files
之前我所接触的都是 Single Source File
一个源文件一次编译一次运行,不用脑子
这是因为我没有接触过大型的 project: Multiple Source Files 有两个优势- 将各种 features 与主程序 main 分离,提升代码组织性与可读性
- 允许其他程序复用 features
具体来说,我们将需要分离的 feature 从 main 源文件 (.cpp) 中取出
其 声明 (declaration) 组织在自定义的头文件 (.h) 中,定义 (definition) 组织在另一源文件 (.cpp) 中 (这样是为了防止同样的文件被 include 多次)
(main 源文件
gcd_main.cpp)
(gcd 源文件 gcd.cpp,包含 gcd 的定义)
(gcd 头文件 gcd.h,包含 gcd 的声明)
注意,所有的源文件都需要被编译 (头文件不需要被编译,它可以视作一个宏)编译过程 Compilation Process
分别是 预处理 (处理头文件), 编译 (将代码编译成组合代码 Assembly code), 汇编 (将 Assembly Code 编译成机器码 machine code,此时是.obj
文件的形式), 链接 (将所有的obj
文件都链接在一起)
- Separate Compilation
可以发现 pre-process, compilation 与 assembly 过程均是独立的,只需要单一的目标源文件
因此,在 link 之前,我们可以分别对每个源文件进行前三个编译过程以得到 object codes,再进行 link 过程对其进行连接得到最终的 executable
这样的编译方案称为 Separate Compilation
Separate Compilation 有以下几个优点- 允许对不同的源文件分别进行编写与编译,并且分别测试其 object codes 的运行情况
- 对某个 project 进行修改时,只有受影响的源文件需要重编译 (recompile) : 这样可大大减少编译时间
- 只向用户提供 object codes 用于运行,从而隐藏真正的类型实现
例子:
对 gcd.cpp
, gcd_main.cpp
分别编译得到 object codes gcd.o
与 gcd_main.o
当所有源文件均生成 object codes 后,进行 link 过程得到 final executable gcd
- File Dependency 文件依赖性
上图展示了一个简单的文件依赖树。举例来说,若对源文件 calc.cpp
进行修改,则 calc.o
需要重编译并与未修改的 lcm.o
与 gcd.o
进行 link 以生成 final executable
(可看出 separate compilation 的优越性:lcm.o
与 gcd.o
都不需要进行重编译)
当情况更加复杂时,我们需要借助其它的工具来简化重编译过程
Using the make tool
- The make tool
当源文件被修改时, Linux 的make
命令能够很方便的对受到影响的文件进行重编译 (recompile) 与链接 (link)
make
尝试避免不必要的重编译与文件的重新生成
为了实现这个功能,我们需要向make
命令提供文件的依赖性:储存文件依赖性的文件应被命名为MakeFile
MakeFile
文件的格式如上
有几个小注意,g++
中的-c
参数代表进行预处理,编译,汇编三个步骤,因此最终产生的是 object codes
-o
参数代表自定义生成程序的名称,而不是采取默认名称
make
working procedure
我们将需要 生成 (generate / regenerate) 的文件称为目标文件 (target)
make
在进行工作时 (我以伪代码的形式展示,大体思路相同)
File MakeFile[] // MakeFile is a tree
int upToDate(string FileName) {
if (MakeFile[FileName] == NULL) return 0;
for (i iterate through sons) {
if (sons.LastModificationTime > MakeFile[FileName].Lastmodification time)
return 0;
}
return 1;
}
void make(string FileName) {
for (i iterate through sons) {
if (!upToDate(i)) make(i);
}
if (upToDate(FileName))
return; // if the current file is up to date after its dependency is updated, then return
recompile(MakeFile[FileName]); // using the command in the MakeFile
MakeFile[FileName].LastModificationTime = CurrentTime;
}
make(target); // target is the root of MakeFile (usually)
采用这样的策略,能够使得某个源文件被修改后,需要 regenerate 的文件数目最少
make
奇淫技巧 1 :MakeFile 中的变量
在 MakeFile 中,可以定义变量来指代文件
用$(variableName)
进行文本替换
另外,MakeFile 中定义了默认的三个变量@
,<
与^
,它们分别指代
注意:头文件.h
是不用进行编译的!make
奇淫技巧 2:假目标 Phony Target
我们可以通过 MakeFile 与假目标简化命令
以clean
命令为例
当 directory 中没有名为clean
的文件时,执行make clean
make
将会发现clean
是过时的 (因为它根本就不存在),于是执行 MakeFile 中记录的命令
以这种形式简化了命令的调用
但当目录中存在名为clean
的文件时,make
可能会发现clean
并不是过时的,于是不会执行 MakeFile 中的命令
为了解决这个问题,我们在.PHONY
中声明clean
是一个假目标:在.PHONY
中声明的目标文件,即使其并没有过时,也将会被 regenerate
Module 5
介绍了函数和递归的概念,很简单
Function
Pass by value / Pass by reference
Global / Local variable
Variable Scope (还记得 Lexical Scope)
Recursive
Recursive Definition
Stack Overflow
Recursion V.S. Iteration
ENGG1340 Computer Programming II的更多相关文章
- The Art of Computer Programming
<计算机程序设计艺术>即<The Art of Computer Programming>是计算机领域里颠峰级的里程碑,加上国外人士对它的推崇,所以提起它的大名简直就象法律书籍 ...
- K老在拿图灵奖时的发言:Computer Programming as an Art
很多话说得很透彻,把一些觉比较精彩的摘抄一下. ... It seems to me that if the authors I studied were writing today, they wo ...
- The Art Of Computer Programming: 1.1
The Art Of Computer Programming: 1.1 */--> div.org-src-container { font-size: 85%; font-family: m ...
- 类型检查和鸭子类型 Duck typing in computer programming is an application of the duck test 鸭子测试 鸭子类型 指示编译器将类的类型检查安排在运行时而不是编译时 type checking can be specified to occur at run time rather than compile time.
Go所提供的面向对象功能十分简洁,但却兼具了类型检查和鸭子类型两者的有点,这是何等优秀的设计啊! Duck typing in computer programming is an applicati ...
- Reflection (computer programming) -反射-自身结构信息
n computer science, reflection is the ability of a computer program to examine, introspect, and modi ...
- leetcode Ch2-Dynamic Programming II
一. Longest Valid Parentheses 方法一.一维DP class Solution { public: int longestValidParentheses(string s) ...
- python advanced programming ( II )
面向对象编程 简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数.数据封装.继承和多态是面向对象的三大特点. 在Python中,所有数据类型都可以视为对 ...
- [MIT6.006] 20. Daynamic Programming II: Text Justification, Blackjack 动态规划II:文本对齐,黑杰克
这节课通过讲解动态规划在文本对齐(Text Justification)和黑杰克(Blackjack)上的求解过程,来帮助我们理解动态规划的通用求解的五个步骤: 动态规划求解的五个"简单&q ...
- Important Programming Concepts (Even on Embedded Systems) Part V: State Machines
Earlier articles in this series: Part I: Idempotence Part II: Immutability Part III: Volatility Part ...
- How to using Piwis Tester II code Porsche rear end electronics
V18.100 Piwis Tester II Diagnostic Tool For Porsche With CF30 Laptop High Quality Top 7 Reasons to G ...
随机推荐
- 字符输入流读取字符数据-writer类
字符输入流读取字符数据 读取字符:read方法,每次可以读取一个字符的数据,提升为int类型,读取到文件末尾,返回-1,循环读取,代码使用演示∶ writer类 java.io.Filelwriter ...
- C#实现聊天消息渲染、图文混排(支持Windows、Linux)
在实现聊天软件时,渲染文字表情图文混排是一项非常繁琐的工作,再加上还要支持GIF动图.引用消息.撤回消息.名片等不同样式的消息渲染时,就更加麻烦了. 好在我们可以使用 ESFramework 提供的 ...
- C#,Winform软件防破译-源代码加密简单方法之.NET REACTOR(一)
一..NET Reactor介绍 .NET Reactor是一个功能强大的代码保护和软件许可系统,适用于为.NET Framework编写的软件,并支持生成.NET程序集的所有语言. 支持Blazor ...
- C#获取html标签内容的方法
C# 获取html标签内容的方法: /// <summary> /// 获取html网页标签内容 /// 例如:<span class="index_infoItem__E ...
- 解决Linux上tomcat解析war包中文文件乱码
解决Linux上tomcat解析war包中文文件乱码 第一步 编辑tomcat/conf server.xml vim /usr/local/src/tomcat/conf/server.xml us ...
- Java基础语法:运算符、包机制、JavaDoc
Java基础语法:运算符.包机制.JavaDoc 自增.自减.一元运算符:++.-- 例子:b = a++; -->先给b赋值,a再自增:b=a; a=a+1; b = ++a; -->a ...
- 使用IDM从Google 云端硬盘链接上下载超大文件
1.将原始文件以快捷方式存放到自己的网盘中. 2.进入自己的网盘,找到存放好的目标文件快捷方式,点击右键,选择下载. 3.如果电脑上IDM且浏览器装有IDM插件,会弹出下载框,点击下载即可. 4.然后 ...
- linux备份系统
转载csdn: Linux 中我该如何备份系统 - 京山游侠 - 博客园 (cnblogs.com)
- python 操作 WhiteSpace 语言
python 操作 WhiteSpace语言 目录 python 操作 WhiteSpace语言 1 WhiteSpace 简介 2 Python 操作栈流程 1 WhiteSpace 简介 Whit ...
- 跳板攻击之:lcx 端口转发
跳板攻击之:lcx 端口转发 郑重声明: 本笔记编写目的只用于安全知识提升,并与更多人共享安全知识,切勿使用笔记中的技术进行违法活动,利用笔记中的技术造成的后果与作者本人无关.倡导维护网络安全人人有责 ...