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参数代表自定义生成程序的名称,而不是采取默认名称

makeworking 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 ...
随机推荐
- Git入门图文教程(1.5W字40图)🔥🔥--深入浅出、图文并茂
01.认识一下Git!-简介 Git是当前最先进.最主流的分布式版本控制系统,免费.开源!核心能力就是版本控制.再具体一点,就是面向代码文件的版本控制,代码的任何修改历史都会被记录管理起来,意味着可以 ...
- C#零基础小白快速入门
前言 本文写给想学C#的朋友,目的是以尽快的速度入门 C#好学吗? 对于这个问题,我以前的回答是:好学!但仔细想想,不是这么回事,对于新手来说,C#没有那么好学. 反而学Java还要容易一些,学Jav ...
- Performance API不完全使用指北
本教程解释了如何使用Performance API来记录真实用户访问你的应用程序的统计数据. 使用浏览器的DevTools来评估web应用性能是很有用的,但要复现现实世界的使用情况并不容易.因为人们在 ...
- 12月23日内容总结——csrf跨站请求伪造、校验策略、相关装饰器,auth认证模块及相关操作,拓展auth_user表
目录 一.csrf跨站请求伪造 概念引入 概念讲解 二.csrf校验策略 概念讲解 form表单操作csrf策略 ajax请求csrf策略 三.csrf相关装饰器 四.auth认证模块 五.auth认 ...
- 10月31日ATM编写逻辑描述
目录 ATM逻辑描述 三层框架简介 1.第一层(src.py) 2.第二层(interface文件夹下内容) 3.第三层(db_hanlder) 启动函数 用户注册功能 用户登录 common中的小功 ...
- 10月11日内容总结——global和nonlocal方法、函数名的多种用法、闭包函数和装饰器
目录 一.global和nonlocal方法 global方法 nonlocal方法 二.函数名的多种用法 1.函数名可以当作变量名赋值 2.函数名可以当作函数的参数 3.函数名可以当作函数的返回值 ...
- Idea未识别maven项目
https://blog.csdn.net/qq_41460654/article/details/120539509
- LG P4717 【模板】快速莫比乌斯/沃尔什变换 (FMT/FWT)
\[C_k = \sum_{i|j=k}A_i B_j \] 这样的或卷积可以做一次 \(\text{FWT}\),把数组变为 \(\widehat{A}_i = \sum_{j\subseteq i ...
- [专题总结]Gridea快速免费搭建个人博客
介绍 或许你很想把你所知道的问题写出来,或许你文思泉涌,想给大家分享.我相信,你一定能写好博客,只要坚持,就可以了. 或许大家会不理解,为什么不用大平台的博客呢?或许你稍微了解就会知道,现在的博客平台 ...
- Java/.Net双平台核心,Jvm和CLR运行异同点
前言: 本篇以.Net 7.0.2 CLR 和 OpenJDk19参照,解析下它们各自调用函数的异同. 以下为个人理解. 概述 JDK大约5.9G,CLR大约7.6G,两者相差1.7G左右. root ...