Matlab代码编写格式推荐之半夜发疯

本文介绍了编程初学者应遵循的17项重要编码规范,包括变量和结构体命名、返回值处理、代码缩进、行长度控制、注释使用、函数模块化、输入验证等,旨在帮助提升代码可读性和维护性。

前言之看一眼没坏处

        初学者建议按一定的规范编写代码,因为~进公司后,老大会因为找不到理由夸你而发愁!!!大部分建议的后面会紧跟着一个简单的例子,便于理解。拿走不谢!!!

        友情提示:转载请标明出处,谢谢合作!!!不然画个圈圈诅咒你(狗头)……

1.变量命名:     

  1. 建议使用“有意义且描述性”的名称,能够清晰地表达其用途和含义;

    wheelbase = 10;		% 轴距大小为10.
  2. 建议使用“小写字母”命名,有助于与函数名和类名进行区分;

    lambda = 1; 			% 电磁波波长
  3. 若存在几个相同功能的变量,可使用多单词命名,单词中间使用“_”隔开;

    epsilon_c = 1e-4; 		% 通信阈值参数 ε_c = 0.0001;
    epsilon_r = 1e-3; 		% 雷达阈值参数 ε_r = 0.001
    首字母或者单词代表“阈值参数”,下划线后表示“不同的类型”。
  4. 不要将 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……
  5. 建议变量名总字符长度小于30(个别公司要求),若命名涉及单词的数目太多,可使用简称代替对应的单词;

    sim_commun_max = 20;		% 通信仿真最大次数(maximum number of communication simulations)
    simulations --- sim; communication --- commun; maximum --- max
  6. 在特定领域或项目中,可能存在特定的命名约定或惯例。应与团队成员保持一致并遵循相关约定;
    1. 论文中出现的变量名:FoptHKFc……
    2. 专业术语的简称:SNRSDRQCQP……             

2.结构体命名

  1. 结构体的命名应该以一个大写字母开头,有助于区分结构体与普通变量。

    Radar.lambda = 1;		% 雷达的电磁波波长为1
    Radar.SNR = -10 : 2 : 30;		% 雷达的信噪比为-10~30,采样间隔为2
    其中:Radar为结构体名,lambdaRadar结构体的变量,其值为1
  2. 选择具有描述性的名称来命名结构体,能够清晰地表达其用途和内容;

    Radar.xxxx			% 雷达相关的的结构体
    Com.xxxx			% 通信相关的的结构体
  3. 避免使用 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……
  4. 在特定领域或项目中,可能存在特定的命名约定或惯例。应与团队成员保持一致并遵循相关约定。

3.返回值变量命名

  1. 选择描述性的名称来命名返回值变量,能够清晰地表达其含义和用途。确保名称与返回值的内容相匹配。

    a    function [Urad,  FD ] = ISAC_SDR_AltMin(Frad, Fopt,……)
    b    function [out1, out2] = ISAC_SDR_AltMin(Frad, Fopt,……)

    其中a函数返回值的命名可提高可读性,无需详细浏览ISAC_SDR_AltMin函数可直接确认返回值的含义(反例为b)

  2. 函数输出的常量的命名建议全部为小写或大小写混合。

    a    function [angle, coord] = KinematicModel(a, phi, ...)	
    b    function [Fopt, Wopt, H, ar, at] = SV_mmWave_channel(Nt1, Nt2, ...)
    

    其中angle, coordFopt, Wopt, H, ar, at为函数的返回值。

  3. 如果函数返回多个相关的值,可以考虑将这些值作为结构体的字段或对象的属性进行返回。这样可以提供更好的封装和易读性。

    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(θ)); 		% 雷达波束形成矩阵
    
  4. 如果返回的是数组或矩阵,可以在函数开始时预先分配足够的内存空间,以避免频繁的内存重新分配。

    myMatrix = zeros(100, 100);		% 预先分配一个 100x100 的零矩阵
  5. 尽量避免使用全局变量来存储函数的返回值。应该优先通过函数的返回值来传递结果。

    ​错误示例:global myGlobalVariable		% 声明全局变量myGlobalVariable
    ​​​​

4.缩进

  1. 优先建议使用四个空格进行缩进(懒人专场:使用TAB键缩进),有助于代码的可读性(赏心悦目,特别是在多层嵌套环境下调试时,方便浏览整体框架,不然看着就痛苦面具)

  2. 每个嵌套的代码块应该相对于上一级代码块进行适当的缩进,以突出显示其层次结构。

  3. 避免在代码块中过度缩进,这会导致代码水平过宽,可能降低代码的可读性。

  4. 在整个代码中应保持一致的缩进风格,有助于统一代码的外观,并使其更易于阅读和理解。

    举例说明:
    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.合理使用空格

  1. 操作符周围的空格:在二元操作符( +-、*、/ 等)两侧留出空格,以增加代码的可读性。

    x = Xmax - rand * (Xmax - Xmin);	
  2. 逗号和分号后面的空格:在逗号和分号之后留出一个空格,以增加代码的可读性。

    function [a] = Array_Response(Elevation, Azimuth, ……, Module)
  3. 数组、矩阵和单元数组的元素之间的空格:在元素之间留出适当的空格,以增加元素的可读性。

    SNRdB     = -30:5:10;		    % 信噪比(dB)
    Radar_DOA = [0; 30; 50; 70];	% 测试使用
  4. 赋值操作符周围的空格:在赋值操作符 = 的两侧留出空格,以增加代码的可读性。

    for sim_ii = 1 : SIM_NUM
    	……
    end

6.控制行长度

  1. 尽量将每行代码的长度限制在80个字符以内。这有助于在大多数文本编辑器和终端窗口中更好地显示代码。

  2. 如果一行代码太长,可以选择合适的位置使用“”进行换行。建议在运算符后或逗号之后进行换行。

    [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);
  3. 对于需要换行的运算符,将运算符放在新行的开头,而非结束行的结尾。这样可以清楚地表示运算符的运算顺序。

    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'));
  4. 对于函数调用时的参数列表,可以将每个参数放在新行上,并使用适当的缩进来增加代码的可读性。

    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
    
  5. 如果括号内的内容超出了行的长度限制,可以将内容放在新行上,并使用适当的缩进,以突出显示其层次结构。

    plot(Rad_theta * 180 / pi, 10 * log10(diag(FF_AOI_at’ * …… * FF_AOI_at )...
                         / real(trace(……))), 'LineWidth', 1.5); hold on;
    
    ​​​​

7.条件语句

  1. 在条件语句中使用 if-elseif-else-end 结构来处理多个条件。确保每个关键字后面有正确的语法结构。

    if condition1 ……elseif condition2 ……else ……end
  2. 按照逻辑顺序排列条件,将最常见或最简单的条件放在前面。这样可以提高代码的效率,并减少不必要的条件判断;​​​​

  3. 尽管 MATLAB 中的条件语句中的括号是可选的,但对于复杂的条件表达式,建议使用括号来明确优先级和增强可读性;

    if (condition1 && condition2) || (condition3 && condition4) ……end
    
    ​​​​​​
  4. switch语句应该包含otherwise条件;

    switch x 
        case 1     disp('x is 1’); 
        case 2     disp('x is 2’); 
        otherwise  disp('Unexpected value for x’); 
    end
    
  5. 避免使用if 0条件表达式;

    1. 可读性差:使用 if 0 条件可能会使代码变得难以理解,因为它没有明确的目的或作用。其他人阅读代码时可能会对其意图产生疑惑;

    2. 容易被忽略:其中的代码块将始终被跳过,这可能导致开发人员在后续修改或调试代码时忽视它们;

    3. 潜在的错误:将真实的代码放在 if 0 条件表达式中,并且以后忘记更改为真实的条件,那么这段代码将永远不会执行,即使有需要执行它的情况。​​​​​​​​​​​​​​

8.循环语句

  1. 确保循环条件能够清晰地表达其意图,并且易于理解。这有助于其他人阅读代码和理解循环的目的;​​​​​​​

    for i = 1 : length(array) 
        if array(i) > 0 
            sum = sum + array(i); 
        end 
    end
    
    ​​​​​​​
  2. 在循环语句中,确保控制流的正确处理。在需要时使用 breakcontinue 或其他控制语句来跳出循环或继续下一次迭代(应该尽量少使用 breakcontinue);

  3. 确保循环条件能够最终达到结束条件。不要出现while(true);

  4. 避免多层嵌套(嵌套次数尽可能控制在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.合理对齐

  1. 对于结构体的字段,可以将字段名称对齐,以增加结构体字段的可读性;​​​​​​​

    myStruct = struct('field1', value1, ... 
    		          'field2', value2, ...
    		          ‘field3', value3);

    ​​​​​​​

  2. 如果有多个赋值语句,可以将等号对齐,以增加代码的可读性;

    variable1 = someLongExpression1; 
    variable2 = someLongExpression2; 
    abb       = someLongExpression3;
    

    ​​​​​​​

  3. 在函数调用时,将多个参数垂直对齐,并在参数列表之间保留适当的空格,以增加代码的可读性。特别是一行代码装不下的情况下,非常建议对齐,毕竟看着就爽;

    result = myFunction(arg1, arg2, ... 
    		            arg3, arg4);

    ​​​​​​​

  4. 在团队编写代码时,建议在整个代码中保持一致的对齐风格和约定,以提高代码的可读性和一致性(此项为公司要求)。

10.添加注释

  1. 使用注释来解释代码的目的、功能和实现方法。注释应该概括性地描述代码的意图和逻辑;

    % 模拟车辆运动学模型
    for i = 1:num_steps 
    	……
    end
    ​​​​​​​
  2. 注释应该注重于关键性的信息,如算法的步骤、变量的含义或特殊处理的原因等;

    Urad = (randn(K, Ns) + 1i * randn(K, Ns)) / sqrt(2);		% 随机初始化Urad矩阵/单位化
    ​​​​​​​
  3. 避免对每个细节都进行注释,注重于解释那些非显而易见或容易混淆的部分;

  4. 可以使用两种主要的注释风格:行注释(%)和块注释(%{...%})。选择适用的注释风格来增强代码的可读性;

    1. %{……%}:块注释,可跨多行,添加对代码的详细说明、功能描述等;

    2. % :行注释。​​​​​​​​​​​​​​

  5. 对于长的或复杂的代码块,可以使用注释行来标记段落,并提供简短的描述;

    % SVD分解求解Urad 
    [U, S, V] = svd(Frad' * FD); 
    …… 
    Unit_Matrix = eye(size(U, 2)); 
    ​​​​​​​
  6. 建议注释行数不少于代码总行数的1/3 (个别公司强制要求)

11.函数抬头备注

  1. 写明函数的名称,并简要描述函数的目的和功能。这帮助其他人快速了解函数的用途;

  2. 列出函数的输入参数以及每个参数的类型、含义和限制等信息。描述各个参数的名称、用途和意义;

  3. 指明函数的输出结果以及每个输出的数据类型和含义。描述函数的返回值、输出参数或修改传入参数的方式;

  4. 提供函数的正确语法和用法示例,以便其他人知道如何正确调用和使用该函数;

  5. 如果有特殊的注意事项、使用限制或需要其他环境条件,请在抬头备注中进行说明;

  6. 如果有相关的参考文献、链接或其他资源,可以在抬头备注中提供这些信息,以便其他人进一步了解相关内容。​​​​​​​

12.代码模块化

  1. 将代码分解为模块或函数,每个函数执行一个特定的任务。这有助于提高可读性和可维护性,并便于重复使用;​​​​​​​

    % 交替SDR优化函数
    function [Urad, FD] = ISAC_SDR_AltMin(Frad, Fopt, epsilon_r, epsilon_c, rho, PT, cycle_max) 
    	……
    end
    ​​​​​​​
  2. 编写单元测试函数来验证每个函数的正确性;

  3. 为 函数编写文档,包括使用说明、输入输出示例、依赖项等信息。这样可以帮助其他人理解代码,并为自己提供未来参考 (此项为公司要求)

13.输入验证和错误处理

  1. 在函数内部进行输入参数的验证,以确保其合法性和适用性。可以检查变量的类型、大小、范围等;

    if rho < 0 || rho > 1 
    	rho = 0.5; 
    end
    ​​​​​​​
  2. 如果输入无效,可以抛出异常并提供相应的错误消息;

    if ~isnumeric(input) || numel(input) ~= 1 
    	error('Input must be a numeric scalar.’); 
    end
    ​​​​​​​
  3. 使用 error 函数返回错误消息,说明导致错误的原因和解决方法。这有助于用户识别和纠正错误;

  4. 使用 warning 函数返回警告消息,指示潜在的问题或需要注意的事项;

    if input < 0 
    	error('Input must be non-negative.’); 
    elseif input == 0 
    	warning('Input is zero, which may cause unexpected behavior.’); 
    end
    ​​​​​​​
  5. 使用 try-catch 块捕获可能引发异常的代码段,并在 catch 块中处理异常情况。可以通过显示错误消息、记录日志或执行其他适当的操作来处理异常(此项可暂不学习)

  6. 对于可能引发多种异常的代码,可以使用多个 catch 块来分别处理不同类型的异常(此项可暂不学习)。

    try % 可能引发异常的代码 catch exception % 处理异常情况 end
    ​​​​​​​​​​​​

14.合理使用空行

  1. 函数之间:在不同的函数之间添加空行,以便在代码中创建适当的分隔。这有助于区分不同功能的代码段,使代码更易于阅读;​​​​​​​

    function output = function1(input) …… end
    %空行
    function output = function2(input) …… end
    ​​​​​​​
  2. 代码段之间:在相似但独立的代码段之间添加空行,以将它们区分开来,可提高代码的模块化程度;

    %算法1:SDR
    %空行
    %算法2:Manopt
    ​​​​​​​
  3. 逻辑块之间:在逻辑上相关的代码块之间添加空行,以增强代码的可读性。这有助于将逻辑结构清晰地呈现出来,并使代码更易于理解;

    if condition1 …… else …… end
    %空行
    while condition2 …… end
    ​​​​​​​
  4. 不同变量之间:不同类型变量之间可增加空行,加以区分。

    %变量类型1:向量
    %空行
    %变量类型2:矩阵
    ​​​​​​​

15.代码调试

  1. 在需要调试的代码行上设置断点,以便在执行到该行时停止程序的执行;

  2. 在关键位置添加显示输出语句,以获取有关程序状态和变量值的附加信息;

    disp([‘The result is: ’ num2str(result)]); 	% 打印数据信息
    ​​​​​​​
  3. 在调试代码时,考虑将日志记录添加到代码中,以记录程序执行的详细信息和关键变量的值;

    fprintf('Result: %d\n', result);		%记录计算结果
    ​​​​​​​
  4. 在调试期间监视和观察关键变量的值;

  5. 熟悉 MATLAB 的调试工具,如断点管理器、变量窗口、命令行调试等。掌握这些工具可以提高调试效率。

    ​​​​​​​

16.通用规范

  1. 避免出现含糊不清的代码;

    a    变量命名时为按照Part-1(变量命名)创建,并增加注释表示其含义。
    b    b = 10; 
    ​​​​​​​
  2. 当涉及多个运算符或表达式的优先级时,建议使用括号明确指定操作顺序,以避免歧义和误解;

    while (Rad_norm > epsilon_r || Opt_norm > epsilon_c) && cycle_max > iii 
    	……
    end
    ​​​​​​​
  3. 当小数点前面的数字非常大或非常小时,建议使用科学表示法,以提高代码的可读性和一致性;

    epsilon_c = 1e-4; 		% 通信阈值参数 ε_c = 0.0001;
    epsilon_r = 1e-3; 		% 雷达阈值参数 ε_r = 0.001;
    ​​​​​​​
  4. 对于逻辑表达式,使用自然且直接的形式,以使代码更易于理解。避免过多的否定或复杂的逻辑结构,使代码更简洁和可读;

    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
    
    ​​​​​​​
  5. 若使用其它文本软件编写代码,需要和matlab的设置保持一致,如缩进字符数等。

    常见文本编辑器:Notepad++ Sublime Text等.​​​​​​​​​​​​​​

17.未完待续……

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值