最后一节课!

今天下午在上一节课就放假lo!!

Advertisements

C++编程规范

C++编程规范

1.基本要求

1.1 程序结构清析,简单易懂,单个函数的程序行数不得超过100行。
1.2 打算干什么,要简单,直接了当,代码精简,避免垃圾程序。
1.3 尽量使用标准库函数和公共函数。
1.4 不要随意定义全局变量,尽量使用局部变量。
1.5 使用括号以避免二义性。

2.可读性要求
2.1 可读性第一,效率第二。
2.2 保持注释与代码完全一致。
2.3 每个源程序文件,都有文件头说明,说明规格见规范。
2.4 每个函数,都有函数头说明,说明规格见规范。
2.5 主要变量(结构、联合、类或对象)定义或引用时,注释能反映其含义。
2.7 常量定义(DEFINE)有相应说明。
2.8 处理过程的每个阶段都有相关注释说明。
2.9 在典型算法前都有注释。
2.10 利用缩进来显示程序的逻辑结构,缩进量一致并以Tab键为单位,定义Tab为 6个
字节。
2.11 循环、分支层次不要超过五层。
2.12 注释可以与语句在同一行,也可以在上行。
2.13 空行和空白字符也是一种特殊注释。
2.14 一目了然的语句不加注释。
2.15 注释的作用范围可以为:定义、引用、条件分支以及一段代码。
2.16 注释行数(不包括程序头和函数头说明部份)应占总行数的 1/5 到 1/3 。

3. 结构化要求

3.1 禁止出现两条等价的支路。
3.2 禁止GOTO语句。
3.3 用 IF 语句来强调只执行两组语句中的一组。禁止 ELSE GOTO 和 ELSE RETURN。
3.4 用 CASE 实现多路分支。
3.5 避免从循环引出多个出口。
3.6 函数只有一个出口。
3.7 不使用条件赋值语句。
3.8 避免不必要的分支。
3.9 不要轻易用条件分支去替换逻辑表达式。

4. 正确性与容错性要求

4.1 程序首先是正确,其次是优美
4.2 无法证明你的程序没有错误,因此在编写完一段程序后,应先回头检查。
4.3 改一个错误时可能产生新的错误,因此在修改前首先考虑对其它程序的影响。
4.4 所有变量在调用前必须被初始化。
4.5 对所有的用户输入,必须进行合法性检查。
4.6 不要比较浮点数的相等,
如: 10.0 * 0.1 == 1.0 , 不可靠
4.7 程序与环境或状态发生关系时,必须主动去处理发生的意外事件,如文件能否
逻辑锁定、打印机是否联机等。
4.8 单元测试也是编程的一部份,提交联调测试的程序必须通过单元测试。

5. 可重用性要求

5.1 重复使用的完成相对独立功能的算法或代码应抽象为公共控件或类。
5.2 公共控件或类应考虑OO思想,减少外界联系,考虑独立性或封装性。
5.3 公共控件或类应建立使用模板。

附:C++ 编程规范,delphi作相应的参考

.1适用范围

本标准适用于利用Visul C++ ,Borland C++进行软件程序开发的人员.。

.2变量命名

命名必须具有一定的实际意义,形式为xAbcFgh,x由变量类型确定,Abc、Fgh表示连续意
义字符串,如果连续意义字符串仅两个,可都大写.如OK.

具体例程:

BOOL类型 bEnable;

ch * char chText
c * 类对象 cMain(对象实例)
h * Handle(句柄) hWnd
i * int
n * 无符号整型
p * 指针
sz,str * 字符串
w WORD
x,y 坐标

Char或者TCHAR类型 与Windows API有直接联系的用szAppName[10]形式否则用
FileName[10]形式,单个字符也可用小写字母表示;

Int类型 nCmdShow;

LONG类型 lParam;

UINT类型 uNotify;

DWORD类型 dwStart;

PSTR类型 pszTip;

LPSTR类型 lpCmdLine

LPTSTR类型 lpszClassName;

LPVOID类型 lpReserved

WPARAM类型 wParam,

LPARAM类型 lParam

HWND类型 hDlg;

HDC类型 hDC;

HINSTANCE类型 hInstance

HANDLE类型 hInstance,

HICON类型 hIcon;

int iTmp

float fTmp

DWORD dw*

String , AnsiString str *

m_ 类成员变量 m_nVal, m_bFlag
g_ 全局变量 g_nMsg, g_bFlag

局部变量中可采用如下几个通用变量:nTemp,nResult,I,J(一般用于循环变量)。

其他资源句柄同上

.3常量命名和宏定义

常量和宏定义必须具有一定的实际意义;

常量和宏定义在#include和函数定义之间;

常量和宏定义必须全部以大写字母来撰写,中间可根据意义的连续性用下划线连接,每一
条定义的右侧必须有一简单的注释,说明其作用;

资源名字定义格式:

菜单:IDM_XX或者CM_XX

位图:IDB_XX

对话框:IDD_XX

字符串:IDS_XX

DLGINIT:DIALOG_XX

ICON:IDR_XX

.4函数命名

函数原型说明包括引用外来函数及内部函数,外部引用必须在右侧注明函数来源: 模
块名及文件名, 如是内部函数,只要注释其定义文件名;

第一个字母必须使用大写字母,要求用大小写字母组合规范函数命名,必要时可用下划线
间隔,示例如下:

void UpdateDB_Tfgd (TRACK_NAME); //Module Name :r01/sdw.c

void PrintTrackData (TRACK_NAME); //Module Name :r04/tern.c

void ImportantPoint (void); //Module Name :r01/sdw.c

void ShowChar (int , int , chtype); //Local Module

void ScrollUp_V (int , int); //Local Module

.5结构体命名

结构体类型命名必须全部用大写字母,原则上前面以下划线开始;结构体变量命名必须用
大小写字母组合,第一个字母必须使用大写字母,必要时可用下划线间隔。对于私有数
据区,必须注明其所属的进程。全局数据定义只需注意其用途。

示例如下:

typedef struct

{

char szProductName[20];

char szAuthor[20];

char szReleaseDate[16];

char szVersion[10];

unsigned long MaxTables;

unsigned long UsedTables;

}DBS_DATABASE;

DBS_DATABASE GdataBase;

6 控件的命名:
用小写前缀表示类别

用小写前缀表示类别:
fm 窗口
cmd 按钮
cob combo,下拉式列表框
txt 文本输入框
lab labal,标签
img image,图象
pic picture
grd Grid,网格
scr 滚动条
lst 列表框
frm fram

7注释

原则上注释要求使用中文;

文件开始注释内容包括:公司名称、版权、作者名称、时间、模块用途、背景介绍等,复
杂的算法需要加上流程说明;

函数注释包括:输入、输出、函数描述、流程处理、全局变量、调用样例等,复杂的函数
需要加上变量用途说明;

程序中注释包括:修改时间和作者、方便理解的注释等;

引用一: 文件开头的注释模板

/******************************************************************

** 文件名:

** Copyright (c) 1998-1999 *********公司技术开发部

** 创建人:

** 日 期:

** 修改人:

** 日 期:

** 描 述:

**

** 版 本:

**————————————————————————–

******************************************************************/

引用二: 函数开头的注释模板

/*****************************************************************

** 函数名:

** 输 入: a,b,c

** a—

** b—

** c—

** 输 出: x—

** x 为 1, 表示…

** x 为 0, 表示…

** 功能描述:

** 全局变量:

** 调用模块:

** 作 者:

** 日 期:

** 修 改:

** 日 期:

** 版本

****************************************************************/

引用三: 程序中的注释模板

/*———————————————————-*/

/* 注释内容 */

/*———————————————————-*/

8 程序

a. 程序编码力求简洁,结构清晰,避免太多的分支结构及太过于技巧性的程序,
尽量不采用递归模式。

b. 编写程序时,亦必须想好测试的方法,换句话说,”单元测试” 的测试方案应
在程序编写时一并拟好。

c. 注释一定要与程序一致。

d. 版本封存以后的修改一定要将老语句用/* */ 封闭,不能自行删除或修改,并要
在文件及函数的修改记录中加以记录。

e. 程序中每个block 的开头 ”{" 及 "}” 必须对齐,嵌套的block 每进一套,
缩进一个tab,TAB 为4个空格,block类型包括if、for、while、do等关键字引出的。

f. 对于比较大的函数,每个block 和特殊的函数调用,都必须注明其功能,举例如下

count.divisor = 1193280 / freq; // compute the proper count

OutByte((unsigned short)67, (unsigned char)182); // tell 8253 that a
count is coming

OutByte((unsigned short)66, count. c[0]); // send low-order byte

OutByte((unsigned short)66, count. c[1]); // send high-order byte

×××××××××××××××××××××××××××××××××××××××

bcb,delphi中的变量命名:

遵循匈牙利命名法,命
名必须有意义,制定如下规定

窗体: 以大写的W开始,如About版权窗体, 命名为WAbout

文件:以大写的F开始,如About版权窗体,文件命名为FAbout.cpp

按钮(Button):如退出按钮,命名为btnExit

……

基类: 加base标记,如报表基类,窗体命名为:WBaseRep, 文件命名为FBaseRep.cpp

转贴

> 1. 在.h/.cpp的开头应有一段格式统一的说明,内容包括:
> a. 文件名 (FileName);
> b. 创建人 (Creater);
> c. 文件创建时间 (Date);
> d. 简短说明文件功能、用途 (Comment)。

好习惯

> 2. 除非极其简单,否则对函数应有注释说明。内容包括:功能、入口/出口参数,必

> 时还可有备注或补充说明。

还是好习惯

> 3. 每列代码的长度推荐为 80列,最长不得超过120列;折行以对齐为准。
太宽了,我的限制是60列,因为文本方式下屏幕一共80列,如果你用BC这一类的编辑
器,窗口边框等又要占据一定空间,所以80列太宽

> 4. 循环、分支代码,判断条件与执行代码不得在同一行上。

很对

> 5. 指针的定义,* 号既可以紧接类型,也可以在变量名之前。
>
> 例:可写做:int* pnsize;
>
> 也可写做:int *pnsize;
>
> 但不得写做:int * pnsize;

建议采用第二种,除非附加另外一条规定:一次只声明一个变量,否则就会让人混淆,
比如:
int* a, b;
看起来b好像也是个指针,其实不是。

> 6. 在类的成员函数内调用非成员函数时,在非成员函数名前必须加上"::"。

这一条我倒觉得并不是必需的,我的看法是决不要让你的类成员函数和全局函数的名称
相同(或类似)

> 7. 函数入口参数有缺省值时,应注释说明。
>
> 例:BOOL CWpsDib::PaintDIB(CDC* pDC, CRect& rc,
> int nBrightness, file://*=0*//
> BOOL bGrayScale file://*=FALSE*// )

每个变量写一行,必要时加上/*in, out*/注释

> 8. else if 必须写在一行。

应该尽量避免else if这样的结构

> 9. 与‘{’、‘}’有关的各项规定:
>
> 9.1‘{’、‘}’应独占一行。在该行内可有注释。
> 9.2 ‘{’必须另起一行,‘{’ 之后的代码必须缩进一个Tab。‘{’与‘}’必须在

> 一列上。
> 9.3 在循环、分支之后若只有一行代码,虽然可省略‘{’、‘}’,但不推荐这么
> 做。若省略后可能引起歧义,则必须加上‘{’、‘}’。

持保留意见,因为GNU的代码规范是这样的:

if ( NULL == ptr )
{
// do something here
}

或者

if ( NULL == ptr ) {
// do something here
}

争论哪个更好并没有意义,关键是统一,如果用VC当然你的办法最方便,可是如果你用
emacs或者vi,就不是这样了。

> 10. 与空格有关的各项规定。
>
> 10.1 在所有两目、三目运算符的两边都必须有空格。在单目运算符两端不必空格。

> 在‘—>’、‘::’、‘.’、‘[’、‘]’等运算符前后,及‘&’(取地址)、‘*
> ’(取值)等运算符之后不得有空格。

> 10.2 for、while、if 等关键词之后应有1个空格,再接‘(’,之后无空格;在结

> 的‘)’前不得有空格。

我认为在括号两端加空格并不是什么错误,尤其是在一个条件十分复杂的if语句里

> 10.3 调用函数、宏时,‘(’、‘)’前后不得有空格。
> 10.4 类型强制转换时,‘(’‘)’前后不得有空格

同上

> 11. 与缩进有关的各项规定
>
> 11.1 缩进以 Tab 为单位。1 个 Tab 为 4 个空格

我认为这个值应该更大,我自己使用8个空格,如果你的代码因为缩进幅度太大而导致
折行,那么几乎可以肯定你的程序设计方案有问题。

> 11.2 下列情况,代码缩进一个 Tab:
> 1. 函数体相对函数名及’{’、’}’。
> 2. if、else、for、while、do 等之后的代码。
> 3. 一行之内写不下,折行之后的代码,应在合理的位置进行折行。若有 + – * / 等

> 算符,则运算符应在上一行末尾,而不应在下一行的行首。

这一条我反对,运算符应该放在下一行行首,以使人能清楚的知道这一行是续上一行
的,比如

if ( something
&& somethingelse
&& otherthings )

如果写做

if ( something &&
somethingelse &&
otherthings )

反而看不清楚

> 11.3 下列情况,不必缩进:switch 之后的 case、default。

这是典型的VC风格,不应该是强制性的

其实好的代码关键是要易读,这就要求结构清晰,风格统一,至于具体细节可以在工作
中逐步细化。

Delphi代码创建形式规范 1.0

Delphi代码创建形式规范 1.0
Bear, 2000-5-1

本规范的目的:给自己的代码一个统一而标准的外观,增强
可读性,可理解性,可维护性
本规范的原则:名称反映含义,形式反映结构

1、单元风格
2、各区风格
3、语句风格
4、命名规则

参考:Borland官方Object Pascal风格指南
Delphi5程序员指南编码标准

1、单元风格
 

{*******************************************************}
{ }
{ 项目名称 }
{ }
{ 版权所有 (C) 2000,2001 公司名称 }
{ }
{*******************************************************}

unit UnitName;
{*******************************************************
项目:
模块:
描述:
版本:
日期:
作者:
更新:
TODO:
*******************************************************}

interface

uses
—-,—-,—-,—-,—-,—-,—-,—-,—-,—-,—-,
—-,—-, —-,—-,—-,—-;

const
——————–;
——————–;
——————–;

type
——————–;
——————–;
——————–;
——————–;
——————–;
——————–;

var
——————–;
——————–;
——————–;

implementation

uses
—-,—-,—-,—-;

{$R *.RES}
{$R *.DFM}

——————————–;
——————————–;
——————————–;
——————————–;
——————————–;
——————————–;
——————————–;
——————————–;
——————————–;
——————————–;
——————————–;
——————————–;

end.

返回

2、各区风格
0、注释与空白
用{ } 不用 //
主题注释,函数过程目的说明,语句注释
空行 :版权块,类之间,方法之间–(两行) 方法内部块(一行)
空格 :用以增强清晰度
缩进 :两个空格

1、常量区
基本:

Const
—– = —-;
—– = —-;
—– = —-;
—– = —-;

扩展
前缀: 少则C_—;多则可以每个主题有一个前缀
Const

{ 主题1 }
C_— = —-; { 含义 }
C_— = —-; { 含义 }
C_— = —-; { 含义 }
C_— = —-; { 含义 }
{ 主题2 }
—– = —-;
—– = —-;
—– = —-;
—– = —-;

资源字符串,放在变量区后面

resourcestring

const
S_— = ‘—-‘;
S_— = ‘—-‘;
S_— = ‘—-‘;

例子:

CM_BASE = $B000;
CM_ACTIVATE = CM_BASE + 0;
CM_DEACTIVATE = CM_BASE + 1;
CM_GOTFOCUS = CM_BASE + 2;
CM_LOSTFOCUS = CM_BASE + 3;
NumPaletteEntries = 20;
BoxPoints : array[0..5, 0..2] of GLfloat =
( (-1, 0, 0),
( 0, 1, 0),
( 1, 0, 0),
( 0, -1, 0),
( 0, 0, 1),
( 0, 0, -1) );

{ Variant type codes (wtypes.h) }

varEmpty = $0000; { vt_empty }
varNull = $0001; { vt_null }
varSmallint = $0002; { vt_i2 }
GIFVersions : array[gv87a..gv89a] of TGIFVersionRec = (’87a’, ’89a’);

2、类型区
数据类型–>不提供服务的数据类型
T—- = ———
对象类型–>有状态并提供服务的实体
T—- = class(—-)
private
——–
——–
protected
——–
——–
public
——–
——–
published
——–
——–
end;

按字母排序

Private
1、所有数据放在Private 区,以F打头
2、所有事件属性对应的方法指针放在Private 区,以F打头
3、属性的Get与Set方法放在Private 区–>不准备被继承
4、响应消息的方法放在Private 区
protected
1、被子类调用的但不能被外界调用的方法与属性
2、供子类重载的方法 virsual; virsual; abstract
public
1、构建析构方法
2、供外界调用的方法
3、供外界调用的属性
published
1、出现在Object Inspector里供设计时用的属性
2、出现在Object Inspector里供设计时用的事件响应

例子:

TGIFVersion = (gvUnknown, gv87a, gv89a);
TGIFVersionRec = array[0..2] of char;
PInterfaceTable = ^TInterfaceTable;
TInterfaceTable = packed record
EntryCount: Integer;
Entries: array[0..9999] of TInterfaceEntry;

{ forword declairation }
TGIFImage = class;
TGIFSubImage = class;
{—————————
TGIFItem
—————————}
TGIFItem = class(TPersistent)
private
FGIFImage: TGIFImage;
………….
end;

3、变量区
定义全局变量
注意不要有缺省的类对象变量,在调用者中声明!
var
———–: ——-;
———–: ——-;
例子:
GIFDelayExp: integer = 10; { Delay multiplier in mS.}
GIFDelayExp: integer = 12;

4、实现区
{———————————————————
主题
———————————————————-}

{ 方法的目的 }
procedure —————————-
begin
——–;
——–;
end;

{ 方法的目的 }
function —————————–
begin
——–;
——–;
end;

5、过程与函数
命名
格式

返回

3、语句风格
1、简单语句
——-;
2、复合语句
begin
—–;
—–;
end;

3、赋值语句
— := ——-;
— := (– + –)* (– / –);

4、局部变量
var
—: —;
—: —;
对于逻辑上并列的变量组:
var
—,
—,
—: —;

5、数组声明
— = array [*..*] of —;

6、if 语句
if (——–) then
————-;

if (——–) then
begin
————-;
————-;
————-;
end;

if (——–) then
————-;
else
————-;

if (——–) then
begin
————-;
————-;
————-;
end else
————-;

if (——–) then
begin
————-;
————-;
————-;
end else
begin
————-;
————-;
————-;
end;

if (——–) then
————-
else if (——–) then
————-;

7、for 循环

for I := ——– to ——– do
————-;

for I := ——– to ——– do
begin
————-;
————-;
————-;
end;

for I := ——– to ——– do
if (——–) then
begin
————-;
————-;
————-;
end;

for I := ——– to ——– do
with ——– then
begin
————-;
————-;
————-;
end;

8、while 循环

while —— do
begin
————-;
————-;
————-;
end;

9、repeat 循环
repeat
————-;
————-;
————-;
until ——;

10、case 语句

case ——– of
——– : ————-;
——– : ————-;
——– : ————-;
else ————-;
end;

case ——– of
——– :
—————————————————————–;
——– :
—————————————————————–;
——– :
—————————————————————–;
else
—————————————————————–;
end;

case ——– of
——– : begin
————————–;
————————–;
————————–;
end;
——– : begin
————————–;
————————–;
————————–;
end;
——– : begin
————————–;
————————–;
————————–;
end
else begin
————-;
————-;
————-;
end;

end;

11、with 语句
with ——– do
————-;

with ——– do
begin
————-;
————-;
————-;
end;

12、try 语句
try
————-;
————-;
————-;
finally
————-;
————-;
————-;
end;

try
try
————-;
————-;
————-;
except
————-;
————-;
end;
finally
————-;
————-;
————-;
end;

13、其它
运算:运算符前后要有空格
w1[n] := ((i + 1) * v0[n] + j * v1[n] + (k – 1) * v2[n]) / depth;

— = —
— >= —
— <= —
— > —
— < —
— <> —
— := –; 赋值
–: —-; 类型

同一类型且含义逻辑上不并列的变量 20个字符长的变量名
private
——- : ——-;
——- : ——-;
——- : ——-;
——- : ——-;
——- : ——-;
var
——- : ——-;
——- : ——-;
——- : ——-;
——- : ——-;
——- : ——-;
function ———————(–: —-; –: —-; –: —-): —-;

同一类型且含义逻辑上并列的变量 如 Error0,Error1,Error2 ; R,G,B
private
——- ,
——- ,
——- ,
——- ,
——- : ——-
var
——- ,
——- ,
——- ,
——- ,
——- : ——-
function ———————(–, –, –: —-; var –, –, –: —-): —-;

T——- = class(——-)
private
F——-: ——-;
F——-: ——-;
F——-: ——-;
function ————–: ——-;
procedure ————–;
protected
function ————–: ——-;
procedure ————–;
function ————–: ——-; virtual; abstract;
public
constructor Create(——-: ——-); override; {if need to do something after Create}
destructor Destroy; override; {if need to do something before Destroy}
function ————–: ——-;
procedure ————–;
property ——-: ——- read F——-;
published

end;

14、形式反映结构
例子:
TetIndex : array[0..3] of TInteger3v =
( (0, 1, 3),
(2, 1, 0),
(3, 2, 0),
(1, 2, 3) );
Cursors: array[0..4] of TIdentMapEntry = (
(Value: crDefault; Name: ‘crDefault’),
(Value: crArrow; Name: ‘crArrow’),
(Value: crCross; Name: ‘crCross’),
(Value: crIBeam; Name: ‘crIBeam’) );

if (dwFlags and PFD_DRAW_TO_WINDOW) = 0)
or( (dwFlags and PFD_SUPPORT_OPENGL) = 0)
or( (dwFlags and PFD_DOUBLEBUFFER) = 0)
or (iPixelType <> PFD_TYPE_RGBA)
or (cColorBits < 16)
)
) then
raise Exception.Create(‘Inappropriate Pixel Format chosen.’);

glBegin(shadeType);
glNormal3fv(@n0);
glVertex3fv(@dodec[a, 0]);
glVertex3fv(@dodec[b, 0]);
glVertex3fv(@dodec[c, 0]);
glVertex3fv(@dodec[d, 0]);
glVertex3fv(@dodec[e, 0]);
glEnd();

dodec[0, 0] := -alpha; dodec[0, 1] := 0; dodec[0, 2] := beta;
dodec[1, 0] := alpha; dodec[1, 1] := 0; dodec[1, 2] := beta;
dodec[2, 0] := -1; dodec[2, 1] := -1; dodec[2, 2] := -1;

procedure glutWireTorus(
innerRadius : GLdouble; //———
outerRadius : GLdouble; //———
nsides : GLint; //———
rings : GLint ); //———
case FRunDirection of
rdRightToLeft : begin
StY:=CnY;
StX:=Width – CurrentStep;
end;
rdLeftToRight : begin
StY:=CnY;
StX:=-CurrentStep;
end;
rdBottomToTop : begin
StX:=CnX;
StY:=Height – CurrentStep;
end;
rdTopToBottom : begin
StX:=CnX;
StY:=CurrentStep – RTHeight;
end;
else begin
StX:=CnX;
StY:=CnY;
end;
end;

case (DitherMode) of
dmNearest:
Ditherer := TDitherEngine.Create(Bitmap.Width, ColorLookup);
dmFloydSteinberg:
Ditherer := TFloydSteinbergDitherer.Create(Bitmap.Width, ColorLookup);
dmStucki:
Ditherer := TStuckiDitherer.Create(Bitmap.Width, ColorLookup);
dmSierra:
Ditherer := TSierraDitherer.Create(Bitmap.Width, ColorLookup);
dmJaJuNI:
Ditherer := TJaJuNIDitherer.Create(Bitmap.Width, ColorLookup);
dmSteveArche:
Ditherer := TSteveArcheDitherer.Create(Bitmap.Width, ColorLookup);
dmBurkes:
&n

据库表的划分的标准和方法

所谓范式就是符合某一种级别的关系模式的集合。通过分解把属于低级范式的关系模式转换为几个属于高级范式的关系模式的集合。这一过程称为规范化。

1、&nbsp; 第一范式(1NF):一个关系模式R的所有属性都是不可分的基本数据项。
2、&nbsp; 第二范式(2NF):关系模式R属于第一范式,且每个非主属性都完全函数依赖于键码。
3、 第三范式(3NF):关系模式R属于第一范式,且每个非主属性都不伟递领带于键码。
4、&nbsp; BC范式(BCNF):关系模式R属于第一范式,且每个属性都不传递依赖于键码。

不到第一范式:
create 学生(姓名,性别年龄) —-(因为性别年龄列包括了两个属性)
第一范式不到第二范式:
create 学生(姓名,性别,年龄,语文老师名) –(因为老师列不是完全函数依赖于键码)
第二范式不到第三范式
create 学生(姓名,性别,年龄,语文老师id,数学老师id)
create 老师(老师id,老师名,老师年龄)
第三范式不到第四范式
create 学生(学生id,姓名,性别,年龄,籍贯)
create 关系表(学生id,老师id)
create 老师(老师id,老师名,老师年龄,籍贯)
第四范式
create 学生(学生id,姓名,性别,年龄,籍贯id)
create 关系表(学生id,老师id)
create 老师(老师id,老师名,老师年龄,籍贯id)
cteate 籍贯表(id,籍贯)

第一范式:
字段中不能含有多个值,及不能将一个员工的所有信息放入一个字段,要建立NAME,AGE等 字段分别存放
第二范式:
每个表中必须有主键,能够唯一确定表中的一条记录。例如身份证号码就可以作为员工信息的主键,能够唯一确定一个员工
第三范:每个表中不能含有其他表中的非主键字段,主要是为了减少数据冗余

一般数据库设计满足前三范式是就可以了
消除多主键—–1范式
消除不完全依赖—–2范式
消除传递依赖—–3范式

讀書筆記一則,程序員的個人性格

  提要:软件开发是一个“以人的智力为加工原料”的工程活动,在开发过程中会不断的对智力和性格作研究。需要注意20/80原则,并不是最勤奋的才是最优秀的。编程的工作难以检查,是否成为高手和个人性格有关。你无法改变智力,但可以改变性格。在软件开发者的成长过程中,EQ还是占主要因素。

   1.        聪明和谦逊

  一个人越谦虚进步越快,承认自己的无知才会去正视和弥补自己的错误。理解程序需要通常很强的对细节把握和理解能力,这对程序员的智力有很大要求,但是很好的利用聪明要比你到底有多聪明要重要的多。有个程序员需要也需要谦虚,用谦虚去促进自己的智慧,使得自己更加聪明。这是软件开发者的两个基本素质要求,它们互相依赖促进,有时候也互相排斥,把握好自己的才智和谦虚就能更大程度提高能力。

  也许某些事情很麻烦和困难,我们这时就需要使用一些方法去聪明的解决它们。比如:采用良好的程序风格便于理解、采用分解的办法使复杂问题简单化、多进行评审和测试,多和别人讨论和关注软件质量问题、尽量使用高度抽象的思维使问题一般化,提高重用率减少工作量、如果问题走进一个“死胡同”不妨和杯咖啡放松情绪,或和别人交谈交流观点,这是解决钻牛角尖的好方法。

  2.        好奇心

  一旦你认为自己理解程序的能力是有限的,而且你意识到,进行有效编程是补偿自己能力的方法时,你就开始了你职业生涯中漫长的探索过程。对技术的好奇很重要,否则你将在知识爆炸的时代迅速落伍。别在忙碌的工作或琐事中,失去了对学术,自然和生活的好奇心和激情。我们可以在:

  1         开发过程中建立自我意识。通过在开发中有意识的可以使用进行新技能的锻炼,多对开发工程进行观察,和学习其他解决方法,这样就对整个项目有很强的把握能力,甚至可以带领整个团队走向更好的方向。如果你现在做的是市场前景很好的工作,那也意味着工作中的某些技术可能会很快被淘汰,注意保持好奇心和创造力。

  2         实验。了解编程的一个有效方法就是对编程和开发过程做实验。你可以编写一个程序并观察它是如何工作的,调试器里跟踪程序的执行把握它的特性。用个小程序去检验一个不太了解的概念,这对增进理解有非常大的帮助。或者用一个短程序,去试图制造一些错误,通过错误去学习。错误不是罪过,没有从错误中学到什么那才是罪过。

  3         阅读解决问题的有关方法。解决问题是软件开发过程核心的活动。一个奇怪的现象:人们通常不能从自己面临的问题找出解决的方法,即使这个方法很简单。

  4         行动前先做好分析和设计。尽管实践和分析设计过程有很大的矛盾,但是好的分析会避免让你过早走向一个错误的方向,好的设计可以避免混乱。

  5         学习成功或失败项目的开发经验。学习编程的好方法是向一些优秀的程序员学习。应该要注重项目的战略思想,把握项目中解决关键难点的战术。任何成熟的科学,都是通过解决问题发展起来的。这些问题通常被看一些被良好解决的例子,并可为将来工作做指导。(这可能也是目前很多公司注重工作经验的原因吧?)我们应该努力对别人工作存在的问题做研究,学习别人的无论成败的解决办法都是很有意义的。多拿自己的代码和比你优秀人的代码做比较,看看你们间有什么异同?为什么会有这样的差异?谁的更好?为什么?也要多让自己的代码让别人评价,这样可以提高自己的程序质量。

  6         阅读手册,书籍和期刊。手册中往往对带有些可以直接调用的子程序,这对我们研究和解决具体问题有很大帮助。书籍中往往是介绍系统理论,多阅读可以提高专业能力;期刊中常常包含着流行的技术和观点可以开阔眼界。

  3.        诚实

  编程生涯成熟的部分标志是坚持诚实。通常是:不假装自己是高手、乐于承认错误、尊重编译器的警告、对程序有清晰的了解,而不是编译看其是否有错、提高实际状态报告、提供实际方案评估,在上级面前坚持自己的意见。你最好假装自己知之甚少,听别人的解释,向他们学习,并且评估他们是否了解其正在讨论的东西:)

  你应该对自己能力做某种程度评估,认为自己完美是一个不妙的信号。错误正如潮流一样是一个复杂的活动,如果你过去没犯过错误,那么没有人会将错误归咎于你。所以正视自己的错误。当你并不了解程序时,编译运行并不是解决问题的方法。测试是证明错误的存在,而不是保证没有错误。如果不能深入理解程序,就不能深入测试。依据事实给出准确的状态报告,不能欺骗自己和别人,这是充分合作的前提。不能因为压力而否定符合规律的做法——这个项目需要10人月,要用5人月完成除非降低性能或其他做法——准确的向上司说明情况。

  4. 交流与合作

  真正优秀的程序员应学会怎样和别人工作和娱乐。真正阅读你写出的程序是人,而不是给计算机——注意代码的可读性。绝多数高水平的程序员坚持自己代码的可读性,并抽出充足时间这么做。对程序员能力的界定标准:

  1 初学者

  是能使用一种语言基本能力的程序员,他能使用子程序、循环、条件语句或其他许多语言特征。

        2 中间者

            有使用许多语言的能力,并且至少非常熟悉某一种语言。

        3 专家

            对其语言或环境或这二者有很深的造诣。这种级别的程序员对公司是有价值的,而且有些程序员往往就停留在这个水平上。

        4 大师

            有着专家那样的专业知识,并且意识到编程只是15%和计算机交流,其余85%是和人打交道。一般程序员只有30%时间或更少。而且大师注重给人看的清晰易懂的代码,并注意建立有关文档。

            不强调可读性的高水平代码者可能停留在级别3上面。并且根据经验,编写不可读代码的主要原因是:代码质量差或是编写者自己并不能完整地理解自己的代码。当你知道自己的水平后,不必内疚和自愧。在你知道如何提高水平后,你倒应该为自己停留在初学者或专家水平上有多长时间而内疚。

  5.       创造力和纪律

  虽然一些有创造力的程序员将各种标准和约定视为对其创造力的阻碍,但是没有这些约束项目实现是不可能的。不要在无关紧要的领域建立约定,应该在值得的地方发挥你的创造力。一个杰出的程序员需要遵守许多规则。如果编码之前不分析需求就设计,那么你就学不到项目的许多东西,那样工作就像小孩画画而不是艺术品。

  6.  懒惰

  懒惰的三种形式:1 拖延自己讨厌的工作 2 迅速解决讨厌的任务以摆脱任务 3 写一个工具来完成讨厌的工作解脱自己。当你不是透过玻璃看问题的时候,你就看到了懒惰的另一方面。“赶着做”是一种多余和没有必要的“努力”。有效的工作最重要的现象是人们在思考种往往显得冷静而不忙。一个一直很忙碌的程序员不是好程序员,因为他并不是在使用对于他来说最有价值的工具和头脑。

  7.  并不是你想象中起作用的性格

  坚持:这是一笔财富也是不利的条件。你可以称它为顽固或者坚强,这完全取决于应用它的场合。在多数情况下,软件开发的“坚持”就是顽固的意思!当你遇到新问题时候,你再固执己见并不是好事。你应该迅速适应它,或原方案并不起作用时,学会用另一种解决方法。调试中,当你发现一个困扰你4个小时之久的错误时,你一定感到非常满意。但是实际上,如果你在一段时间——通常为15分钟没有取得任何进展时,你应该放弃找错。用你的潜意识去思考问题,尝试用别的方法解决问题,甚至重写厌烦的代码段。和计算机错误做斗争时不明智的,你应该尽量避免它们。知道在时候需要放弃时困难的,但是必须面对一个问题:当你觉得自己受挫折时,是否考虑尝试其他不同的方法。

        经验:过于依赖经验会导致知识的落伍。今天的经验必须为明天的工作服务。如果不在过去经验中去归纳总结出一些有价值的原则或规律并改变自己去适应它们,那么经验也将一文不值。如果你的经验还是停留在上一次战斗而不是下一次,也不因时间做出应变,那么经验更像是一个阻碍。此外,错误的经验往往得不到客观的评价。错误的经验可以让你得出重要的不同结论,学习其他人的错误经验是一个好方法——你更可以对它做客观的检查。其他领域有成功经验的专业人员往往使人放心,而在软件开发中,知识更新迅速使得此领域中“经验”处于一个奇怪的地位。为了使自己有所价值,你必须紧跟潮流,对于年轻求知欲旺盛的程序员在这点有优势,而有些年老的程序员认为自己有所资格而厌倦一年接一年都要证实自己的能力。如果你已工作了10年,你得到了10年的经验未必是真正的经验——你如果坚持不断地学习,你就能得到经验,但如果你并不想学到什么,不管多少年你也学不到什么。

  编程狂:如果你还没有至少在一个相同的项目上花费一个月的时间——一天工作 16 个小时;为了发现你的程序中最后一个错误睡眠中你也念念不忘它,你接连几天没日没夜地工作——即使你所编的程序并不复杂,那么你可能不会意识到编程中有某种令人兴奋的东西。                              Edward Yourdon

  这种对编程的痴迷纯粹是胡闹,并且几乎注定要失败。但是那些通宵程序员使你觉得他们是世界上最好的程序员,但是随后你不得不花费几周的时间来修正你在这短时间的辉煌中所带来的错误,你可能对编程非常热爱,但是你应能冷静地处理这个问题。

  8.  习惯

  好的习惯起作用是由于你为一个程序员所作的大部分事情是你在无意识中所完成的。成为某方面好的或差的程序员,主要是靠你自己的所作所为。你所作所为习惯,决定了你的编程品行。最终,你的习惯好坏决定了你是否能成为一位好的程序员。当你开始学习某一件事时,你应按正确的方式学好它。当你开始学时,你已对其进行了思考,并且你可在正确或错误的途径间作出轻易的选择。在你作过一段时间后,你对你所作的不太注意,此时“习惯的力量”会开始起作用。确保起作用的习惯是你所希望的。

小结

  ·你的个人性格直接影响你编写计算机程序的能力。

  · 最有明显作用的性格为:谦虚、好奇心、诚实、创造性和纪律,还有文明的“懒惰”。

  · 高级程序员的发展和生成与天才并无多大联系,任何事情都和个人的发展有关。

  · 令人吃惊的是,小聪明、经验、坚持和欲望既可帮助你也能妨碍你。

  · 许多程序员不主动去吸收新信息和新技术,而是靠偶然地上获得一些新信息,如果你抽出少量时间学习别人的编程经验,过一段时间后,你将在你的同行中脱颖而出。

  · 好的性格对养成良好习惯有很大影响。为了成为一位高水平的程序员,你应养成良好的习惯,其余的就会随之而来。