当前位置:文档之家› C#代码--编写高质量C#程序

C#代码--编写高质量C#程序

C#代码--编写高质量C#程序
C#代码--编写高质量C#程序

1.1 换行的讲究 5

1.1.1 寻找最佳的断行位置5

1.1.2 每行只写一条语句7

1.1.3 分行定义变量8

1.2 避免代码过于拥挤9

1.2.1 使用空行分隔代码块10

1.2.2 使用空格降低代码密度13

1.3 如何缩进15

1.3.1 嵌套或包含关系引起的缩进17

1.3.2 因换行而产生的缩进20

1.3.3 使用空格还是Tab键21

1.4 大括号 22

1.4.1 大括号的位置22

1.4.2 空的大括号结构23

1.4.3 仅包含单个语句的结构体26

1.5 保持项目文件的条理性29

1.5.1 解决方案的结构呼应29

1.5.2 代码文件的结构29

1.5.3 使用#region标记32

第2章养成良好的注释习惯33

2.1 何时需要注释33

2.1.1 解释代码的意图34

2.1.2 对局部变量的说明35

2.1.3 充当代码标题36

2.1.4 指出例外情况40

2.1.5 开发提示 40

2.2 注释的格式 41

2.2.1 单行注释42

2.2.2 多行注释44

2.3 正确使用XML文档注释45

2.3.1 结构与类的XML文档注释46

2.3.2 属性的XML文档注释47

2.3.3 方法的XML文档注释49

2.3.4 构造函数的XML文档注释50

2.3.5 事件的XML文档注释51

2.3.6 枚举类型的XML文档注释53

2.3.7 泛型的XML文档注释53

2.3.8 其他标记54

总的来说,如果多看看MSDN自身的类库参考,你会发现其实XML文档注释最终形成的就是这样的结果。MSDN本身就是一个最好的XML文档注释的范例,我们可以在实践过程中不断地进行模仿和学习。第7章如何使用函数57

7.1 为什么要使用函数57

7.1.1 函数与方法57

7.1.2 代码复用59

7.1.3 隐藏细节61

7.2 函数重载65

7.2.1 重载的语义65

7.2.2 保持核心代码唯一70

7.3 参数的设计74

7.3.1 参数的命名74

7.3.2 不要使用保留项74

7.3.3 变长参数列表75

7.3.4 何时使用ref参数和out参数77

7.3.5 参数的顺序78

7.3.6 重载函数的参数一致79

7.4 参数检查82

7.4.1检查零值及空引用83

7.4.2 检查枚举类型84

7.4.3 防止数据被篡改85

7.4.4 在何处检查合法性87

7.5 函数出口88

7.5.1 返回值的用法88

7.5.2 离开函数的时机89

假设我们写的是文章而不是程序,那么你一定觉得诸如文章应该分为若干个自然段、每段开头空两格之类的规则是理所当然的。如果段落的开头不空两格,或者干脆把整个文章写成单独的一段,仔细想来似乎也不会影响文章实质内容的表达。既然如此,我们为什么还要在形式上下功夫呢?设想一下,如果你手中的这本书既无章节也无目录,正文中的不同内容都使用同样的字体字号印刷,几百页纸从头至尾洋洋洒洒如念经般地“一气呵成”,你还有耐心看下去吗?

这是一个人人都能理解的道理,可是当文章变成程序的时候,就不是每个人都能想得通的了。不仅仅是初学者,甚至一些熟练的开发人员,也会写出凌乱不堪的代码。许多人一定有过这样的经历:一年半载之后,自己原来写的程序就完全看不懂了。如果这段程序只是为了交作业,或者临时一用,那还可以不去追究,但如果这是一个商业软件,现在需要根据客户的要求进行修改的话,工作量可就大了——你不得不先花时间把你原来的思路看懂。

肯定会有人反驳:代码是给机器运行的,又不是给人看的,写那么好看有什么用?

他的话只对了前半句:代码确实是给机器运行的,可是机器总共才需要看它几分钟?你花一个月编写的程序,机器顶多两三分钟就编译好了——在这两三分钟之前,这代码不都是你在看吗?开发软件编写代码不是一朝一夕的事情,更多的情况下,一个软件的开发要经历很长的时间,并且常常由多人合作完成。一个庞大的软件项目,可能会动用上千名程序员工作数年!如果把代码写得连自己都看不明白,怎么与别人交流?同一个开发团队内,一定要保持良好且一致的代码风格,才能最大化地提高开发效率。

有的初学者会问:我现在只是一个人写程序,并不需要和其他人合作,这些条条框框还有什么必要吗?

要知道,团队协作只是一个方面。我经常遇到这类情况,一些初学者拿着他的程序来说:“这个怎么不能编译?”我帮他把代码整理了半天,发现有一个地方丢了半个大括号。如果他写程序的时候能够稍加注意一些的话,相信此类错误完全可以避免。保持良好的编程习惯,能够避免的错误还远不止这些。

如果说程序代码中对算法的清晰表述是通过长期训练而获得的,那么本章要介绍的这些方法则无需伤神,你不必对代码做任何实质性的改动,只需要添加一些空行与空格,就可以使其可读性大大提高——这些规则就像写文章应该分段一样简单,只要愿意遵守,那么别人在第一眼看你的代码时,必能感觉到你那良好的编程修养,即所谓“见字如见人”。

1.1 换行的讲究

虽然你完全可以在C# 里将所有的代码都连在一行里书写,但想必没有人愿意这么做,谁也不会自己折磨自己的眼睛,何况大多数鼠标对于上下翻页的支持都比左右翻滚好得多。我相信,这也是大多数人接受将每条语句分行书写的原因,很少有人会怀疑这一点的合理性。例如下面这行代码,虽然结构很简单,但是它实在太长了,所以被分成了两行:

代码示例1-1:由于代码过长而进行断行

bitmap = new Bitmap(size.Width, size.Height,

System.Drawing.Imaging.PixelFormat.Format32bppArgb);

这一点我相信大家都能理解并愿意遵循,然而问题的焦点并不在于要不要换行,而在于在什么位置换行。

1.1.1 寻找最佳的断行位置

写程序不能像写文章那样,什么时候顶到了边界就换,而必须按照其语法规则,在可以换行的位置断开。例如,对于包含一个超长表达式的语句来说,我们可以在某两个表达式项之间将其断开,如下所示:

代码示例1-2:通过断行使代码更加清晰

if (f == ImageFormat.Jpeg.Guid ||

f == ImageFormat.Tiff.Guid ||

f == ImageFormat.Png.Guid ||

f == ImageFormat.Exif.Guid)

{

supportsPropertyItems = true;

}

else

{

supportsPropertyItems = false;

}

原本一个很长的条件表达式,通过在“||”运算符处换行,显得更加地清晰。有一点需要我们注意的是,当我们进行折行时,要将折行位置处的分隔符(如前一例中的逗号,这一例中的“||”运算符等)留在上一行的行末,给人以“此行并未结束”的直观印象。这就好像在英文书写中,如果你需要将一个单词拆开,就需要在前一行末尾加上连字符,以表示那个单词并没有结束。

可以看出,换行在防止代码超出屏幕边界的同时,还影响着代码的表达。因此如何选择合适的换行位置也是很有讲究的。有的时候,我们并不一定非要在临近右边界的时候才去换行,如果存在更为合理的分法,就应当采用,例如下面的情况:

double containerAspectRatio = (double)container.ClientWidth /

container.ClientHeight;

按理说这样的断行并没有什么问题,它在表达式的两项之间断开,并将运算符留在了上一行的行末。但是,我相信如果换一种断行方式的话,能够更加清楚地表达出原来的逻辑:

代码示例1-3:寻找最佳的断行位置

double containerAspectRatio =

(double)container.ClientWidth / container.ClientHeight;

如此一来,这个除法算术表达式就显得较为完整,相比前一种写法而言更能体现其内在的逻辑关系。通常我们会选择整个表达式中最高的关系层次进行断行,例如上述代码中的“赋值号”和“除号”都是可以考虑的断行点,但相比较而言,除号连接的这个算术表达式只是整个赋值表达式的右半部分,如果在除号处断行,那么不但整个表达式会被截断,连局部的这个除法表达式也会被截断;反之,我们选择在赋值号处换行,可以保持除法表达式的完整,最大限度地减少换行对语句整体结构的破坏。

同样的道理,为了将逻辑体现得更为清晰,我们甚至可以将函数调用中的每一个参数都分行书写,如同下面这样:

代码示例1-4:将函数调用中的每一个参数都分行书写

Rectangle imageBounds = new Rectangle(

itemBounds.X + padding,

itemBounds.Y + padding,

itemBounds.Width - padding * 2,

itemBounds.Height - padding * 2

);

当参数数量较多,参数较长或者包含表达式的时候,这种排版比起单独写成一行更为直观醒目。

对于LINQ查询表达式来说,将每个子句单独写成一行也是好的习惯。因为这同时符合了T-SQL语言的文化传统。例如:

代码示例1-5:将LINQ查询表达式中的每个子句单独写成一行

IEnumerable highScoresQuery =

from score in scores

where score > 80

orderby score descending

select score;

1.1.2 每行只写一条语句

如果说换行是为了防止屏幕左右滚动的话,那么当这个情况不存在的时候,一些人就开始打算充分利用屏幕空间了:

private static void Swap(object a, object b)

{

object temp;

temp = a; a = b; b = temp;

}

看起来好像确实没有占据多少屏幕空间,这只是把三条很短的语句凑在一行了而已——关键的理由是:它不会引起屏幕的左右滚动。但是当人们已经习惯于一行一条语句的时候,很可能就会忽视这里有三条语句这个事实(不要指望每次遇到的都像这个例子一样地简单)。更为重要的一点是,编译器总是按行来进行设计的,将多条语句写在一行会引起不必要的麻烦,例如:你将永远无法把断点设置在后面的语句上:

图1-1:一行代码包含多条语句时的断点设置[1]

有的读者会觉得,如果代码复杂,当然应该分开书写,没有必要去节省那点屏幕,但是如果像这个例子中这么简单,写在一起也不会带来什么麻烦。单纯地看来,他的话不无道理,可是,对于一个开发团队,或者将要进入开发团队的人来说,最重要的是“统一”。如果我们允许将多条语句合并到同一行代码内,那么怎样的代码才算“简单”到可以合并的程度?是宽度小于50个字符的可以合并,还是宽度小于51个字符的可以合并?当一条规定无法被准确地定义的时候,它也就无法执行,从而必将在整个开发团队中产生不一致性,最终导致更多的混乱。

1.1.3 分行定义变量

我们再来看一种情况,这类代码出现的机率更为频繁,它是将相同数据类型的几个变量声明放在了同一条语句中:

int num, factor, index, length;

如果我说我反对这种写法,一定会有读者大叫起来:这明明是单独的一条语句,何况C# 允许我们在一条语句内声明多个变量,如此一来还可以少写几个“int”,为什么不行?

这种写法,显而易见会给注释带来很大的麻烦。把它们都写在一起以后,我怎么给每个变量添加注释呢?如果是分开书写的,那么我可以很容易地为每一个变量添加单独的注释,就像这样:

代码示例1-6:将每个变量分行定义将有助于单独注释

// 要计算的数值

int num;

// 表示影响因子

int factor;

// 元素所在的索引号

int index;

// 数据列表的总长

int length;

如果觉得这种写法较为繁琐,一定要节约那几个“int”,以强调它们的数据类型相同的话,也可以采取下面的写法:

代码示例1-7:变量分行定义的折衷方案

int num, // 要计算的数值

factor, // 表示影响因子

index, // 元素所在的索引号

length; // 数据列表的总长

这种方式只使用了一条声明语句,但是每个变量都书写在单独的行上,便于有针对性的注释。

1.2 避免代码过于拥挤

想想人们为什么喜欢为文章添加各级标题以及其他复杂的格式,是因为美观吗?也许是的,但我相信这些格式可以更容易地让人们理清思路。可是在程序中,我们无法使用这些手段,所有的代码都是纯文本的,即使Visual Studio的代码高亮功能可以为代码的不同部分标上不同的颜色,但这并不能真正影响到代码本身。因此,光是换行还是不够的,我们还需要更多的手段。

1.2.1 使用空行分隔代码块

适当地添加空行则是一个非常有效的代码整理方式——有点像文章中的分段,一段意思也许需要若干个句子才能表达清楚,在表达下一段意思之前,应当另起一段。

首先,每个C# 代码文件是从命名空间引用开始的,一组引用结束之后,则是命名空间的声明及类型的声明。很显然地,在命名空间引用与命名空间声明之间,应该留有一个空行以示区隔:

代码示例1-8:在命名空间引用之后添加空行

using System;

using System.Collections.Generic;

using System.Drawing;

using System.Drawing.Imaging;

using System.IO;

using System.Text;

using Avilla.Metadata;

using Avilla.Searching;

// 这里用空行隔开namespace Avilla

{

// 下面的内容省略

一个空行,意味着不同的功能块的分隔,如果读者稍加留心,就会发现Visual Studio自动生成的代码,总是在类型的各个成员之间留有一个空行。我们在书写代码的时候,也可以模仿这一格式:

代码示例1-9:在类型的各个成员之间添加空行

///

/// 表示一条搜索条件的抽象基类

///

public abstract class SearchCondition

{

///

/// 初始化一个 类型的实例,并指明是否区分大小写

///

/// 是否区分大小写

protected SearchCondition(bool caseSensitive)

{

this.caseSensitive = caseSensitive;

}

// 这里用空行隔开 protected bool caseSensitive = false;

///

/// 获取或设置一个 类型的值,以指示是否区分大小写

///

public bool CaseSensitive

{

get { return caseSensitive; }

set { caseSensitive = value; }

}

// 这里用空行隔开 ///

/// 获取表示此搜索条件的 SQL 筛选条件表达式

///

///

/// 返回一个字符串形式的条件表达式,可直接用于 SQL 语言中的 WHERE 子句

///

public abstract string GetFilterExpression();

}

这样排版无疑会使得每个成员的代码段更富独立性,绝大多数的编译器,在自动生成代码时都会遵照此方式排版。您可能会发现,上例中的caseSensitive字段与CaseSensitive属性之间并未留有空行,这是为了强调字段与其对应用于公开访问的属性之间的联系,关于类似情况,我们将在后面的章节详细讨论。

然而,一个空行意味着的不仅仅是功能模块的界限,它更是对代码逻辑块的划分。我们无法期望每个操作都只通过一行代码一条语句来完成,大多数情况下,它们都需要许多行代码来执行一个完整的操作。例如,你想查询数据库,那么你需要先生成SQL代码,建立命令,然后执行这个命令并填充至数据集。这中间大约需要使用四五行代码,而这四五行代码便组成了一个相对紧密的逻辑块,它与其后面的其他逻辑块即可以通过一个空行来进行分隔。请看下面的一个例子:

代码示例1-10:用空行分隔逻辑块

public static string[] GetPhotoIds(string filterExpression, string sort,

bool caseSensitive)

{

// 第一个逻辑段代码根据处理后的参数取得数据行

xml.Photos.CaseSensitive = caseSensitive;

DataRow[] rows =

xml.Photos.Select(filterExpression, sort ?? string.Empty);

// 遍历数据行,取出需要的元素

string[] ids = new string[rows.Length];

for (int i = 0; i < rows.Length; i++)

{

ids[i] = (string)rows[i]["Id"];

}

// 返回结果

return ids;

}

这个函数的目的是根据指定的筛选条件和排序规则返回照片的标识号(Photo IDs),函数内部自然形成了三个逻辑段:先是根据要求取得原始数据,然后从原始数据中提取我们需要的部分,最后将结果返回。用空行将这三个逻辑区分隔开来将会更加有利于我们理解其思路。关于注释的合理使用,我们会在后面的章节中再专门介绍。

既然空行可以起到分隔代码,提高清晰度的作用,那么有的朋友也许会为了强调这种分隔效果,多加几个空行。可事实的效果是,连续的多个空行,在并未提高多少清晰度的同时,浪费了屏幕的空间,而且会让人觉得前后两个代码段并不相关——事实上它们应该是相继执行的。空行的意义和文章的段落一样,仅在于表示一个停顿,而并非结束。

1.2.2 使用空格降低代码密度

Basic、Pascal与C这三种早期高级程序设计语言的语法,至今仍在发挥着其重要的作用。Visual Basic仍然保留着Basic的句法简单,多用完整英文单词,贴近自然语序的习惯(如And、Not、Inherits、Implements、Handles等等关键字);而Delphi更是沿续着Pascal 语言那标志性的BEGIN-END作风。C语言由于在操作系统开发上取得了成功,使得它在软件开发历史上占据了绝对的优势,相比而言,它的语法更加具有影响力,广泛被C++、Java、C#,乃至用于编写网页的ECMAScript/JavaScript和Flash的脚本语言ActionScript所吸纳,因此也变化丰富。但是它那种善用符号的古老特色一直被保留了下来,有理由相信,C 语言是使用符号最多的语言。当其他语法体系都采用AND、OR等关键字作为运算符时,C语言却使用了“&&”、“||”这样的符号,虽然在语法上并没有增加任何复杂性,但各种奇形怪状难以记忆的符号还是会令初学者望而却步。让我们来比较一下面的几行代码:BASIC: If a>b And c<>d Or Not e>f Then ...

PASCAL: If (a>b) And (c<>d) Or (Not (e>f)) Then ...

C: if(a>b&&c!=d||!(e>f)) ...

这三行的意义是完全相同的,但明显可以让人感觉到清晰程度的差异,Basic和Pascal的代码看上去很容易明白,而C语言的代码却像蚂蚁一般缩成一团。重要的原因在于:C语言的运算符几乎都只由“符号”构成,与变量名之间不需要用空格充当分隔符。这样一来,由于缺少空格的稀释,C语言的代码就像被浓缩过似的——现如今它除了影响我们阅读以外,

没有什么好处。因此我们有必要人为地添加一点空格,帮它降低代码的“密度”。这里,我总结了一些关于如何在运算符两侧添加空格的基本规则:

1. 单目运算符(Unary Operators)与它的操作数之间应紧密相接,不需要空格。例如:代码示例1-11:单目运算符的空格规则示例

y = ++x; // ++ 在这里是前缀单目运算,它与x之间无空格

2. 在双目、三目运算符(Binary/Ternary Operators)的左右两侧分别添加空格。例如:

代码示例1-12:双目、三目运算符的空格规则示例

int a = 3 + 5; // 在双目运算符左右添加空格

int b = a * 6 + 7;

int c = a & b;

int d = b++ * c--; // 虽然有单目运算符,但双目运算符两侧仍应添加空格

int e = a > 0 ? 1 : 0; // 在三目运算符左右添加空格

3. 括号(包括小括号、中括号与大括号)的内侧应该紧靠操作数或其他运算符,不需要添加额外的空格。例如;

代码示例1-13:括号的空格规则示例

int f = (a + b) * c; // 括号内侧紧靠操作数,因其他运算符添加的空格留在外侧

int g[MAX] = {1, 2, 3}; // 中括号与表达式中的大括号也同样处理

4. 不要使用连续的两个或多个空格。

其实,如果理解了这些规则,在实际书写的时候很容易遵循。对于任何一个表达式,我们先把单目运算符和括号去掉,然后在双目、三目运算符的左右两侧分别添加一个空格,再将单目运算符和括号填回去,放在靠近自己操作数的一边即可。

关于函数调用时,要不要在函数名和其后的括号之间添加空格的问题已经讨论了很久。其实这个是一个无伤大雅的事情,无论使用何种方式,都不会对代码的可读性产生多少实质性的影响,纯粹是各人喜好罢了。不过在这里,我建议采用Visual Studio中的默认规则:在函数调用时不添加空格,而在一些类似的带括号的语法结构中添加空格。请看下面这段代码:代码示例1-14:函数调用时的空格规则示例

string cmd = string.Empty;

// 函数形式的调用,括号前没有空格

cmd = Console.ReadLine();

// 语句结构,括号前有空格

if (cmd.Length > 0)

{

Console.WriteLine(cmd.ToUpper());

}

else

{

Console.WriteLine("(Empty)");

}

这段代码中的ReadLine、WriteLine都是函数调用,因此与其后面的括号紧密相连,不需要添加空格。而if结构虽然同样带有类似的括号结构,但是它属于C# 的内部语法,为了以示区别,在if与括号之间添加了一个空格。除if外,switch、for、while等都应做同样地处理。

1.3 如何缩进

在有关代码风格的问题中,最为显眼的可以说就是代码的缩进(Indent)了。所谓缩进,是通过在每一行的代码左端空出一部分长度,更加清晰地从外观上体现出程序的层次结构。为了更好地描述这一点,先请读者欣赏下列这段代码:

int kmp_match(char[] t, char[] p, int[] flink, int n, int m)

{

int i = 0, j = 0;

while (i < n)

{

while (j != -1 && p[j] != t[i])

{

j = flink[j];

}

if (j == m - 1)

{

return i - m + 1;

}

i++;

j++;

}

return -1;

}

我想,就算让你检查一下它里面有没有大括号配对错误恐怕都很困难,更不用说这段代码有什么功能了——你能一眼看清楚每个while循环的内容是什么吗?让我们换个方式,看看另一段程序:

代码示例1-15:正确缩进的例子

int kmp_match(char[] t, char[] p, int[] flink, int n, int m)

{

int i = 0, j = 0;

while (i < n)

{

while (j != -1 && p[j] != t[i])

{

j = flink[j];

}

if (j == m - 1)

{

return i - m + 1;

}

i++;

j++;

}

return -1;

}

两段程序,除了缩进的区别以外,一字不差。孰是孰非,相信大家都能看得出来,缩进的必要性不难理解。接下来的问题就是:应该如何缩进。

1.3.1 嵌套或包含关系引起的缩进

当遇到有关命名空间、类、结构、函数、以及枚举等等复杂程序结构的定义的时候,我们通常需要将它的内容缩进一层。在C# 语言中,大括号是一个非常明显的标志,凡是遇到大括号,都应该直接联想到缩进。请看下面的示例:

代码示例1-16:包含关系下的缩进

namespace MyNamespace

{

// 命名空间内的内容应缩进

public class MyClass

{

// 类的成员应缩进

public string MyMethod()

{

// 方法函数的函数体应缩进

return "Hello!";

}

private MyEnum myProperty = MyEnum.Alpha;

public MyEnum MyProperty

// 属性的内容应缩进

get

{

// 属性的get部分函数体应缩进

return myProperty;

}

set

{

// 属性的set部分函数体应缩进

myProperty = value;

}

}

}

public enum MyEnum

{

// 枚举类型内容应缩进

Alpha,

Beta,

Gamma

}

}

分支结构(包括if…else结构、switch结构等)和循环结构(包括for结构、while/do…while结构等)都是存在嵌套关系的,因此从条理清晰的角度来说,它同样应该进行缩进书写:

代码示例1-17:嵌套关系下的缩进

// if...else结构

{

// if 子句的结构体内容应缩进 max = a;

min = b;

}

else

{

// else 子句的结构体内容应缩进 max = b;

min = a;

}

// switch结构

switch (n)

{

// switch结构的内容应缩进

case 0:

// case 子句内容也应缩进 // ...

break;

case 1:

// ...

break;

default:

// ...

break;

}

// for结构

for (int i = 0; i < 100; i++)

{

// for 的循环体应缩进

s += data[i];

t *= data[i];

}

// while结构

i = 0;

while (data[i] != 0)

{

// while 的循环体应缩进

s += data[i];

t *= data[i];

i++;

}

缩进时,应将内部结构中的所有语句都统一向右退一格,大括号则与原来的语句保持在同一个垂直位置上。每层缩进的长度应该一致,通常为一个制表符宽或四个空格。

还有一些细节的地方也与换行相关,例如if、switch、for这类具有嵌套结构的语句,在书写的时候都应避免将结构体与语句本身写在同一行上,关于嵌套结构的书写方法,我们会在后面的章节中详细讨论。

1.3.2 因换行而产生的缩进

我们在前面提到过,当一条语句太长而超出一定的宽度时,应该折行书写。此时,从第二行起到该语句结束之间的各行应该缩进一层,至下一条语句时再恢复原来的缩进位置。

代码示例1-18:因换行而产生的缩进

int myVar = 0;

编写高质量代码--Web前端开发修炼之道笔记

第一章从网站重构说起 打造高质量的前端代码,提高代码的可维护性——精简、重用、有序。 第二章团队合作 精一行,通十行。 增加代码可读性——注释。 重用性需提高,分为公共组件与私有组件,代码模块化。公共组件不能轻易修改,因为影响大,所以一般只提供“读”的权限。 磨刀不误砍柴工——前期的构思很重要。构思的主要内容包括规范的制定、公共组件的设计和复杂功能的技术方案等。一般来说,前期构思占整个项目30%~60%的时间都算是正常的。 第三章高质量的HTML

CSS只是web标准的一部分,在HTML、CSS、JS三大元素中,HTML才是最重要的,结构才是重点,样式是用来修饰结构的。正确的做法是,先确定HTML,确定语义的标签,再来选用合适的CSS。 判断标签语义是否良好的简单方法:去掉样式,看网页结构是否组织良好有序,是否仍然有很好的可读性。语义良好的网页去掉样式后结构依然很清晰。 “CSS裸体日”,2006.04.05第一届,从第三届开始改为4月9日。(设立目的就是为了提醒大家用合适的HTML标签的重要性) 一个语义良好的页面,h标签应该是完整有序没有断层的,也就是说要按照h1、h2、h3、h4这样的次序排下来,不要出现类似h1、h3、h4,漏掉h2的情况。 当页面内标签无法满足设计需要时,才会适当添加div和span等五语义标签来辅助实现。 第四章高质量的CSS 组织CSS的方法:base.css+common.css+page.css,在一般情况下任何一个网页的最终表现都是由这三者共同完成的,这三者不是并列结构,而是层叠结构。

base.css一般包括cssreset和通用原子类,比如设置一些常用的清除浮动、宽度、高度等class。可以参考一些前端框架,例如YUI、bootstrap等等。 拆分模块技巧:模块与模块之间尽量不要包含相同的部分,如果有相同部分,应将它们提取出来,拆分成一个独立的模块。模块应在保证数量尽可能少的原则下,做到尽可能简单,以提高重用性。 团队开发人员多,可在classname前加前缀。 如果不确定模块的上下margin特别稳定,最好不要将它们写到模块的类里,而是使用类的组合,单独为上下margin挂用于边距的原子类(例如mt10、mb20)。模块最好不用混用margin-top和margin-bottom,统一使用margin-top或margin-bottom。 低权重原则——避免滥用子选择器 普通标签权重1,class权重10,id权重100 为了保证样式容易被覆盖,提高可维护性,CSS选择符需保证权重尽可能低。 CSS sprite的最大好处是减少HTTP请求数,减轻服务器的压力,但它却需要付出“降低开发效率”和“增大维护难度”的代价。对于流量并不大的网站来说,CSS sprite带来的好处并不明显,而它付出的代价却很大,其实并不划算。所以是否使用CSS sprite主要取决于网站流量。 编码风格:推荐一行书写,能减少文件大小。(因为调试工具多,所以忽略易读性)Hack: A标签问题:

中间代码生成实验报告材料

一、实验目的 通过在实验二的基础上,增加中间代码生成部分,使程序能够对实验二中的识别出的赋值语句,if语句和while语句进行语义分析,生成四元式中间代码。 二、实验方法 实验程序由c语言完成,在Turboc 2.0环境中调试通过。 语义分析程序的基本做法是对文法中的每个产生式分别编写一个语义分析子程序,当程序语法部分进行推倒或规约时,就分别调用各自的语义分析程序。当语法分析结束时,语义分析也就结束了。 在本实验程序中,当语法分析部分识别出语确的句子时,就进入content函数(当语法分析识别出不正确的句子时,不进入content函数,也就是不进行语义分析),然后根据句子的类型进行分类,进入不同的语义处理部分。 对于赋值语句,关键是产生正确的处理算术表达式E的四元式。 程序中的ec函数的功能就是产生算术表达式的四元式,在ec函数中使用了两个栈idshed,opshed,分别是算术表达式的数据栈和符号栈。每次提取一个数字和一个算符,然后将算符与与栈顶算符进行优先级比较,优先级高则将单前数字和算符进栈,低或者相等的话则将当前栈顶元素进行合并,产生四元式。直至整个算术表达式结束。其中还有一些细节问题,具体的做法可以参看程序。 对于实验给定的if语句的文法格式,条件判断式C只中可能是>或者<=两种关系,不可能是布尔表达式,这样程序就简单的多了。 通过ec函数可以产生条件判断式C中的E的四元式,然后只要加上转向四元式就可以了。本实验程序中只给出真出口的转向四元式,没有给出假出口的转向四元式,这在实际中是不可以的,但在

本实验中,实际上是对每条独立的语句进行语法分析,给出假出口转向四元式实际上意义不大,而且假出口转向语句的转移目标必须要到整个语句分析结束以后才可以知道,这样就要建立栈,然后回填,这样会使程序复杂很多,所以没有加上假出口转向四元式。 对于while语句,具体的做法和if语句差不多,所不同的是当while语句结束时,要多出一条无条件转向四元式,重新转到条件判断式C的第一条四元式。当要产生无条件转向四元式时,它的转向目标C的第一条四元式已经产生了,所以具体的做起来是不太困难的。只要记下当前while中的C的第一条四元式的位置,填上就可以了。 整个程序的结束是当读入“. ”时,程序就中止。 程序中还有很多细节问题,具体的可以后面的附录:程序的完整代码。 三、测试程序 ff:=6+6*6-; if sl>89+56*67 then f:=7*7+4; ff:=6+6*6-6%4+8; if sl+78*76>89*56+67 then while a-7>98+45*45 do f:=7*7+4; . 四、运行结果 首先对测试程序进行语法分析,识别出正确的句子,当识别出正确的句子时,就对当前句子进行语义分析,而语法不正确的句子不进行语义分析。 ff:=6+6*6- Error(4):Except ID or NUM ; Error(2):Syntax error if sl>89+56*67 then f:=7*7+4; success!!! (1) [ *, 56, 67, T1 ]

20个代码生成框架

20个代码生成框架 11.1 CodeSmith http: 官方论坛: http: 版权形式:30天试用 开源:否需要先注册确认后才能下载 1.2 MyGenerator MyGenerator是又一个国外很不错的代码生成工具,有人觉得比CodeSmith 简单、好用。 所有api可以在帮助菜单中找到。 http: 官方论坛: 版权形式: 免费 开源:否 1.3 NHibernate. http: 官方论坛: 版权形式:

免费 开源:否 1.4湛蓝.Net代码生成器 http: 官方论坛: http: 版权形式: 免费 开源:否 1.5动软.NET代码自动生成器 一款人气很旺的免费C#代码生成器 http: 官方论坛: 版权形式: 免费 开源:否 1.6 CodePlus 专为sql server c#语言设计的代码生成器,功能还是很强大http: 官方论坛:

版权形式: 需要少量的注册费用 开源:否下载地址很神秘 1.7 CodeMaker http: 官方论坛: 版权形式: 免费 开源:否 https://www.doczj.com/doc/6e13812478.html,代码生成器 可以使用本工具生成https://www.doczj.com/doc/6e13812478.html,和C#语言的代码,以及三层架构与ORM架构代码,并且使用的ORM持久化组件是开源的,您可以在本软件的安装目录下找到它 官方论坛: 版权形式: 免费 开源:否 1.9 BMW业务模型及代码生成器 一款人气很旺的免费C#代码生成器

官方论坛: 版权形式: 免费 开源:否 1.10飞鹰CoolCoder 专门为采用nhibernate做关系对象影射架构的系统提供代码的工具,简单易用,虽然不提供源码,我们可以用反编译工具对其反编译看源码。这是个很不错的学习机会。 官方论坛: 版权形式: 免费 开源:否 1.11 AutoCoder自动代码生成器 AutoCoder自动代码生成器是一个根据模板自动生成代码的代码生成工具,根据模板的不同,可以生成任何语言(如: ASP、C#、C++BUILDER、DELPHI、JAV A、JSP、PHP、V B、https://www.doczj.com/doc/6e13812478.html,……),不同层次结构(B/S、C/S、n-tiger……),基于不同数据库(ORACL E、MSSQL、MYSQL、

程序代码注释编写规范

程序代码注释编写规范 为提高控制程序的阅读性与可理解性,现制定相关代码程序代码注释编写的编写规范。 一般情况下,源程序有效注释量必须在20%以上,注释的原则是有助于对程序的阅读理解,在该加的地方都加了,注释不宜太多也不能太少,注释语言必须准确、易懂、简洁。 常规注释有以下两种方式。 单行:以"//"符号开始,任何位于该符号之后的本行文字都视为注释。 多行:以"/*"符号开始,以"*/"结束。任何介于这对符号之间的文字都视为注释。 一、说明性文件 说明性文件(如头文件.h文件、.inc文件、.def文件、编译说明文件.cfg等)头部应进行注释,注释必须列出:版权说明、版本号、生成日期、作者、内容、功能、与其它文件的关系、修改日志等,头文件的注释中还应有函数功能简要说明。 示例:下面这段头文件的头注释比较标准,当然,并不局限于此格式,但上述信息建议要包含在内。 /************************************************* COPYRIGHT (C), MicTiVo International. Co., Ltd. File NAME: // 文件 Author: Version: Date: // 作者、版本及完成日期 DESCRIPTION: // 用于详细说明此程序文件完成的主要功能,与其他模块 // 或函数的接口,输出值、取值范围、含义及参数间的控 // 制、顺序、独立或依赖等关系 Others: // 其它内容的说明 Function List: // 主要函数列表,每条记录应包括函数名及功能简要说明 1.... History: // 修改历史记录列表,每条修改记录应包括修改日期、修改 // 者及修改内容简述 1. Date: Author: Modification: 2. .. *************************************************/ 二、源文件头 源文件头部应进行注释,列出:版权说明、版本号、生成日期、作者、模块目的/功能、主要函数及其功能、修改日志等。 示例:下面这段源文件的头注释比较标准,当然,并不局限于此格式,但上述信息建议要包含在内。 /************************************************************ COPYRIGHT (C), MicTiVo International. Co., Ltd. FileName: Author:

编译原理综合性实验报告-分析中间代码生成程序分析

编译原理综合性实验报告-分析中间代码生成程序分析XXXXXX计算机系综合性实验 实验报告 课程名称编译原理实验学期 XXXX 至 XXXX 学年第 X 学期学生所在系部计算机系年级 X 专业班级 XXXXXX 学生姓名 XXX 学号 XXXXXXXXXXXX 任课教师XXX 实验成绩 计算机系制 《编译原理》课程综合性实验报告 开课实验室: 年月日实验题目分析中间代码生成程序 一、实验目的 分析PL/0编译程序的总体结构、代码生成的方法和过程;具体写出一条语句的中间代码生成过程。 二、设备与环境 PC兼容机、Windows操作系统、Turbo Pascal软件等。 三、实验内容 1. 分析PL/0程序的Block子程序,理清PL/0程序结构和语句格式。画出Block 子程序的流程图,写出至少两条PL/0程序语句的语法格式。 2. 分析PL/0程序的Block子程序和Gen子程序,了解代码生成的方法和过程。 使用概要算法来描述语句的代码生成过程。 3. 自己编写一个简单的PL/0程序,能够正确通过编译,得到中间代码。列出自

己编写的源程序和编译后得到的中间代码。 4. 从中选择一个语句或表达式,写出代码生成的过程。要求从自己的源程序中 选择一条语句,结合这条语句写出语义分析和代码生成过程。在描述这个过程中,要说清楚每个功能有哪个子程序的哪条语句来完成,说清楚语句和参数的含义和功能。 四、实验结果及分析 (一)Block子程序分析 1.常量声明的分析: 常量声明部分的语法结构定义为如下形式: -> const ; -> [;] ->id = C 其中C可以是常量标识符或字符串或整数(可带符号)或实数(可带符号)。 常量声明分析程序的主要任务是: (1).扫描整个常量声明部分。 (2).为被声明的常量标识符建立符号表项。 (3).检查重复的声明。 2.变量声明部分的分析: 变量声明部分的语法结构定义为如下形式: -> var -> [;] ->:T ->id[,]

代码编写安全规范

代码编写安全规范 一、本总则提供编码的总体要求与遵循原则。 二、本总则制订是为了规范程序的编码风格,使项目开发过程中所有开发人员的编码有一个良好的、规范的、统一的编码风格,确保在开发成员或开发团队之间的工作可以顺利交接,同时不必花费大力气便能理解已编写的代码,以便继续维护和改进以前的工作。 三、本总则对所有技术开发部编码人有效。 四、本总则对所有开发语言有效,凡任何开发规范与本总则相冲突,以本总则为准。 五、本总则提供各种语言的编码规范,编码人员开发(编码)前应选取相应的语言编码规范进行编码。具体的“开发语言编码规范”请参见附件。 六、若总则附件中无所规范的开发语言规范,请先制订出(一般由项目经理制订)该语言的编码规范后再进行编码。 七、编码命名准则: 1、使用可以准确说明变量/字段/类的完整的英文描述符。例如,采用类似firstName,grandTotal 或CorporateCustomer 这样的名字。禁止使用一些象x1,y1 或fn 这样的名字很简短,输入起来容易,辨别含义困难的命名,使得代码难以理解、维护和改进。 2、采用领域的术语命名。如果用户称他们的“客户”(clients) 为“顾客”(customers),那么就采用术语Customer 来命名这个类,而不用Client。保证命名使用行业或领域里已经存在着很完美的术语,避免生造词汇。

3、采用大小写混合,提高名字的可读性。一般应该采用小写字母,但类名、接口名以及任何非初始单词的第一个字母要大写,一些特殊场合以具体规范为准。 4、尽量少用缩写,但如果一定要使用,必须使用一个统一遵守的缩写,并且在使用时保持一致。例如,如果要对单词“number”采用缩写,那么可从nbr,no 或者num 中选取一个,采用其中一个(具体是哪个倒无所谓),并且只使用这一种形式。 5、避免使用长名字(最好不超过20 个字母)。避免类似如PhysicalOrVirtualProductOrService 之类的超长命名。 6、避免使用相似或者仅在大小写上有区别的名字。例如,不应同时使用变量名persistentObject 和persistentObjects,以及anSqlDatabase 和anSQLDatabase。 7、避免使用下划线作为名字的首末字母。以下划线为首末字母的名字通常为系统保留,除预处理定义之外,一般不用作用户命名。 八、编码注释准则: 1、必须明确注释的重要性。如果你的程序不值得注释,那么它也不值得运行。 2、注释应该增加代码的清晰度。代码注释的目的是要使代码更易于被同时参与程序设计的开发人员以及其他后继开发人员理解。如果不能被他人所理解,则代码的注释是失败的注释,等同于无注释。 3、避免使用装饰性内容,不要使用象广告横幅那样的注释语句。

敏捷开发中高质量Java代码开发实践

本文将介绍在敏捷开发过程中如何通过采取一系列的步骤来保证和提高整个项目的代码质量,阐述了每一步可以利用的工具和最佳实践,从而使开发过程更加规范化,成就高质量的代码。 概述 Java项目开发过程中,由于开发人员的经验、代码风格各不相同,以及缺乏统一的标准和管理流程,往往导致整个项目的代码质量较差,难于维护,需要较大的测试投入和周期等问题。这些问题在一个项目组初建、需求和设计均具有不完全可预期性和完备性的全新项目中将尤为突出。本文将结合敏捷开发周期短,变化快等特点,介绍如何通过在开发过程中采取一系列步骤来保证和提高整个开发团队的代码质量,并阐述了每一步可以利用的工具和最佳实践,从而使开发过程更加规范化,成就高质量的代码,减少测试的投入,并促进整个团队的技能提高,最终提高开发效率和质量。 如图1所示,敏捷开发过程经历需求调研,用例分析和用例分解,进入开发迭代阶段。在每个迭代过程中,可以采用以下五个步骤来保证和提高整个项目的代码质量:统一编码规范、代码样式;静态代码分析(static code review);单元测试;持续集成;代码评审和重构(Review&Refactor)。下文将针对每个步骤和其所使用的工具、方法进行详细描述。 图 1.敏捷开发中的Java代码质量保证步骤 步骤一:统一编码规范、代码样式 规范统一的编码会增加项目代码的可读性和可维护性,但实际情况往往是项目组内的Java代码开发

人员的编码风格常常各不相同,这可能是由于不同的经验习惯或者缺乏编码规范方面的学习造成的。这样一来,其他项目成员或者维护人员在阅读项目代码时就需要花费更多的时间来理解代码作者的意图,所以制定并采取统一的编码规范就显得很重要。编码规范主要应包含以下几个方面: ?一般规则和格式规范。例如代码缩进、程序块规范、每行最大代码长度等。 ?命名规则。例如包名、类名、变量、方法、接口、参数等命名规范 ?文档规范。例如类文件头声明、类注释、成员变量和方法注释等规范。 ?编程规范。例如异常、并发、多线程等方面的处理方式。 ?其他规范。例如日志格式、属性文件格式,返回值和消息格式。 项目的编码规范可以参考已有的一些Java编程规范书籍和其他相关资料并结合项目的本身来制定,可供参考的书籍有《Java编程风格》(英文书名为:The Elements of Java Style)。编码规范要形成文档,而且要简洁明了,并组织项目成员一起学习,确保所有成员正确理解所有条目。 一旦编码规范确定,就可以利用Eclipse自身提供的功能来控制代码样式和格式。具体做法是,点击Eclipse的Windows->Preference菜单项,在打开的Preferences对话框的左侧栏中找到Java节点下的子项Code Style(如图2),该项和它的子项允许您对Java代码的样式进行控制。 图 2.Eclipse代码样式设置窗口

语义分析与中间代码生成程序的设计原理与实现技术__实验报告与源代码_北京交通大学

语义分析及中间代码生成程序设计原理与实现技术 XXX 1028XXX2 计科1XXX班 1.程序功能描述 完成以下描述赋值语句和算术表达式文法的语法制导生成中间代码四元式的过 程。 G[A]:A→V:=E E→E+T∣E-T∣ T→T*F∣T/F∣F F→(E)∣i V→i 说明:终结符号i 为用户定义的简单变量,即标识符的定义。 2. 设计要求 (1)给出每一产生式对应的语义动作;(2)设计中间代码四元式的结构(暂不与符号表有关)。(3)输入串应是词法分析的输出二元式序列,即某算术表达式“实验项目一”的输出结果。输出为输入串的四元式序列中间文件。(4)设计两个测试用例(尽可能完备),并给出程序执行结果四元式序列。 3.主要数据结构描述: 本程序采用的是算符优先文法,文法以及算符优先矩阵是根据第四次实验来修改的,所以主要的数据结构也跟第四次差不多,主要为文法的表示,FirstVT集和LastVT 集以及算符优先矩阵:

算符优先矩阵采用二维字符数组表示的: char mtr[9][9]; //算符优先矩阵 4.程序结构描述: 本程序一共有8功能函数: void get(); //获取文法 void print(); //打印文法 void fun(); //求FirstVT 和LastVT void matrix(); //求算符优先矩阵 void test(); //测试文法 int cmp(char a,char b); 比较两个运算符的优先级 1 0 -1 void out(char now,int avg1,int avg2); //打印四元式 int ope(char op,int a,int b); //定义四元式计算方法 5.实验代码 详见附件 6.程序测试 6.1 功能测试 程序运行显示如下功能菜单:

程序代码编写规范

程序编写规范及约定 (仅供内部使用) 文档作者:_______________ 日期:___/___/___ 开发/测试经理:_______________ 日期:___/___/___ 项目经理:_______________ 日期:___/___/___ 请在这里输入公司名称 版权所有不得复制

目录 程序编写规范及约定 (3) 1编写目的 (3) 2代码编写风格 (3) 2.1单元风格 (3) 2.2语句风格 (3) 3命名规则 (3) 3.1命名约定 (3) 3.1.1标志符 (3) 3.1.2类class (3) 3.1.3枚举类型enum (4) 3.1.4委托delegate (4) 3.1.5常量const (4) 3.1.6接口interface (4) 3.1.7方法function (4) 3.1.8命名空间namespace (4) 3.1.9参数 (4) 3.1.10局部变量 (5) 3.1.11数据成员 (5) 3.1.12自定义异常类 (5) 3.1.13命名缩写 (5) 3.1.14数据库命名 (5) 3.2代码编写命名规范 (6) 3.3界面常用控件命名约定 (6) 3.4文件命名规范 (7) 3.4.1文档文件命名 (7) 3.4.2配置文件命名 (7) 3.4.3程序文件命名 (7)

程序编写规范及约定 1编写目的 为了使编写代码具有可读性、可理解性、可维护性,对程序编写人员代码实行统一风格,使得程序代码能够以名称反映含义、以形式反映结构。此文档可供程序代码编写人员及代码维护人员使用。 2代码编写风格 2.1单元风格 2.2语句风格 3命名规则 3.1命名约定 Pascal和Camel命名约定: 编程的命名方式主要有Pascal和Camel两种(Pascal:每个单词的首字母大写,例如ProductType;Camel:首个单词的首字母小写,其余单词的首字母大写,例如productType) 3.1.1标志符 规则:Pascal、Camel 实例与描述:例子说明 3.1.2类class 规则:Pascal 实例与描述:Application

编译方法实验报告(中间代码生成器的设计)

编译方法实验报告 2011年10月

一、实验目的 熟悉算术表达式的语法分析与中间代码生成原理。 二、实验内容 (1)设计语法制导翻译生成表达式的四元式的算法; (2)编写代码并上机调试运行通过。 输入——算术表达式; 输出——语法分析结果; 相应的四元式序列。 (3)设计LL(1)分析法或LR(0)分析法的属性翻译文法,并根据这些属性翻译文法,使用扩展的语法分析器实现语法制导翻译。 三、实验原理及基本步骤 ●算术表达式文法: G(E): E →E ω0 T | T T →T ω1 F | F F → i | (E) ●文法变换: G’(E) E →T {ω0 T} T →F {ω1 F} F → i | (E) ●属性翻译文法: E →T {ω0“push(SYN,w)” T “QUAT”} T →F {ω1“push(SYN, w)” F “QUAT”} F →i “push(SEM, entry(w))” | (E) 其中: push(SYN, w) —当前单词w入算符栈SYN; push(SEM, entry(w)) —当前w在符号表中的入口值压入语义栈SEM; QUA T —生成四元式函数 i.T = newtemp; ii.QT[j] =( SYN[k], SEM[s-1], SEM[s], T); j++; iii.pop( SYN, _ ); pop( SEM, _ ); pop( SEM, _ ); push( SEM, T ); ●递归下降子程序: 数据结构:SYN —算符栈; SEM —语义栈;

四、数据结构设计 使用递归的结构进行四元式的设计,同时,运用堆栈结构将四元式的输出序列打印出来 while ( exp[i]=='+' || exp[i]=='-'){ syn[++i_syn]=exp[i]; //push(SYN,w) i++; //read(w) T(); quat();} while ( exp[i]=='*' || exp[i]=='/'){ syn[++i_syn]=exp[i]; //push(SYN,w) i++; //read(w) F(); quat();} void quat(){ strcpy(qt[j],"(, , , )");

程序代码注释编写规范

百度文库- 让每个人平等地提升自我 1 程序代码注释编写规范 为提高控制程序的阅读性与可理解性,现制定相关代码程序代码注释编写的编写规范。 一般情况下,源程序有效注释量必须在20%以上,注释的原则是有助于对程序的阅读理解,在该加的地方都加了,注释不宜太多也不能太少,注释语言必须准确、易懂、简洁。 常规注释有以下两种方式。 单行:以"文件、.inc文件、.def文件、编译说明文件.cfg等)头部应进行注释,注释必须列出:版权说明、版本号、生成日期、作者、内容、功能、与其它文件的关系、修改日志等,头文件的注释中还应有函数功能简要说明。 示例:下面这段头文件的头注释比较标准,当然,并不局限于此格式,但上述信息建议要包含在内。 /************************************************* (C), MicTiVo International. Co., Ltd. 1.File : . History: Date: Author: Modification: 2. .. *************************************************/ 一、源文件头 源文件头部应进行注释,列出:版权说明、版本号、生成日期、作者、模块目的/功能、主要函数及其功能、修改日志等。 示例:下面这段源文件的头注释比较标准,当然,并不局限于此格式,但上述信息建议要包含在内。 /************************************************************ (C), MicTiVo International. Co., Ltd. FileName: Author: Version : Date: : / /*receive _process() */ 意:与溢出中断写初值不同}

编写高质量Java代码

敏捷开发中编写高质量Java代码 敏捷开发的理念已经流行了很长的时间,在敏捷开发中的开发迭代阶段中,我们可以通过五个步骤,来有效的提高整个项目的代码质量。 Java项目开发过程中,由于开发人员的经验、Java代码编写习惯,以及缺乏统一的标准和管理流程,往往导致整个项目的代码质量较差,难于维护,需要较大的测试投入和周期等问题。这些问题在一个项目组初建、需求和设计均具有不完全可预期性和完备性的全新项目中将尤为突出。 如图1所示,敏捷开发过程经历需求调研,用例分析和用例分解,进入开发迭代阶段。在每个迭代过程中,可以采用以下步骤来保证和提高整个项目的代码质量:统一编码规范、代码样式;静态代码分析(staticcodereview);单元测试;持续集成;代码评审和重构 (Revi ew&Refactor)。下文将针对每个步骤和其所使用的工具、方法进行详细描述。 图1.敏捷开发中的Java代码质量保证步骤 步骤一:统一编码规范、代码样式 规范统一的编码会增加项目代码的可读性和可维护性,但实际情况往往是项目组内的Java代码开发人员的编码风格常常各不相同,这可能是由于不同的经验习惯或者缺乏编码规范方面的学习造成的。这样一来,其他项目成员或者维护人员在阅读项目代码时就需要花费更多的时间来理解代码作者的意图,所以制定并采取统一的编码规范就显得很重要。编码规范主要应包含以下几个方面: ◆一般规则和格式规范。例如代码缩进、程序块规范、每行最大代码长度等。 ◆命名规则。例如包名、类名、变量、方法、接口、参数等命名规范 ◆文档规范。例如类文件头声明、类注释、成员变量和方法注释等规范。 ◆编程规范。例如异常、并发、多线程等方面的处理方式。 ◆其他规范。例如日志格式、属性文件格式,返回值和消息格式。

编译原理实验 中间代码生成

实验四中间代码生成 一.实验目的: 掌握中间代码的四种形式(逆波兰式、语法树、三元式、四元式)。 二.实验内容: 1、逆波兰式定义:将运算对象写在前面,而把运算符号写在后面。用这种表示法表示的表 达式也称做后缀式。 2、抽象(语法)树:运算对象作为叶子结点,运算符作为内部结点。 3、三元式:形式序号:(op,arg1,arg2) 4、四元式:形式(op,arg1,arg2,result) 三、以逆波兰式为例的实验设计思想及算法 (1)首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。 (2)读入一个用中缀表示的简单算术表达式,为方便起见,设该简单算术表达式的右端多加上了优先级最低的特殊符号“#”。 (3)从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符是数字,则分析到该数字串的结束并将该数字串直接输出。 (4)如果不是数字,该字符则是运算符,此时需比较优先关系。 做法如下:将该字符与运算符栈顶的运算符的优先关系相比较。如果,该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。倘若不是的话,则将此运算符栈顶的运算符从栈中弹出,将该字符入栈。 (5)重复上述操作(1)-(2)直至扫描完整个简单算术表达式,确定所有字符都得到正确处理,我们便可以将中缀式表示的简单算术表达式转化为逆波兰表示的简单算术表达式。 四、程序代码: //这是一个由中缀式生成后缀式的程序 #include<> #include<> #include<> #include<> #define maxbuffer 64 void main() { char display_out(char out_ch[maxbuffer], char ch[32]); //int caculate_array(char out_ch[32]); static int i=0; static int j=0; char ch[maxbuffer],s[maxbuffer],out[maxbuffer]; cout<<"请输入中缀表达式: ";

我编写过的最漂亮的代码

第3章我编写过的最漂亮的代码 Jon Bentley 我曾经听一位大师级的程序员这样称赞到,“我通过删除代码来实现功能的提升。”而法国著名作家兼飞行家Antoine de Saint-Exupéry的说法则更具代表性,“只有在不仅没有任何功能可以添加,而且也没有任何功能可以删除的情况下,设计师才能够认为自己的工作已臻完美。”某些时候,在软件中根本就不存在最漂亮的代码,最漂亮的函数,或者最漂亮的程序。 当然,我们很难对不存在的事物进行讨论。本章将对经典Quicksort(快速排序)算法的运行时间进行全面的分析,并试图通过这个分析来说明上述观点。在第一节中,我将首先根据我自己的观点来回顾一下Quicksort,并为后面的内容打下基础。第二节的内容将是本章的重点部分。我们将首先在程序中增加一个计数器,然后通过不断地修改,从而使程序的代码变得越来越短,但程序的功能却会变得越来越强,最终的结果是只需要几行代码就可以使算法的运行时间达到平均水平。在第三节将对前面的技术进行小结,并对二分搜索树的运行开销进行简单的分析。最后的两节将给出学完本章得到的一些启示,这将有助于你在今后写出更为优雅的程序。 3.1 我编写过的最漂亮代码 当Greg Wilson最初告诉我本书的编写计划时,我曾自问编写过的最漂亮的代码是什么。这个有趣的问题在我脑海里盘旋了大半天,然后我发现答案其实很简单:Quicksort算法。但遗憾的是,根据不同的表达方式,这个问题有着三种不同的答案。 当我撰写关于分治(divide-and-conquer)算法的论文时,我发现 C.A.R. Hoare的Quicksort算法(“Quicksort”,Computer Journal 5)无疑是各种Quicksort算法的鼻祖。这是一种解决基本问题的漂亮算法,可以用优雅的代码实现。我很喜欢这个算法,但我总是无法弄明白算法中最内层的循环。我曾经花两天的时间来调试一个使用了这个循环的复杂程序,并且几年以来,当我需要完成类似的任务时,我会很小心地复制这段代码。虽然这段代码能够解决我所遇到的问题,但我却并没有真正地理解它。 我后来从Nico Lomuto那里学到了一种优雅的划分(partitioning)模式,并且最终编写出了我能够理解,甚至能够证明的Quicksort算法。William Strunk Jr.针对英语所提出的“良好的写作风格即为简练”这条经验同样适用于代码的编写,因此我遵循了他的建议,“省略不必要的字词”(来自《The Elements of Style》一书)。我最终将大约40行左右的代码缩减为十几行的代码。因此,如果要回答“你曾编写过的最漂亮代码是什么?”这个问题,那么我的答案就是:在我编写的《Programming Pearls, Second Edition》(Addison-Wesley)一书中给出的Quichsort算法。在示例3-1中给出了用C语言编写的Quicksort函数。我们在接下来的章节中将进一步地研究和改善这个函数。 【示例】 3-1 Quicksort函数 void quicksort(int l, int u) { int i, m; if (l >= u) return;

代码生成器

代码生成器使用规则 1.创建一个表,红色为必须字段,该sql执行前去掉行前的tab符号 DROP TABLE IF EXISTS `books`; CREATE TABLE `books` ( `id` varchar(64) NOT NULL COMMENT '编号', `bookid` varchar(30) default NULL COMMENT '书号', `name` varchar(100) default NULL COMMENT '书名', `author` varchar(100) default NULL COMMENT '作者', `price` float default NULL COMMENT '单价', `number` int(11) default NULL COMMENT '存库', `publish` varchar(30) default NULL COMMENT '出版社', `img` varchar(30) default 'upload/default.jpg' COMMENT '封面', `create_by` varchar(64) default NULL COMMENT '创建者', `create_date` datetime default NULL COMMENT '创建时间', `update_by` varchar(64) default NULL COMMENT '更新者', `update_date` datetime default NULL COMMENT '更新时间', `remarks` varchar(255) default NULL COMMENT '备注信息', `del_flag` char(1) NOT NULL COMMENT '删除标志', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 2.修改Generate类,修改如下 String moduleName = "books"; // 模块名,例:sys String subModuleName = ""; // 子模块名(可选) String className = "books"; // 类名,例:user String classAuthor = "石义良"; // 类作者,例:ThinkGem String functionName = "图书"; // 功能名,例:用户 // 是否启用生成工具 Boolean isEnable = true; 右击,run as java application 3.刷新整个项目,将com.thinkgem.jeesite.modules.books.web.BooksController中的 return"books/booksList"; return"books/booksForm"; 修改为 return"modules/books/booksList"; return"modules/books/booksForm"; 4.将/JeeSite/src/main/java/com/thinkgem/jeesite/modules/books/entity/Books.java中的父类修改IdEntity,并删除id成员,添加其他非红色字段成员及get、set方法。并将表映射为books表。 5.以thinkgem身份登录,在菜单管理中添加菜单:

FORTRAN 90 程序编程规范

FORTRAN 90 程序编程规范 Fortran 90 编程规范,使程序代码高度组织化,更加易读、易懂、易于维护,程序更加高效。使编出的程序更易懂、易于维护。 1 语言选择 数值预报创新系统软件开发应避免使用Fortran77 的某些过时特征以Fortran 90不一致的特征。选择Fortran 90 作为开发语言,并采用Fortran 90 的新功能,如动态内存的分配(dynamic memory allocation)、递归(recursion ), 模块(modules)、POINTER 、长变量名、自由格式等。 Fortran 77其中某些只是一些冗余的功能,这些功能已经过时,另外,还有一些在Fortran90 中被证明是不好的用法,建议不要使用。 2 Fortran 90 的新特性 2.1.1 建议使用的Fortran 90 新特性 建议使用Fortran 90 提供的模块(module ),并用Use ONLY 指定module 中哪些变量或派生类型定义可用于调用程序。 尽量使用数组下标三元组,这样可优化并减少所需的代码行数。为提高可读性,要在括号内表明数组的维数,例如: 1dArrayA(:) = 1dArrayB(:) + 1dArrayC(:) 2dArray(: , :) = scalar * Another2dArray(: , :) 当访问数组的子集时,例如在有限差分等式中,可以通过使用下标三元组实现。例如:2dArray(: , 2:len2) = scalar *( & Another2dArray(:, 1:len2 -1) & - Another2dArray(:, 2:len2) & ) 对程序单元(program units )命名,并使用End program ,End subroutine ,End interface ,End module 等结构再次指定“program unit ”的名称。 在逻辑表达式中使用>、 >=、 ==、 <、 <=、 /=,它们分别代 替.gt.、.ge.、.eq.、.lt.、.le.、.ne. 。新的表示方法更接近标准的数学符号 在变量定义中始终使用“::”;始终用“DIMENSION ”定义数组形状;始终用(len=)的语法格式声明字符变量的长度。

敏捷开发中编写高质量Java代码+

敏捷开发中编写高质量Java代码收藏 敏捷开发的理念已经流行了很长的时间,在敏捷开发中的开发迭代阶段中,我们可以通过五个步骤,来有效的提高整个项目的代码质量。 Java项目开发过程中,由于开发人员的经验、Java代码编写习惯,以及缺乏统一的标准和管理流程,往往导致整个项目的代码质量较差,难于维护,需要较大的测试投入和周期等问题。这些问题在一个项目组初建、需求和设计均具有不完全可预期性和完备性的全新项目中将尤为突出。 如图1所示,敏捷开发过程经历需求调研,用例分析和用例分解,进入开发迭代阶段。在每个迭代过程中,可以采用以下步骤来保证和提高整个项目的代码质量:统一编码规范、代码样式;静态代码分析(staticcodereview);单元测试;持续集成;代码评审和重构(Review&Refact or)。下文将针对每个步骤和其所使用的工具、方法进行详细描述。 图1.敏捷开发中的Java代码质量保证步骤

步骤一:统一编码规范、代码样式 规范统一的编码会增加项目代码的可读性和可维护性,但实际情况往往是项目组内的Java代码开发人员的编码风格常常各不相同,这可能是由于不同的经验习惯或者缺乏编码规范方面的学习造成的。这样一来,其他项目成员或者维护人员在阅读项目代码时就需要花费更多的时间来理解代码作者的意图,所以制定并采取统一的编码规范就显得很重要。编码规范主要应包含以下几个方面: ◆一般规则和格式规范。例如代码缩进、程序块规范、每行最大代码长度等。 ◆命名规则。例如包名、类名、变量、方法、接口、参数等命名规范 ◆文档规范。例如类文件头声明、类注释、成员变量和方法注释等规范。 ◆编程规范。例如异常、并发、多线程等方面的处理方式。 ◆其他规范。例如日志格式、属性文件格式,返回值和消息格式。 项目的编码规范可以参考已有的一些Java编程规范书籍和其他相关资料并结合项目的本身来制定,可供参考的书籍有《Java编程风格》(英文书名为:TheElementsofJavaStyle)。编码规范要形成文档,而且要简洁明了,并组织项目成员一起学习,确保所有成员正确理解所有条目。 一旦编码规范确定,就可以利用Eclipse自身提供的功能来控制代码样式和格式。具体做法是,点击Eclipse的Windows->Preference菜单项,在打开的Preferences对话框的左侧栏中找到Java节点下的子项CodeStyle(如图2),该项和它的子项允许您对Java代码的样式进行控制。

相关主题
文本预览
相关文档 最新文档