命名规范
命名不规范可能会引起异议。
变量
变量的名字需要体现其意义和用途。
变量名应该用小写字母开头的混合大小写。
例如:
linearity, credibleThreat, qualityOfLife
另一种方法是使用下划线分隔复合变量名的各个部分。
具有较大作用域的变量应该具有有意义的名称。作用域较小的变量可以有较短的名称。
用于临时储存的变量可以简短一点。
一般来说,整型常见的初始变量是i,j,k,m,n;双精度的是x,y和z.
(matlab中i,j是固定虚数单位,需要注意。)
前缀n应该用于表示对象数量的变量。
例如:
nFiles, nSegments
避免使用同一个变量名字的不同仅有一个s后缀的区别
例如:
point,points
但数组是可以的如
point,pointArray
表示单个实体号的变量可以用No作为后缀,也可以用i作为前缀i。
tableNo, employeeNo
iTable, iEmployee
迭代变量的命名或前缀为i、j、k等
Ex:
for iFile = 1:nFiles
:
end
同时对于嵌套循环,迭代变量按字母顺序进行,同时是有意义的
for iFile = 1:nFiles
for jPosition = 1:nPositions
:
end
:
end
应该避免使用否定的布尔变量名。
避免使用 isNotFound
缩写单词也需要大写首字母,即使其通常是大写的。
通常使用: isUsaSpecific
不使用:isUSASpecific
避免使用关键词或特别意义的词,如内置函数
常量
命名的常量(包括全局变量)应该全部使用大写,单词之间使用下划线分隔。
例如:
COLOR_RED, MAX_ITERATIONS
可以使用类型名字作为前缀
例如:
COLOR_RED, COLOR_GREEN, COLOR_BLUE
结构体
结构名称应以大写字母开头
结构的名称是隐式的,不需要包含在字段名中。
例如:
Segment.length
函数
函数名应该用小写书写
最清晰的做法是让函数和它的m文件名相同。
使用小写可以避免潜在的文件名问题。
例如:
getname(.), computetotalwidth(.)
同时可以使用下划线隔开,增强可读性。
函数应该有有意义的名称。
缩写或首字母缩略词在数学中广泛使用是一个例外。
max(.)
可以根据输出命名具有单个输出的函数。
mean(.), standarderror(.)
没有输出参数或只返回句柄的函数应该根据它们的功能命名。
plot(.)
前缀get/set通常应该为访问对象或属性而保留。
getobj(.); setappdata(.)
前缀compute可以用于计算某些内容的方法中。
computweightedaverage(.); computespread(.)
前缀find可用于查找某项内容的方法。
findoldestrecord(.); findheaviestelement(.);
在建立对象或概念的地方可以使用前缀初始化。
initializeproblemstate(.);
前缀is应该用于布尔函数
isoverpriced(.); iscomplete(.)
有一些替代is前缀的方法在某些情况下更适合。这些前缀包括has、can和should:
hasLicense(.);canEvaluate(.);shouldSort(.)
互补名称应用于对应操作
get/set, add/remove, create/destroy, start/stop, insert/delete,
increment/decrement, old/new, begin/end, first/last, up/down,
min/max, next/previous, old/new, open/close, show/hide,
suspend/resume, etc.
避免无意义的重复。
函数命应该是唯一的。
一般规则
量纲化变量和常量的名称通常应该有单位后缀。
添加单位后缀有助于避免几乎不可避免的混合。
incidentAngleRadians
名称中的缩写应避免使用
减少模糊和歧义
computearrivaltime(.)(建议) comparr(.)(避免)
(注:除了特定短语)
文件和组织结构
M文件
模块化
将大的整个程序化为一个个模块,以便调用或复用。
明确交互接口
结构可用于避免输入或输出参数的长列表。
分区
划分所有子函数和许多函数应该可以很好地完成一件事。每个函数都应该隐藏一些东西。
尽可能使用现有函数
反复出现的代码应当模块化到一个函数内
子函数
只有一个其他函数使用的函数应该作为它的子函数打包在同一个文件中。这使得代码更容易理解和维护。
测试脚本
为每个函数编写一个测试脚本。这种做法将提高初始版本的质量和更改版本的可靠性。考虑到任何难于测试的函数可能难于编写。
Boris Beizer: “More than the act of testing, the act of designing tests is one
of the best bug preventers known.”
输入和输出
输入输出模块
格式化输出方便使用。
表述
变量和常量
除非内存限制,否则不应重用变量。
相同类型的相关变量可以在公共语句中声明。不相关的变量不应该在同一语句中声明。
它增强了对变量分组的可读性。
persistent x, y, z
global REVENUE_JANUARY, REVENUE_FEBRUARY
考虑在文件开头附近的注释中记录重要的变量。
% pointArray Points are in rows with coordinates in columns.
考虑用行尾注释来记录常量赋值。
THRESHOLD = 10; % Maximum noise level found by experiment.
全局变量
应该尽量减少全局变量的使用。
应该尽量减少全局常量的使用。
循环语句
循环变量应该在循环之前立即初始化。
result = zeros(nEntries,1);
for index = 1:nEntries
result(index) = foo(index);
end
应该尽量减少在循环中使用break和continue。
嵌套循环的结束行可以有注释
条件语句
应该避免使用复杂的条件表达式。取而代之,引入临时逻辑变量。
通过将逻辑变量赋给表达式,程序可以自动编写文档。构造将更易于阅读和调试。
if (value>=lowerLimit)&(value<=upperLimit)&~ismember(value,…
valueArray)
:
end
替换为
isValid = (value >= lowerLimit) & (value <= upperLimit);
isNew = ~ismember(value, valueArray);
if (isValid & isNew)
:
end
一般的情况应该放在if-part中,异常放在if else语句的else-part中。
fid = fopen(fileName);
if (fid~=-1)
:
else
:
end
除了临时块注释外,应该避免条件表达式if 0。
switch语句应该包含otherwise条件。
switch (condition)
case ABC
statements;
case DEF
statements;
otherwise
statements;
end
switch变量通常应该是一个字符串。
一般情况
避免使用加密代码
使用括号
表达式中数字的使用应该尽量减少。可更改的数字通常应命名为常量。
浮点常量应该总是在小数点前加上一位数字。
THRESHOLD = 0.5;
不要使用 THRESHOLD = .5;
应该谨慎地进行浮点数比较。
shortSide = 3;
longSide = 5;
otherSide = 4;
longSide^2 == (shortSide^2 + otherSide^2)
ans =
1
scaleFactor = 0.01;
(scaleFactor*longSide)^2 == ((scaleFactor*shortSide)^2 + …
(scaleFactor*otherSide)^2)
ans =
0
排版、注释和文件
排版
内容应保持在前80列内。
线条应该在优美的点上分开。
需要进行适当的换行
totalSum = a + b + c + …
d + e;
function (param1, param2,…
param3)
setText ([‘Long line split’ …
‘into two parts.’]);
基本的缩进应该是3或4个空格。
缩进应与MATLAB编辑器一致。
一般来说,一行代码应该只包含一个可执行语句。
短的单个语句if、for或while语句可以写在一行上。
if(condition), statement; end
while(condition), statement; end
for iTest = 1:nTest, statement; end
留白
用空格环绕=、&和|。
simpleSum = firstTerm+secondTerm;
常规操作符可以被空格包围。
simpleAverage = (firstTerm + secondTerm) / two;
1 : nIterations
逗号后面可以跟一个空格。
foo(alpha, beta, gamma)
foo(alpha,beta,gamma)
一行中多个命令的分号或逗号后面应该跟一个空格字符。
if (pi>1), disp(‘Yes’), end
关键字后面应该跟一个空格。
块内的逻辑语句组之间应该用一个空行分隔。
块之间应由多个空行分隔。
在能够提高可读性的地方使用对齐方式。
weightedPopulation = (doctorWeight * nDoctors) + …
(lawyerWeight * nLawyers) + …
(chiefWeight * nChiefs);
注释
注释的目的是向代码中添加信息。注释的典型用途是解释用法,提供参考信息,证明决策的合理性,描述限制,提到需要的改进。经验表明,最好是在编写代码的同时编写注释,而不是打算在以后添加注释。
注释不能证明写得很差的代码是正确的。
注释应该与代码一致,但不仅仅是重申代码。
注释应该易于阅读。
注释通常应该与引用的语句具有相同的缩进。
函数头注释应该支持help和lookfor的使用。
函数头注释应该讨论输入参数的任何特殊要求。
% ejectionFraction must be between 0 and 1, not a percentage.
% elapsedTimeSeconds must be one dimensional.
函数头注释应该描述任何副作用。
一般来说,函数头的最后一个注释应该重述函数行。
在函数头中使用大写写函数名是有争议的。
避免函数头帮助打印输出中出现不必要的信息。
将版权行和修改历史记录行与其他的注释分隔开,避免在帮助文件中显示出来。
文件
正式文档
有用的文档应该包括代码应该做什么(需求)、如何工作(设计)、依赖于哪些功能以及如何被其他代码(接口)使用,以及如何测试的可读性描述。为了额外加分,文档可以包括对替代解决方案的讨论,以及扩展或维护的建议。
考虑先写文档
变化
管理和记录代码变更的专业方法是使用源代码控制工具。对于非常简单的项目,在函数文件中添加更改历史注释肯定比什么都没有要好。
% date Month Year, Name, 。。。
[1] Johnson R. MATLAB Programming Style Guidelines[J]. 2002(October).