MATLAB02:結構化編程和函數定義

學習一門技術最好的方式就是閱讀官方文檔,可以查看MATLAB官方文檔

結構化編程

流程控制語句和邏輯運算符

與大多數編程語言相同,MATLAB有以下流程控制語句:

流程控制語句 作用
if, elseif, else if語句爲真,則執行子句
switch, case, otherwise 根據switch語句內容判斷執行哪個子句
while 重複執行子句直到while中的條件爲真
for 執行子句固定次數
try, catch 執行子句並捕獲執行過程中的異常
break 跳出循環
continue 直接進入下一次循環
end 結束子句
pause 暫停程序
return 返回到調用函數處

上述所有循環和條件語句都要在末尾以end閉合.

MATLAB還有以下邏輯運算符:

運算符 意義
< 小於
<= 小於或等於
> 大於
>= 大於或等於
== 等於
~= 不等於
&&
||

&&||運算符支持邏輯短路功能.

流程控制語句示例

下面演示各流程控制語句:

  1. if語句:

    if語句的用法

    if rem(a, 2) == 0
    	disp('a is even');
    else
    	disp('a is odd');
    end
    
  2. switch語句:

    switch語句的用法

    switch input_num
    case -1
    	disp('negative 1');
    case 0
    	disp('zero');
    case 1
    	disp('positive 1');
    otherwise
    	disp('other value');
    end
    
  3. while語句:

    while語句的用法

    n = 1;
    while prod(1:n) < 1e100
    	n = n + 1;
    end
    
  4. for語句:

    for語句的用法

    for n=1:10
    	a(n)=2^n;
    end
    disp(a)
    
  5. break語句:

    x = 2; k = 0; error = inf;
    error_threshold = 1e-32;
    while error > error_threshold
        if k > 100
        	break
        end
        x = x - sin(x)/cos(x);
        error = abs(x - pi);
        k = k + 1;
    end
    

使用循環語句應儘量預先分配內存空間

若一個變量所需要的內存空間是一個可預測的定值,我們應儘量提前爲其分配內存空間.

以下面兩段程序爲例,演示這一點:

  • 程序一:

    tic
    for ii = 1:2000
        for jj = 1:2000
            A(ii,jj) = ii + jj;
        end
    end
    toc
    

    程序輸出Elapsed time is 4.616199 seconds.

  • 程序二:

    tic
    A = zeros(2000, 2000);		% 預先爲變量分配內存空間
    for ii = 1:size(A,1)
        for jj = 1:size(A,2)
            A(ii,jj) = ii + jj;
        end
    end
    toc
    

    程序輸出Elapsed time is 2.786401 seconds.

可以看到,程序一比程序二所用的時間更少.這是因爲: 對於程序一,沒有預先爲變量A分配內存,因此每當A的形狀發生改變時,都需要重新爲A分配內存地址,這花費了更多的時間.

編寫腳本時應注意的問題

在腳本開頭應添加語句清空工作區

在每個腳本的開頭,應添加下述語句,清空工作區緩存以及之前程序運行的痕跡:

clear all	% 清空工作區內存中的變量
close all 	% 關閉之前程序繪製的圖像
clc			% 清空之前程序在終端的輸出

在運算和賦值語句後應添加分號;抑制輸出

在所有運算和賦值語句都應該添加分號;抑制輸出,若需要向終端輸出一個變量,應對其調用disp方法.

使用省略號...拼接多行語句

在MATLAB中,省略號...可以將多行語句拼接爲一行,靈活使用該語句可以提高代碼可讀性.

annPoints_sampled = annPoints(annPoints(:,1)>x1 & ...
    annPoints(:,1) < x2 & ...
    annPoints(:,2) > y1 & ...
    annPoints(:,2) < y2);

函數

與其他語言相似,MATLAB也可以定義函數.與腳本類似,函數可以被存入函數名.m文件中,也可以以函數句柄的形式定義在內存中.

查看內置函數

我們可以使用which命令查看內置函數源代碼文件的位置,與edit命令結合可以查看內置函數的源代碼.

運行下面語句可以打開MATLAB內置的mean函數的源文件:

edit(which('mean.m'))

可以在編輯器中看到mean函數的源代碼如下:

mean函數源代碼

函數名.m文件形式定義函數

在MATLAB文件中定義函數的格式如下:

function [輸出變量名] = 函數名(輸入變量名) 
% 函數的文檔

函數代碼
  • function是一個關鍵字,聲明該文件中保存的是一個函數.
  • 輸入變量輸出變量是非必須的,函數既可以沒有輸入變量,也可以沒有輸出變量.
  • 函數名應與.m文件名相同,且不包含特殊字符(最好不要有中文).

MATLAB內置的函數參數

在MATLAB中,內置了一些函數參數如下:

函數參數 意義
imputname 輸入變量名列表
mfilename 函數源代碼文件名
nargin 輸入變量數
nargout 輸出變量個數
varargin 可變長輸入參數列表
varargout 可變長輸出參數列表

MATLAB不提供其他高級語言的指定默認參數值以及函數重載等語法,但靈活使用上述內置的函數參數,可以在一定程度上實現指定默認參數值以及方法重載:

function [volume]=pillar(Do,Di,height)
if nargin==2,
	height=1;
end
volume=abs(Do.^2-Di.^2).*height*pi/4;

MATLAB函數定義示例1

下面程序用來計算自由落體運動中位移量:
x=x0+v0t+12gt2 x = x_0 + v_0 t + \frac{1}{2} g t^2

function x = freebody(x0,v0,t)
% calculation of free falling
% x0: initial displacement in m
% v0: initial velocity in m/sec
% t: the elapsed time in sec
% x: the depth of falling in m
x = x0 + v0.*t + 1/2*9.8*t.*t;

該函數演示了一個MATLAB編程技巧: 計算乘法時應儘量使用.*而非*,因爲前者不僅對參數t爲標量的情況可用,也對變量t爲向量或矩陣的情況可用.

freebody(0, 0, 2)			% 得到 19.6000
freebody(0, 0, [0 1 2 3])	% 得到 [0 4.9000 19.6000 44.1000]
freebody(0, 0, [0 1; 2 3])	% 得到 [0 4.9000; 19.6000 44.1000]

MATLAB函數定義示例2

下面函數實現了從華氏溫度到攝氏溫度的轉換,該函數可以識別輸入的待轉換樣例的個數,當輸入的待轉換樣例個數爲0時,退出函數.

function F2C()
while 1
    F_degree = input('tempreature in Fahrenheit: ', 's');
    F_degree = str2num(F_degree);
    if isempty(F_degree)
        return
    end
    C_degree = (F_degree-32)*5/9;
    disp(['tempreature in Celsius: ' num2str(C_degree)])
end

F2C函數執行結果

以函數句柄形式定義函數

我們也可以使用函數句柄的形式定義函數,這更接近數學上的函數定義,其語法如下:

函數句柄 = @(輸入變量) 輸出變量 

可以直接通過函數句柄調用該方法.

f = @(x) exp(-2*x);
x = 0:0.1:2;
plot(x, f(x));
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章