前言之看一眼没坏处
初学者建议按一定的规范编写代码,因为~进公司后,老大会因为找不到理由夸你而发愁!!!大部分建议的后面会紧跟着一个简单的例子,便于理解。拿走不谢!!!
友情提示:转载请标明出处,谢谢合作!!!不然画个圈圈诅咒你(狗头)……
1.变量命名:
-
建议使用“有意义且描述性”的名称,能够清晰地表达其用途和含义;
wheelbase = 10; % 轴距大小为10. -
建议使用“小写字母”命名,有助于与函数名和类名进行区分;
lambda = 1; % 电磁波波长 -
若存在几个相同功能的变量,可使用多单词命名,单词中间使用“_”隔开;
首字母或者单词代表“阈值参数”,下划线后表示“不同的类型”。epsilon_c = 1e-4; % 通信阈值参数 ε_c = 0.0001; epsilon_r = 1e-3; % 雷达阈值参数 ε_r = 0.001 -
不要将 MATLAB 的保留字用作变量名,如:else 、end等不能作为标识符或变量名使用;
function、return、 global、 persistent、 true、 false、 switch、 case、 otherwise、 try、 catch、 finally、 if 、elseif、 else、 end、 for、 while、 true、 false、 nargin、 nargout、 varargout、 varargin…… -
建议变量名总字符长度小于30(个别公司要求),若命名涉及单词的数目太多,可使用简称代替对应的单词;
sim_commun_max = 20; % 通信仿真最大次数(maximum number of communication simulations) simulations --- sim; communication --- commun; maximum --- max - 在特定领域或项目中,可能存在特定的命名约定或惯例。应与团队成员保持一致并遵循相关约定;
- 论文中出现的变量名:Fopt、H、K、Fc……
- 专业术语的简称:SNR、SDR、QCQP……
2.结构体命名
-
结构体的命名应该以一个大写字母开头,有助于区分结构体与普通变量。
其中:Radar为结构体名,lambda为Radar结构体的变量,其值为1。Radar.lambda = 1; % 雷达的电磁波波长为1 Radar.SNR = -10 : 2 : 30; % 雷达的信噪比为-10~30,采样间隔为2 -
选择具有描述性的名称来命名结构体,能够清晰地表达其用途和内容;
Radar.xxxx % 雷达相关的的结构体 Com.xxxx % 通信相关的的结构体 -
避免使用 MATLAB 的保留字;
function、return、 global、 persistent、 true、 false、 switch、 case、 otherwise、 try、 catch、 finally、 if 、elseif、 else、 end、 for、 while、 true、 false、 nargin、 nargout、 varargout、 varargin…… -
在特定领域或项目中,可能存在特定的命名约定或惯例。应与团队成员保持一致并遵循相关约定。
3.返回值变量命名
-
选择描述性的名称来命名返回值变量,能够清晰地表达其含义和用途。确保名称与返回值的内容相匹配。
a function [Urad, FD ] = ISAC_SDR_AltMin(Frad, Fopt,……) b function [out1, out2] = ISAC_SDR_AltMin(Frad, Fopt,……)其中a函数返回值的命名可提高可读性,无需详细浏览ISAC_SDR_AltMin函数可直接确认返回值的含义(反例为b项)。
-
函数输出的常量的命名建议全部为小写或大小写混合。
a function [angle, coord] = KinematicModel(a, phi, ...) b function [Fopt, Wopt, H, ar, at] = SV_mmWave_channel(Nt1, Nt2, ...)其中angle, coord和Fopt, Wopt, H, ar, at为函数的返回值。
-
如果函数返回多个相关的值,可以考虑将这些值作为结构体的字段或对象的属性进行返回。这样可以提供更好的封装和易读性。
function [Radar] = Test_Fun(Frad, Fopt,……) %该函数功能为获取雷达天线的所有矢量或矩阵其中返回值Radar为结构体,成员变量包括:波束形成矩阵、波束发射转移矢量,功率增益等。Test_Fun函数表示为:
Radar.at = exp(2 * 1i * pi * d / lambda * (Nt_Index - 1) * sin(θ)); % 雷达发射阵列响应向量 Radar.Frad = exp(2 * 1i * pi / lambda * d * (Nt - 1) * sind(θ)); % 雷达波束形成矩阵 -
如果返回的是数组或矩阵,可以在函数开始时预先分配足够的内存空间,以避免频繁的内存重新分配。
myMatrix = zeros(100, 100); % 预先分配一个 100x100 的零矩阵 -
尽量避免使用全局变量来存储函数的返回值。应该优先通过函数的返回值来传递结果。
错误示例:global myGlobalVariable % 声明全局变量myGlobalVariable
4.缩进
-
优先建议使用四个空格进行缩进(懒人专场:使用TAB键缩进),有助于代码的可读性(赏心悦目,特别是在多层嵌套环境下调试时,方便浏览整体框架,不然看着就痛苦面具)。
-
每个嵌套的代码块应该相对于上一级代码块进行适当的缩进,以突出显示其层次结构。
-
避免在代码块中过度缩进,这会导致代码水平过宽,可能降低代码的可读性。
-
在整个代码中应保持一致的缩进风格,有助于统一代码的外观,并使其更易于阅读和理解。
举例说明: function result = calculateSum(a, b) % 计算两个数的和 if ((a > 0) && (b > 0)) % 如果 a 和 b 都大于 0,则返回它们的和 result = a + b; else % 否则,显示错误信息并返回 NaN(非数字) disp('Error: Both inputs must be positive numbers.’); result = NaN; end end
5.合理使用空格
-
操作符周围的空格:在二元操作符( +、-、*、/ 等)两侧留出空格,以增加代码的可读性。
x = Xmax - rand * (Xmax - Xmin); -
逗号和分号后面的空格:在逗号和分号之后留出一个空格,以增加代码的可读性。
function [a] = Array_Response(Elevation, Azimuth, ……, Module) -
数组、矩阵和单元数组的元素之间的空格:在元素之间留出适当的空格,以增加元素的可读性。
SNRdB = -30:5:10; % 信噪比(dB) Radar_DOA = [0; 30; 50; 70]; % 测试使用 -
赋值操作符周围的空格:在赋值操作符 = 的两侧留出空格,以增加代码的可读性。
for sim_ii = 1 : SIM_NUM …… end
6.控制行长度
-
尽量将每行代码的长度限制在80个字符以内。这有助于在大多数文本编辑器和终端窗口中更好地显示代码。
-
如果一行代码太长,可以选择合适的位置使用“…”进行换行。建议在运算符后或逗号之后进行换行。
[FF_OPT_Fopt, FF_OPT_Wopt, FF_OPT_H, FF_OPT_ar, FF_OPT_at] = SV_mmWave_channel... (UPA_Nt1, UPA_Nt2, RSU_Nr1, RSU_Nr2, Ns, L, angle_sigma, sigma, lambda, P, FF_Module); -
对于需要换行的运算符,将运算符放在新行的开头,而非结束行的结尾。这样可以清楚地表示运算符的运算顺序。
FF_SPECEFFY_OSE(SNR_LL, SIM_NUM, rho_kk) = FF_SPECEFFY_OSE(SNR_LL, SIM_NUM, rho_kk)... + log2(det(eye(Ns) + SNR(SNR_LL) * …… * FF_OPT_H' * FF_OPT_Wopt')); -
对于函数调用时的参数列表,可以将每个参数放在新行上,并使用适当的缩进来增加代码的可读性。
fprintf('| %7.3f | %7.3f | %7.3f | %7.3f | %7.3f | %7.3f |\n', ... pow2db(gamma_bar), K, ... % 参数1 …… % …… pow2db(mean(CRLB_precise(idx_scan))) ); % 参数6 -
如果括号内的内容超出了行的长度限制,可以将内容放在新行上,并使用适当的缩进,以突出显示其层次结构。
plot(Rad_theta * 180 / pi, 10 * log10(diag(FF_AOI_at’ * …… * FF_AOI_at )... / real(trace(……))), 'LineWidth', 1.5); hold on;
7.条件语句
-
在条件语句中使用 if-elseif-else-end 结构来处理多个条件。确保每个关键字后面有正确的语法结构。
if condition1 ……elseif condition2 ……else ……end -
按照逻辑顺序排列条件,将最常见或最简单的条件放在前面。这样可以提高代码的效率,并减少不必要的条件判断;
-
尽管 MATLAB 中的条件语句中的括号是可选的,但对于复杂的条件表达式,建议使用括号来明确优先级和增强可读性;
if (condition1 && condition2) || (condition3 && condition4) ……end -
switch语句应该包含otherwise条件;
switch x case 1 disp('x is 1’); case 2 disp('x is 2’); otherwise disp('Unexpected value for x’); end -
避免使用if 0条件表达式;
-
可读性差:使用 if 0 条件可能会使代码变得难以理解,因为它没有明确的目的或作用。其他人阅读代码时可能会对其意图产生疑惑;
-
容易被忽略:其中的代码块将始终被跳过,这可能导致开发人员在后续修改或调试代码时忽视它们;
-
潜在的错误:将真实的代码放在 if 0 条件表达式中,并且以后忘记更改为真实的条件,那么这段代码将永远不会执行,即使有需要执行它的情况。
-
8.循环语句
-
确保循环条件能够清晰地表达其意图,并且易于理解。这有助于其他人阅读代码和理解循环的目的;
for i = 1 : length(array) if array(i) > 0 sum = sum + array(i); end end -
在循环语句中,确保控制流的正确处理。在需要时使用 break、continue 或其他控制语句来跳出循环或继续下一次迭代(应该尽量少使用 break与 continue);
-
确保循环条件能够最终达到结束条件。不要出现while(true);
-
避免多层嵌套(嵌套次数尽可能控制在4层以内),以减少代码的复杂性和提高代码的可读性。
举例说明:嵌套次数为3 for i = 1:3 for j = 1:2 for k = 1:4 disp(['Nested loop iteration: ' num2str(i * j * k)]); end end end
9.合理对齐
-
对于结构体的字段,可以将字段名称对齐,以增加结构体字段的可读性;
myStruct = struct('field1', value1, ... 'field2', value2, ... ‘field3', value3);
-
如果有多个赋值语句,可以将等号对齐,以增加代码的可读性;
variable1 = someLongExpression1; variable2 = someLongExpression2; abb = someLongExpression3;
-
在函数调用时,将多个参数垂直对齐,并在参数列表之间保留适当的空格,以增加代码的可读性。特别是一行代码装不下的情况下,非常建议对齐,毕竟看着就爽;
result = myFunction(arg1, arg2, ... arg3, arg4);
-
在团队编写代码时,建议在整个代码中保持一致的对齐风格和约定,以提高代码的可读性和一致性(此项为公司要求)。
10.添加注释
-
使用注释来解释代码的目的、功能和实现方法。注释应该概括性地描述代码的意图和逻辑;
% 模拟车辆运动学模型 for i = 1:num_steps …… end -
注释应该注重于关键性的信息,如算法的步骤、变量的含义或特殊处理的原因等;
Urad = (randn(K, Ns) + 1i * randn(K, Ns)) / sqrt(2); % 随机初始化Urad矩阵/单位化 -
避免对每个细节都进行注释,注重于解释那些非显而易见或容易混淆的部分;
-
可以使用两种主要的注释风格:行注释(%)和块注释(%{...%})。选择适用的注释风格来增强代码的可读性;
-
%{……%}:块注释,可跨多行,添加对代码的详细说明、功能描述等;
-
% :行注释。
-
-
对于长的或复杂的代码块,可以使用注释行来标记段落,并提供简短的描述;
% SVD分解求解Urad [U, S, V] = svd(Frad' * FD); …… Unit_Matrix = eye(size(U, 2)); -
建议注释行数不少于代码总行数的1/3 (个别公司强制要求) 。
11.函数抬头备注
-
写明函数的名称,并简要描述函数的目的和功能。这帮助其他人快速了解函数的用途;
-
列出函数的输入参数以及每个参数的类型、含义和限制等信息。描述各个参数的名称、用途和意义;
-
指明函数的输出结果以及每个输出的数据类型和含义。描述函数的返回值、输出参数或修改传入参数的方式;
-
提供函数的正确语法和用法示例,以便其他人知道如何正确调用和使用该函数;
-
如果有特殊的注意事项、使用限制或需要其他环境条件,请在抬头备注中进行说明;
-
如果有相关的参考文献、链接或其他资源,可以在抬头备注中提供这些信息,以便其他人进一步了解相关内容。

12.代码模块化
-
将代码分解为模块或函数,每个函数执行一个特定的任务。这有助于提高可读性和可维护性,并便于重复使用;
% 交替SDR优化函数 function [Urad, FD] = ISAC_SDR_AltMin(Frad, Fopt, epsilon_r, epsilon_c, rho, PT, cycle_max) …… end -
编写单元测试函数来验证每个函数的正确性;
-
为 函数编写文档,包括使用说明、输入输出示例、依赖项等信息。这样可以帮助其他人理解代码,并为自己提供未来参考 (此项为公司要求) 。
13.输入验证和错误处理
-
在函数内部进行输入参数的验证,以确保其合法性和适用性。可以检查变量的类型、大小、范围等;
if rho < 0 || rho > 1 rho = 0.5; end -
如果输入无效,可以抛出异常并提供相应的错误消息;
if ~isnumeric(input) || numel(input) ~= 1 error('Input must be a numeric scalar.’); end -
使用 error 函数返回错误消息,说明导致错误的原因和解决方法。这有助于用户识别和纠正错误;
-
使用 warning 函数返回警告消息,指示潜在的问题或需要注意的事项;
if input < 0 error('Input must be non-negative.’); elseif input == 0 warning('Input is zero, which may cause unexpected behavior.’); end -
使用 try-catch 块捕获可能引发异常的代码段,并在 catch 块中处理异常情况。可以通过显示错误消息、记录日志或执行其他适当的操作来处理异常(此项可暂不学习) ;
-
对于可能引发多种异常的代码,可以使用多个 catch 块来分别处理不同类型的异常(此项可暂不学习)。
try % 可能引发异常的代码 catch exception % 处理异常情况 end
14.合理使用空行
-
函数之间:在不同的函数之间添加空行,以便在代码中创建适当的分隔。这有助于区分不同功能的代码段,使代码更易于阅读;
function output = function1(input) …… end %空行 function output = function2(input) …… end -
代码段之间:在相似但独立的代码段之间添加空行,以将它们区分开来,可提高代码的模块化程度;
%算法1:SDR %空行 %算法2:Manopt -
逻辑块之间:在逻辑上相关的代码块之间添加空行,以增强代码的可读性。这有助于将逻辑结构清晰地呈现出来,并使代码更易于理解;
if condition1 …… else …… end %空行 while condition2 …… end -
不同变量之间:不同类型变量之间可增加空行,加以区分。
%变量类型1:向量 %空行 %变量类型2:矩阵
15.代码调试
-
在需要调试的代码行上设置断点,以便在执行到该行时停止程序的执行;
-
在关键位置添加显示输出语句,以获取有关程序状态和变量值的附加信息;
disp([‘The result is: ’ num2str(result)]); % 打印数据信息 -
在调试代码时,考虑将日志记录添加到代码中,以记录程序执行的详细信息和关键变量的值;
fprintf('Result: %d\n', result); %记录计算结果 -
在调试期间监视和观察关键变量的值;
-
熟悉 MATLAB 的调试工具,如断点管理器、变量窗口、命令行调试等。掌握这些工具可以提高调试效率。

16.通用规范
-
避免出现含糊不清的代码;
a 变量命名时为按照Part-1(变量命名)创建,并增加注释表示其含义。 b b = 10; -
当涉及多个运算符或表达式的优先级时,建议使用括号明确指定操作顺序,以避免歧义和误解;
while (Rad_norm > epsilon_r || Opt_norm > epsilon_c) && cycle_max > iii …… end -
当小数点前面的数字非常大或非常小时,建议使用科学表示法,以提高代码的可读性和一致性;
epsilon_c = 1e-4; % 通信阈值参数 ε_c = 0.0001; epsilon_r = 1e-3; % 雷达阈值参数 ε_r = 0.001; -
对于逻辑表达式,使用自然且直接的形式,以使代码更易于理解。避免过多的否定或复杂的逻辑结构,使代码更简洁和可读;
a 错误示范:if ~(x ~= y || (x > y && y < 2 * x)) disp('Condition satisfied'); end b 建议格式:if x == y || (x <= y && y >= 2 * x) disp('Condition satisfied'); end -
若使用其它文本软件编写代码,需要和matlab的设置保持一致,如缩进字符数等。
常见文本编辑器:Notepad++、 Sublime Text等.
本文介绍了编程初学者应遵循的17项重要编码规范,包括变量和结构体命名、返回值处理、代码缩进、行长度控制、注释使用、函数模块化、输入验证等,旨在帮助提升代码可读性和维护性。

被折叠的 条评论
为什么被折叠?



