dream

一个菜鸟程序员的成长历程

0%

学堂在线C++程序设计第四章学习笔记

函数定义

函数:定义好的可重用功能模块

定义函数:将一个模块的算法用C++描述出来

函数的返回值:需要返回的计算结果

定义函数的语法:

1
2
3
4
类型标识符 函数名(形式参数表)
{
语句
}

形式参数表

  • <类型名> 参数名,…

返回值

  • return 一个计算结果
  • 返回的类型是类型标识符的类型
  • 没有返回值,类型标识符写void

函数调用

调用函数前需要先声明函数原型

函数原型

  • 类型标识符
  • 被调用函数名
  • (类型说明的形参表)

函数调用

  • 函数名(实参列表)

计算x的n次方

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
using namespace std;

double pow(double x, int n) {
double sum = 1.0;
for(int i = 1; i <= n; i++) {
sum = x * sum;
}
return sum;
}

int main() {
double sum = pow(2,4);
cout << sum;
return 0;
}

进制转换

输入一个8位二进制,输出十进制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
using namespace std;

double pow(double x, int n) {
double sum = 1;
for (int i = 1; i <= n; i++) {
sum *= x;
}
cout << "x:"<<x<<"n:"<<n<<endl;
return sum;
}

int main() {
int h = 0;
for (int i = 7; i >= 0; i--) {
char d;
cout << "输入:";
cin >> d;
if (d == '1') {
//转换进制
h += static_cast<int>(pow(2, i));
}
}
cout << h;
return 0;
}

计算圆周率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>

using namespace std;

double arctan(double x) {

double sqr = x * x;

double e = x;

double r = 0;

int i = 1;

while (e / i > 1e-15) {

double f = e / i;

r = (i % 4 == 1) ? r + f : r - f;

e = e * sqr;

i += 2;

}

return r;

}

int main() {

double a = 16.0 * arctan(1/5.0);

double b = 4.0 * arctan(1/239.0);

//注意:因为整数相除结果取整,如果参数写1/5,1/239,结果就都是0



cout << "PI = " << a - b << endl;

return 0;

}

求回文

寻找并输出11~999之间的数M,它满足M、M2和M3均为回文数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
using namespace std;

/**
* 判断是否是回文
*/
bool symm(unsigned int n) {
unsigned int i = n;
unsigned int m = 0;
while (i > 0)
{
/* code */
m = m * 10 + i % 10;
i /= 10;
}
return m == n;
}

int main () {
for (int i = 11; i <= 999; i++) {
if (symm(i) && symm(i * i) && symm(i * i *i)) {
cout << "m = " << i << endl;
cout << "m * m =" << i * i << endl;
cout << "m * m * m = " << i * i*i <<endl;
}
}
return 0;
}

计算分段函数,并输出结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <cmath>
using namespace std;

const double IINY_VALUE = 1e-10;

double tsin(double x) {
double g = 0;
double t = x;
int n = 1;
do {
g += t;
n++;
t = -t * x * x/(2*n-1)/(2 * n -2);
} while (fabs(t) >= IINY_VALUE);
return g;
}

int main() {
double k,r,s;
cout << "r =";
cin >> r;
cout << "s=";
cin >> s;
if (r * r <= s * s) {
k = sqrt(tsin(r) * tsin(r) + tsin(s) * tsin(s));
} else {
k = tsin(r * s) /2;
}
cout << k <<endl;
return 0;
}

摇筛子游戏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <cstdlib>
using namespace std;

enum gameStatus {WIN,LOSE,PLAYING};

int rollDice() {
unsigned int rand1 = rand() % 6 + 1;
unsigned int rand2 = rand() % 6 + 1;
cout << "rand1 + rand2 = " << rand1 + rand2 << endl;
return rand1 + rand2;
}


int main() {
unsigned int seed, sum, myPoint;
gameStatus status;
cout << "enter is seed:";
cin >> seed;
srand(seed);
sum = rollDice();
switch (sum)
{
case 7:
case 11:
status = WIN;
break;
case 2:
case 3:
case 12:
status = LOSE;
break;
default:
status = PLAYING;
myPoint = sum;
break;
}

while (status == PLAYING)
{
/* code */
sum = rollDice();
if (sum == 7) {
status = LOSE;
} else if (sum == myPoint) {
status = WIN;
}
}

if (status == WIN) {
cout << "WIN";
} else if (status == LOSE) {
cout << "LOSE";
}
return 0;

}

C++程序设计第三章

数据的输入输出

输入输出看成是数据的流动

IO流

  • 将数据从一个对象到另一个对象的流动抽象为
  • 流在使用前要建立,使用后要删除
  • 数据的输入输出是通过IO流来实现的,cin和cout是预定义的流类对象。cin用来处理标准输入,即键盘输入。cout用来处理标准输出,即屏幕输出
  • 从流中获取数据的操作称为

预定义的插入符和提取符

  • << 是预定义的插入符,作用在流对象cout上就可以向标准输出设备输出
  • >> 是预定义的提取符,作用在流对象cin上
  • 可以写多个

常用的IO流类库操纵符

操纵符名 含义
dec 数值数据采用十进制表示
hex 数值数据采用十六进制表示
oct 数值数据采用八进制表示
ws 提取空白符
endl 插入换行符并刷新流
ends 插入空字符
setprecision(int) 设置浮点数的小数位数(包括小数点)
setw(int) 设置域宽

选择结构

if语句

if语句的语法形式

  • if (表达式)语句
    if (x > y) cout << x;
  • if (表达式) 语句1 else 语句2
    if (x < y) cout << x;
    else cout <<y;
  • if (表达式1) 语句1 else if (表达式2) 语句2 else 语句n
1
2
3
4
5
6
if (表达式1) 
语句1
else if (表达式2)
语句2
else
语句n

上面的表达式等同于下面的表达式

1
2
3
4
5
6
7
if (表达式1) 
语句1
else
if (表达式2)
语句2
else
语句n

switch语句

1
2
3
4
5
6
7
8
9
10
switch (表达式1) {
case 常量值1
语句1
break;
case 常量值2
语句2
break;
default:
默认语句
}

表达式和常量值都是int或char型

循环结构

while语句

计算0到10之和

1
2
3
4
5
int sum = 0;
whileint i <= 10) {
sum += i;
i++;
}

执行顺序

  • 先判断while表达式的值,若为true,执行语句
  • 执行完语句在判断while表达式的值,直到为false,不再执行

while里面可以是复合语句,其中必须含有改变条件表达式值得语句

do-while语句

计算0到10之和

1
2
3
4
5
6
int sum = 0;
int i = 0;
do {
sum += i;
i++;
} while ( i <= 10

执行顺序

  • 先执行语句
  • 执行完语句判断while表达式的值,如果为true,那么接着执行语句
  • 执行完语句后再次判断while表达式的值,直到为false
  • 语句至少会执行一次

for语句

输入一个整数,求出他的所有因子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
using namespace std;

int main() {
int n;
cin >> n;
cout << "Number:" << n << "Factors\n";
for (int k = 1;k <= n;k++) {
if (n % k == 0) {
cout << k << endl;
}
}
cout << "end" << endl;
return 0;
}

嵌套的控制结构

输入一系列整数,统计出正整数个数i和负整数个数j,读入0则结束

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
using namespace std;

int main() {
int n;int z = 0;int f = 0;
cin >> n;
while (n != 0)
{
/* code */
if (n > 0) {
z++;
} else if (n < 0) {
f++;
}
cin >> n;
}
cout << "n:" << n << endl;
cout << "正数数量:" << z << endl;
cout << "负数数量:" << f << endl;

return 0;
}

自定义类型

类型别名:为已有类型另外命名

  • typedef 已有类型名 新类型名表
  • 例子:typedef double area
  • using 新类型名 = 已有类型名
  • 例子:using area = double

枚举类型:

  • 定义方式:
    将全部可取值列出来
  • 语法形式:
    enum 枚举类型名 {变量值列表}
  • 例子
    enum week {1,2,3,4,5,6,7}

C++包含两种枚举类型:

  • 不限定作用域
  • 限定作用域

不限定作用域枚举类型

  • 枚举元素是常量,不能赋值
  • 枚举元素具有默认值,依次为0,1,2,3
  • 也可以在声明时另行指定枚举元素的值
  • 枚举值可以进行关系运算
  • 整数值不能赋值为枚举变量,如需要,应该进行强制转换
  • 枚举可以给整形赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
using namespace std;

enum GameResult {WIN,LOSE,TIE,CANCEL};

int main() {
GameResult Result;
enum GameResult omit = CANCEL;
for (int count = WIN; count <= CANCEL; count++) {
Result = GameResult(count);
if (Result == omit) {
cout << "The game was canceld" << endl;
} else {
cout << "The game was played" << endl;
if (Result == WIN) cout << "and we Win" << endl;
if (Result == LOSE) cout << "and we lose" << endl;
}

}

return 0;
}

auto 类型 与 decltype类型

  • auto :编译器通过初始值自动推断变量的类型
    例如:auto val = val1 + val2
    如果val1 val2是int,那么val是int
    如果val1 val2是double,那么val是double
  • decltype:定义一个变量与某一表达式的类型相同,单并不用该表达式初始化变量
    例如:decltype(i)j = 2;
    表示j 用 2 作为初始值,但是类型和i一致

C++程序设计第二章

C++简单程序设计

C++的基本数据类型

  • 整数类型
  • 实数类型
  • 字符类型
  • 布尔类型

C++的基本运算

  • 算术运算
  • 逻辑运算

程序要能输入数据,输出数据

C++的输入输出可以调用预定义的功能模块实现

程序的执行流程不总是顺序的因此程序要能够

  • 对执行流程进行选择(选择/开关语句)
  • 反复用同一算法依次处理大批量数据(循环语句)

基本数据类型能表示的有限

程序员要能够自定义类型

枚举类型

  • 通过列出所有可取值来定义一种新类型

C++特点和程序实例

  • 从C语言发展而来,最初称为带类的C
  • 1983年正式取名为C++;
  • 1998年11月被国际标准化组织(ISO)批准为国际标准;
  • 2003年10月15日发布第2版C++标准ISO/IEC 14882:2003;
  • 2011年8月12日ISO公布了第三版C++标准C++11,包含核心语言的新机能、扩展C++标准程序库。
  • 2014年8月18日ISO公布了C++14,其正式名称为”International Standard ISO/IEC 14882:2014(E) Programming Language C++”。
  • C++14作为C++11的一个小扩展,主要提供漏洞修复和小的改进。

C++的特点

  • 兼容C,支持面向过程的程序设计
  • 支持面向对象的方法
  • 支持泛型程序设计方法

命名空间

  • 避免命名冲突
  • std是C++标准库的命名空间名
  • using namespace std 表示打开std命名空间

输出Hello

1
2
3
4
5
6
7
8
#include <iostream>
using namespace std;

int main() {
cout << "Hello!" << endl;
cout << "Welcome to C++!" << endl;
return 0;
}

C++字符集和词法记号

词法记号

  • 关键字
    C++预定义的单词
  • 标志符
    程序员声明的单词,它命名程序正文中的一些实体
  • 文字
    在程序中直接使用符号表示的数据
  • 分隔符
    (){};:,用于分隔各个词法记号或程序正文
  • 运算符(操作符)
    用于实现各种运算的符号
  • 空白符
    空格, 制表符,垂直制表符,换行符,回车符和注释的总称

标识符的构成规则

  • 以大写字母,小写字母或下划线开始
  • 可以由大写字母,小写字母,下划线或数字组成
  • 大写字母和小写字母代表不同的标识符
  • 不能是C++关键字或操作符

基本数据类型,常量,变量

程序中的数据

  • 常量
    在源程序中直接写明的数据
    其值在整个程序运行期间不可改变
  • 变量
    在程序运行过程中可以改变

整数类型

  • 基本的INT型
  • 按照符号分
    • 有符号
    • 无符号
  • 按照数据范围分
    • 短整数 short
    • 长整数 long
    • 长长整数 longlong

字符类型

  • 字符容纳单个字符的编码
  • 实质上存储的也是整数

浮点数类型

  • 单精度 float
  • 双精度 double
  • 扩展精度 long double

字符串类型

  • 有字符串常量
  • 基本类型中没有字符串变量
  • 采用字符数组存储字符串
  • 标准C++库中的String类

布尔类型

  • 只有两个值,真 true 假 false

常量

  • 在程序运行中不可改变的量
  • 直接使用符号(文字)表示的值
  • 例如:12,3.5,’A’都是常量

整数常量

  • 十进制
  • 八进制
  • 十六进制

后缀

  • L = long
  • LL = longlong
  • U = 无符号

浮点数常量

  • 以文字形式出现的实数
  • 默认double ,如果后缀F可以指定成float

C风格字符串

  • 一对双引号的字符
  • 在内存中按串中字符的排列次序顺序存放,每个字符占一个字节
  • 在末尾添加’\0’作为结尾标记

变量

在程序运行过程中可改变的量

变量定义

  • 类型 变量名

在定义变量的同时可以初始化

C++多种初始化

  • int a = 0;
  • int a(0)
  • int a = {0}
  • int a{0}

列表初始化

  • 使用大括号的初始化方式
  • 不允许信息的丢失

符号常量

常量定义语句的形式:

  • const 数据类型说明符 常量名 = 值
  • 数据类型说明符 const 常量名 = 值

符号常量定义一定需要初始化,在程序中不能改变值

程序举例

读入并显示整数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;

int main() {
int radius;
cout << "Please enter the radius\n";
cin >> radius;
cout << "The radius is:" << radius << "\n";
cout << "PI is:" << 3.14 << "\n";
cout << "Please enter a different radius\n";
cin >> radius;
cout << "Now the radius is changed to:" << radius <<"\n";
return 0;
}

运算与表达式

算术运算与赋值运算

基本算术运算

  • +-*/(整数相除,结果为整数)
  • %取余运算(结果为整数)

优先级与结合性

  • 先乘除,后加减,同级自左至右

自增自减操作

赋值操作
通过赋值运算符=赋值给变量

复合赋值运算符有10种

  • +=, -=, *=, /=, <<=, >>=, &=, ^=, |=

符号运算,关系运算,逻辑运算和条件运算

逗号运算和逗号表达式

  • 格式
    表达式1,表达式2
  • 求解顺序及结果
    先求解表达式1,在求解表达式2
    用表达式2的结果作为结果
  • 例子
    a = 3 * 5, a * 4 最终结果为60

赋值运算符优先级比逗号低

关系运算

  • 优先级
    高的:< <= >= >
    低的:== !=
  • 关系表达式是一种最简单的逻辑表达式
  • 结果是布尔类型,true or false

逻辑运算符

  • 优先级从高到低:! && ||
  • 结果是布尔类型
  • && 的运算规则
    • 两侧表达式都为真,结果为真
    • 有一侧表达式为假,结果为假
  • || 的运算规则
    • 两侧表达式都为假,结果为假
    • 有一侧表达式为真,结果为真

&& 的短路特性

  • 先求解表达式1,
  • 若表达式1的值为false,则最终结果为false,不再求解表达式2
  • 若表达式1的值为true,则求解表达式2,以表达式2的结果作为最终结果

|| 的短路特性

  • 先求解表达式1
  • 若表达式1的值为true,则最终结果为true,不在求解表达式2
  • 若表达式1的值为false,则求解表达式2,以表达式2的结果作为最终结果

条件运算符

  • 一般形式
    • 表达式1 ? 表达式2 : 表达式3
    • 表达式1必须是bool类型
  • 执行顺序
    • 先求解表达式1
    • 若表达式1的值为true,则求解表达式2,表达式2的结果作为最终结果
    • 若表达式1的值为false,则求解表达式3,表达式3的结果作为最终结果
  • 条件运算符优先级高于赋值运算符,低于逻辑运算符

sizeof运算,位运算

sizeof运算符

  • 语法形式
    sizeof(类型名) 或 sizeof 表达式
  • 结果值
    类型名 所指定的类型,或 表达式 的结果类型所占的字节数

按位与

  • 运算规则
    将两个运算量的每一个位进行逻辑与操作
  • 例子
    计算 3 & 5
    0000 0011
    0000 0101
    结果0000 0001
  • 用途,将某一位置0,取出某一位

按位或

  • 运算规则
    将两个运算量的每一个位进行逻辑或操作
  • 用途,将某一位置1

按位异或

  • 运算规则
    两个操作数进行异或
    若对应位相同,结果为0
    若对应位不同,结果为1
  • 计算 071 ^ 052
    0011 1001
    0010 1010
    结果 0001 0011
  • 用途,特定位翻转

按位取反

  • 运算规则
    0 变 1, 1 变 0

移位操作

  • 左移后,低位补0,高位舍弃
  • 右移后,低位舍弃,高位无符号数补0,有符号为补符号位

运算优先级,类型转换

一些运算符要求数据类型一致
隐含转换的基本原则是低类型转换到高类型

浮点数换成整数,小数部分直接丢弃
整数换成浮点数,小数为0,可能丢失精度

显示转换

  • 类型说明符(表达式)
  • (类型说明符)表达式
  • 类型转换操作符 <类型说明符> (表达式) C++的转换方式
    • 类型转换操作符:const_cast,dynamic_cast ,reinterpret_cast,static_cast

软件工程

软件无处不在

软件是软件工程的研究对象,也是软件工程的产品形态与客观存在

工程是将理论和知识应用于实践的科学,其目的是经济有效的解决实际问题

软件的本质特性

软件 = 程序 + 数据 + 文档

  • 程序:计算机可以接受的一系列指令,运行时可以提供所要求的的功能和性能
  • 数据:使得程序能够适当地操作信息的数据结构
  • 文档:描述程序的研制过程,方法和使用的图文资料

软件具有

  • 复杂性
  • 一致性
  • 可变性
  • 不可见性

上面是软件开发困难的根本原因

一致性

  • 软件不能独立存在,需要依附于一定的环境(如硬件,网络以及其他软件)
  • 软件必须遵从人为的惯例并适应已有的技术和系统
  • 软件需要随接口不同而改变,随时间推移而变化,而这些变化是不同人设计的结果

可变性

  • 软件一直在变化更新
  • 人们总认为软件是容易修改的,但忽视了修改的副作用
  • 不断的修改最终导致软件的退化,从而结束其生命周期

不可见性

  • 软件是一种看不见摸不着的逻辑实体,不具有空间的形体特征
  • 开发人员可以直接看到程序代码,但是源代码并不是软件本身
  • 软件是以机器代码得形式运行,但是开发人员无法看到源代码是如何执行的

软件所具有的复杂性,一致性,可变性,不可见性等特性,使得软件开发过程变得难以控制,开发团队如同在焦油坑中挣扎的巨兽

软件工程的产生与发展

软件开发面临的挑战

  • 客户不满意
    • 交付的许多功能不是客户需要的
    • 交付的日期没有保障
    • 客户使用时发现许多bug
  • 项目过程失控
    • 客户需求变化频繁,无力应对
    • 无法预见软件的交付质量
    • 对流程盲目遵从,忽视客户业务价值
  • 风险与成本问题
    • 开发团队专注技术,忽视风险
    • 无能力预测成本,导致预算超支
  • 无力管理团队
    • 无法评估开发人员能力及工作进度
    • 困扰于如何提升团队的能力与效率

软件工程一直致力于探索软件开发问题的解决之道

1968年,北大西洋公约组织提出软件工程概念和术语

软件工程的基本概念

软件工程

  • 将系统的,规范的,可定量的方法应用与软件的开发,运行和维护,即工程化应用到软件上
  • 对1中所述方法的研究

好的软件

  • 较低的开发成本
  • 按时完成开发任务并及时交付
  • 实现客户要求的功能
  • 具有良好性能,可靠性,可扩展性,可移植性等
  • 软件维护费用低

软件工程的基本要素

  • 过程
    支持软件开发各个环节的控制和管理
  • 方法
    完成软件开发任务的技术手段
  • 工具
    为软件开发方法提供自动或半自动的软件支撑环境

软件开发的基本策略

  • 软件复用
  • 分而治之
  • 逐步演进
  • 优化折中

软件工程的wasserman规范

  • 抽象
  • 软件建模方法
  • 用户界面原型化
  • 软件体系结构
  • 软件过程
  • 软件复用
  • 度量
  • 工具与集成环境

软件质量实现

什么是好的软件

  • 功能质量
    • 软件符合指定需求
    • 软件几乎没有缺陷
    • 软件性能正常
    • 软件容易上手,操作方便
  • 结构质量
    • 代码可测试性
    • 可维护性
    • 可读性
    • 代码效率:高效管理资源
    • 代码安全:可预防常见威胁
  • 过程质量
    • 软件按时交付
    • 软件满足预算
    • 可复用的开发过程,确保交付质量

产品质量维度

  • 性能
  • 特色
  • 可靠性
  • 符合型
  • 耐久性
  • 可服务性
  • 审美
  • 感知

ISO9126质量模型

  • 功能性
    • 适合性:当软件在指定条件下使用,其满足明确和隐含要求功能的能力
    • 准确性:软件提供给用户功能的精确度是否符合目标
    • 互操作性:软件与其他系统进行交互的能力
    • 安全性:软件保护信息和数据的安全能力
  • 可靠性
    • 成熟性:软件产品避免因软件错误发生而导致失效的能力
    • 容错性:防止外部接口错误扩散而导致系统失效的能力
    • 可恢复性:系统失效后,重新恢复原有的功能和性能的能力
  • 易用性
    • 易理解性
    • 易学习性
    • 易操作性
    • 吸引性
  • 效率
    • 时间特性
    • 资源利用
  • 可维护性
    • 易分析性
    • 易改变性
    • 稳定性
    • 易测试性
  • 可移植性
    • 适应性
    • 易安装性
    • 共存性
    • 替换性

数据库系统原理第二节

关系数据库

客户服务器结构

客户端,前台或表示层主要完成与数据库使用者的交互任务

服务器,后台或数据层主要负责数据管理

单机方式
网络方式

浏览器服务器结构

一种基于Web应用的客户/服务器结构,也称为三层客户/服务器结构

三层

  • 表示层
  • 处理层(中间层)
  • 数据层

数据模型

模型是现实世界特征的模拟和抽象表达

数据模型是对现实世界数据特征的抽象,描述的是数据的共性内容

数据的特征

静态特征

  • 数据的基本结构
  • 数据间的联系
  • 数据取值范围的约束

动态特征

  • 指对数据可以进行符合一定规则的操作

数据模型组成要素

数据结构描述的是系统的静态特征,即数据对象的数据类型内容,属性以及数据对象之间的联系

数据操作描述的是系统的动态特征

数据约束描述数据结构中数据间的语法和语义关联

数据模型的分类

数据模型是模型化数据和信息的工具,也是数据库系统的核心和基础

满足三点:

  • 比较真实地模拟现实世界
  • 容易为人们理解
  • 便于在计算机上实现

概念层数据模型

概念层是数据抽象级别的最高层。概念层数据模型,也称为数据的概念模型信息模型,这类模型主要用于数据库的设计阶段

信息世界涉及的基本概念

实体
属性
码或键

实体型
实体集
联系

数据模型中有两个概念

型 是表头,字段名称
值 是内容,字段值

逻辑层数据模型

逻辑层是数据抽象级别的中间层,逻辑层数据模型,也称为数据的逻辑模型。任何DBMS都是基于某种逻辑数据模型。

逻辑模型的类型

层次模型

  • 最早使用的一种数据模型
  • 有且仅有一个结点没有父结点,称作根结点
  • 其他结点有且仅有一个父结点

网状模型

  • 以网状结构表示实体与实体间的联系
  • 允许结点有多与一个父结点
  • 可以有一个以上的结点没有父结点

关系模型

  • 二维表结构来表示实体间的联系
  • 建立在严格的数学概念的基础上,概念单一
  • 存取路径对用户透明,有更高的数据独立性,更好的安全保密性

面向对象模型 = 面向对象方法 & 数据库

  • 既是概念模型又是逻辑模型
  • 表达能力丰富,对象可复用,维护方便

物理层数据模型

物理模型

最底层的抽象

设计目标是提高数据库性能有效利用存储空间

简述概念模型,逻辑模型,物理模型之间的关系

这三个不同的数据模型之间既相互独立,又存在着关联。从现实世界到概念模型的转换是由数据库设计人员完成的。
从概念模型到逻辑模型的转换可以由数据库设计人员完成,也可以用数据库设计工具协助设计人员完成;
从逻辑模型到物理模型的转换主要用数据库管理系统完成。

关系数据库

关系数据库概述

关系数据库的历史

1970 提出了关系模型
20世纪70年代末 重大突破
1981年 证实了关系数据库的优点:高级的非过程语言接口,较好的数据独立性
20世纪80年代后 网状模型和层次模型与底层实现的紧密结合,关系模型具有坚实理论基础,成为主流数据模型

关系数据模型的组成要素

关系数据结构
关系操作集合
关系完整性约束

关系数据结构

关系的三种类型

实际存在的表

基本关系(基本表,基表)
查询表
视图表 导出的虚表

关系数据模型

列 也称为 字段 或 属性

属性 = 列

8元 = 8度 = 8列

分量 = 具体的数据项
元组(行)中的一个属性值,称为分量

C++程序设计第一章

计算机语言

程序员与计算机沟通的语言
描述解决问题的方法和相关数据

计算机语言的级别

  • 二进制代码得机器语言
  • 使用助记符的汇编语言
  • 使用类似英语单词和语句的高级语言

C++是面向对象的高级语言

  • 封装
  • 消息通信

C++支持的程序设计方法

  • 面向过程的程序设计方法
  • 面向对象的程序设计方法
  • 泛型程序设计方法

C++程序的开发过程

  • 算法设计
  • 源程序编辑
  • 编译
  • 连接

信息在计算机中的表示存储

  • 计算机中的数据都是二进制的
  • 逻辑数据,字符数据也用二进制码表示

计算机系统简介

  • 输入设备
  • 内存储器
  • 外存储器
  • CPU
  • 输出设备

计算机的工作需要人来指挥

  • 计算机解决问题是软件控制的
  • 软件的程序就是操作步骤
  • 程序要使用语言来表达

计算机能识别的是机器语言
机器语言指令是由0和1编码的
例如:
加法指令可能是 0001

计算机指令系统

  • 机器硬件能够识别的语言(机器语言)的集合
  • 它是软件和硬件的主要界面

计算机软件:

  • 应用软件
  • 系统软件 操作系统
  • 中间件 提供系统软件和应用软件之间链接的软件

软件 = 程序 + 文档

计算机程序

  • 指令的序列
  • 描述解决问题的方法和数据

计算机语言和程序设计方法的发展

机器语言

  • 由二进制代码构成
  • 计算机硬件可以识别
  • 可以表示简单的操作
  • 例如:
    加法,减法,数据移动等等

最初的计算机语言–机器语言和人类的自然语言之间存在巨大鸿沟

汇编语言

  • 将机器指令映射为一些助记符。如ADD,SUB,MOV等
  • 抽象层次低,需要考虑机器细节

高级语言

  • 关键字,语句容易理解
  • 有含义的数据命名和算式
  • 抽象层次高,例如 A + B
  • 屏蔽了机器的细节,例如 count << a + b + c

C++语言

  • 是高级语言
  • 支持面向对象的观点和方法
  • 将客观事物看做对象
  • 对象间通过消息传送进行沟通
  • 支持分类和抽象

程序设计方法和发展历程

面向过程的程序设计方法

  • 机器语言,汇编语言,高级语言都支持
  • 最初的目的,用于数学计算
  • 主要工作,设计求解问题的过程

大型复杂的软件,难以用面向过程的方式编写

面向对象的程序设计方法

  • 面向对象的高级语言支持
  • 一个系统有对象构成
  • 对象与对象之间通过消息通信

面向对象的基本概念

对象(Object)

  • 一般意义上的对象:
    是现实世界中一个实际存在的事物
  • 面向对象方法中的对象:
    是系统中用来描述客观事物的一个实体

抽象与分类

  • 分类所依据的原则–抽象
  • 抽象出同一类对象的共同属性和行为,形成类

类与对象的关系

  • 类型与实例的关系

封装

  • 隐蔽对象的内部细节
  • 对外形成一个边界
  • 只保留有限的对外接口
  • 使用方便,安全性好

继承

  • 软件复用
  • 改造,扩展已有类行成新的类

多态

  • 同样的消息作用在不同对象上有可能引起不同的行为

程序的开发过程

高级语言 要翻译成 机器语言

源程序

  • 用源语言写的,有待翻译的程序

目标程序

  • 源程序通过翻译加工以后生成的机器语言程序

可执行程序

  • 连接目标程序以及库中的某些文件,生成的可执行程序

三种不同类型的翻译程序

  • 汇编程序
    将汇编语言源程序翻译成目标程序
  • 编译程序
    将高级语言源程序翻译成目标程序
  • 解释程序
    将高级语言源程序翻译成机器指令,是边翻译边执行

JAVA语言是半编译半解释的,目的是为了跨平台

C++程序是直接编译成本地机器语言代码

C++程序开发过程

  • 算法与数据结构设计
  • 源程序编辑
  • 编译
    先做语法检查
    编译
  • 连接
  • 测试
  • 调试

信息的表示和存储

计算机中的信息与存储单位

计算机中的基本功能

  • 算术运算
  • 逻辑运算

计算机中的信息

  • 控制信息
    指挥计算机操作
  • 数据信息

信息的存储单位

  • 位 bit
    数据的最小单位
  • 字节 Byte
    8位二进制 1Byte = 8bit
  • 千字节
    1KB = 1024B
  • 兆字节
    1MB = 1024KB
  • 吉字节
    1GB = 1024MB

计算机的数字系统

数字系统是二进制系统,基本符合0,1

三个二进制 = 一个八进制 四个二进制 = 一个十六进制

R进制 转 十进制:

  • 各位数字与他的权相乘,其积想加

例如:
11111111.11 = 1 * 27 + 1 * 26 + 1 * 25 + 1 * 24 + 1 * 23 + 1 * 22 + 1 * 21 + 1 * 20 + 1 * 2-1 + 1 * 2-2
= 255.75

十进制 转 R进制:

  • 除以R 取余

十进制小数 转 R进制小数:

  • 乘以R 取整

数据的编码表示

0 表示正数
1 表示负数

原码:

  • 符号 – 绝对值 表示的编码
  • 缺点
    • 0的表示不唯一
    • 进行四则运算时,符号位需单独处理且运算规则复杂

补码:

  • 0的表示唯一
  • 符号位可作为数值参加运算
  • 补码运算结果还是补码

模数:
n位二进制整数的模数为2的n次方
n位小数的模数是2

补数:
一个数减去另一个数(加上一个负数)
等于第一个数加第二个数的补数

例如:
8 + (-2) = 8 + 10 (mod 12) = 6

补码的计算规则

反码:作为中间码

反码的计算规则:
负整数

  • 原码符号位不变(仍是1)
  • 其余各位取反(0 变 1 , 1 变 0)

例如:
X = -1100110
原码 = 11100110
反码 = 10011001

正整数
原码就是反码就是补码

补码的计算规则

  • 反码作为中间码
  • 负数补码 = 反码 + 1
  • 正数补码 = 原码 = 反码

如果负数之和得正数或正数之和为负数说明运算结果溢出

小数的表示

浮点方案

N = M * 2E

E:2的幂次,称数N的阶码,反映了该浮点数所表示的数据范围
M:N的尾数 位数反映了数据的精度

字符的表示

字符在计算机中通过编码表示

  • ASCII码:
    常用的西文字符编码,7位二进制表示一个字符,最多可表示 2的7次方 = 128个字符
  • 汉字编码
    中国国家标准

数据库系统原理第一节

数据

什么是数据?

数据是描述事物的符号记录,是指利用物理符号记录下来的,可以鉴别的信息

数据是信息存在的一种形式,只有通过解释或处理的数据才能成为有用的信息。

什么是数据库?

数据库是指长期储存在计算机中的有组织的,可共享的数据集合。

数据要按照一定的数据模型组织描述和存储,具有较小的冗余度,较高的数据独立性,系统易于扩展,并可以被多个用户分享.

数据库的三个特点:

  • 永久存储
  • 有组织
  • 可共享

数据库管理系统(DBMS)

数据库管理系统 是专门用于建立管理数据库的一套软件,介于应用程序操作系统之间

1.数据定义功能
2.数据操纵功能
3.数据库的运行管理功能
4.数据库的建立和维护功能
5.数据组织,存储和管理功能
6.其他功能

数据库系统

组成:

  • 用户
  • 数据库管理系统
  • 数据库
  • 数据库管理员
  • 应用程序

数据库管理技术的发展

  • 人工管理阶段
    1. 数据不保存
    2. 应用程序管理数据
    3. 数据面向应用程序
  • 文件系统阶段
    把数据变成文件存在磁盘
    优点:物理数据独立性
  • 数据库系统阶段
    1. 数据集成(主要目的)
    2. 数据共享性(高)
    3. 数据冗余(小)
    4. 数据一致性
    5. 数据独立性高
    6. 实施统一管理与控制

数据库系统的结构

数据库系统结构的分类

用户视角

  • CS结构
  • BS结构

DBA视角

内部系统结构

采用三级模式

  • 模式 也称为概念模式逻辑模式 概念视图,数据库的核心,数据库设计的关键
  • 内模式 存储模式物理模式 内部视图或存储视图
  • 外模式 给应用使用,不是唯一的,也称为子模式用户模式数据视图即用户视图
外部系统结构
  • 集中式结构
  • 分布式结构
  • 并行结构

三级模式结构的两层映像与数据独立性

所谓映像,就是一种对应规则,它指出映像双方是如何进行转换的。

模式 - 内模式映像:保证了数据与程序的物理独立性

外模式 - 模式映像:保证了数据与程序的逻辑独立性

OpenResty的安装

wsl 使用的是ubuntu 20的版本,所以可以直接使用apt进行安装,OpenResty官网的安装也是推荐使用的apt进行安装。

添加openresty的公钥

1
sudo apt-get -y install --no-install-recommends wget gnupg ca-certificates

导入 GPG 秘钥

1
wget -O - https://openresty.org/package/pubkey.gpg | sudo apt-key add -

添加 Openresty 的源

1
2
echo "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main" > openresty.list
sudo cp openresty.list /etc/apt/sources.list.d/

更新apt

1
sudo apt-get update

安装openresty

1
sudo apt-get -y install --no-install-recommends openresty

检查版本确认是否安装成功

1
openresty -V

启动 openresty

1
sudo service openresty start

访问 localhost 查看

1
curl localhost

安装 resty 命令

1
sudo apt-get -y install openresty-resty

执行 hello world看看是否安装成功

1
resty -e 'print("Hello Resty")'

安装 resty-doc

1
sudo apt-get -y install openresty-restydoc

OpenResty的目录介绍和helloworld

安装目录介绍

上文提到是 ubuntu apt 安装的 openresty

可以查看安装目录

1
openresty -V

安装目录是/usr/local/openresty

目录:

  • bin 这个目录里面是可执行文件,比如openresty,resty,restydoc这些程序
  • pod 这个目录存放的是openresty的文档
  • nginx 存放的就是nginx得相关文件
  • luajit 存放的luajit的相关文件
  • lualib 这个目录放的是lua库,主要分为 ngx 和 resty 两个子目录
    • ngx 存放 lua-resty-core 这个官方项目中的lua代码,里面都是基于FFI重新实现的 openresty API
    • resty 存放各种 lua-resty-* 项目包含的lua代码

wsl安装docker

wsl 使用的是ubuntu 20的版本,所以可以直接使用apt进行安装,docker官网的安装也是推荐使用的apt进行安装。

需要先更新apt安装包

1
sudo apt-get update

安装一些依赖

1
2
3
4
5
6
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release

添加Docker官方的GPG密钥:

1
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

添加docker的源

1
2
3
echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

更新apt安装包

1
sudo apt-get update

安装docker

1
sudo apt-get install docker-ce docker-ce-cli containerd.io

安装完成后启动docker

1
sudo service docker start

测试,运行hello world

1
sudo docker run hello-world