如何寫一個(gè)m函數(shù)?--北太天元學(xué)習(xí)10
如何寫一個(gè)m函數(shù)? -- 北太天元學(xué)習(xí)10
北太天元的執(zhí)行命令可以寫到一個(gè)m文件,m文件可以分為兩種,一種成為m腳本,另一種叫 m函數(shù)。
我舉一個(gè)如何判斷一個(gè)整數(shù)是否是素?cái)?shù)的例子來(lái)說(shuō)明m腳本和m函數(shù)的區(qū)別。
首先,我們回顧一下素?cái)?shù)的定義: 大于1的整數(shù)如果只能被1和它本身兩個(gè)正整數(shù)整除,
那么這個(gè)數(shù)被成為素?cái)?shù)(又叫質(zhì)數(shù)).
先寫一個(gè)腳本來(lái)判斷一個(gè)正整數(shù)是否是素?cái)?shù):
while 1
?? ?n = input("請(qǐng)輸入一個(gè)正整數(shù):? ");
?? ?if? n > 0? && mod(n,1) == 0
?? ??? ?break;
?? ?end
end
素?cái)?shù)判斷結(jié)果 = true;
if( n ==1 )
?? ?素?cái)?shù)判斷結(jié)果 = false;
elseif (n==2 || n == 3)
?? ?素?cái)?shù)判斷結(jié)果 = true; ?? ??? ?
else
?? ?%計(jì)算n的平方根
?? ?sqrt_n = sqrt(n);
?? ?%檢測(cè)是否n 能否被小于或者等于 sqrt(n) 且比1大的整數(shù)整除
?? ?for m=2:1:sqrt_n
?? ??? ?if mod(n,m) == 0
?? ??? ??? ?素?cái)?shù)判斷結(jié)果 = false;
?? ??? ??? ?break
?? ??? ?end
?? ?end
end
?? ?
if 素?cái)?shù)判斷結(jié)果 == true
?? ?fprintf("%d 是素?cái)?shù)\n", n);
else
?? ?fprintf("%d 不是素?cái)?shù)\n", n);
end
?? ?
這是一個(gè)腳本,在這個(gè)腳本運(yùn)行之后,你可以看到工作區(qū)里多了 m, n , sqrt_n 等幾個(gè)變量. 我們要完成一個(gè)更加復(fù)雜的任務(wù),例如我們要驗(yàn)證哥德巴赫猜想:
對(duì)于一個(gè)大于或者等于4的偶數(shù) n, 可以找到兩個(gè)素?cái)?shù)p和q, 滿足
?? n = p + q;
n = 28;
符合歌猜 = false;
for p = 2:n/2
?? ?if? isprime(p) && isprime(n-p)
?? ??? ?符合歌猜 = true;
?? ??? ?break;
?? ?end
end
if (符合歌猜 == true)
?? ?fprintf("%d 可以寫成兩個(gè)素?cái)?shù)的和: %d = %d + %d \n", n, n, p, n-p);
end
我們?cè)趯戇@個(gè)腳本的時(shí)候,希望能夠把判斷一個(gè)數(shù)p是否是素?cái)?shù)的算法重用,
我期待使用的是把 p 作為輸入?yún)?shù), 然后使用是否是素?cái)?shù)的判斷結(jié)果。
那么上面我們給出的腳本的局限性就顯現(xiàn)出來(lái)了。
把上面素?cái)?shù)判斷的算法寫成下面的m函數(shù)就可以滿足我們上面的要求
1. 我們首先建立一個(gè)m文件,文件名是 isprime
2.? 把我們把算法放在以關(guān)鍵字function 和 end 圈定的范圍內(nèi),
例如,我們把上面的m腳本改造成下面的m函數(shù)
function? 素?cái)?shù)判斷結(jié)果 = isprime(n)
?? ?if? ~( n>0 && mod(n,1) == 0)
?? ??? ?素?cái)?shù)判斷結(jié)果 = false;
?? ??? ?return;
?? ?end
? if( n ==1 )
?? ??? ?素?cái)?shù)判斷結(jié)果 = false;
?? ??? ?return;
?? ?end
?? ?if (n==2 || n == 3)
?? ??? ?素?cái)?shù)判斷結(jié)果 = true; ?? ??? ?
?? ??? ?return;
?? ?end
?? ??? ?
?? ?%計(jì)算n的平方根
?? ?sqrt_n = sqrt(n);
?? ?%檢測(cè)是否n 能否被小于 sqrt(n) 且比1大的整數(shù)整除
?? ?for m=2:1:sqrt_n
?? ??? ?if mod(n,m) == 0
?? ??? ??? ?素?cái)?shù)判斷結(jié)果 = false;
?? ??? ??? ?return;
?? ??? ?end
?? ?end
?? ?素?cái)?shù)判斷結(jié)果 = true;
end % 和 function 配對(duì)
我們可以在命令行窗口輸入
>> isprime(2)
得到 true
>> b = isprime(20)
那么 b 是一個(gè)? logical 變量,值是 false
再看我們給出的 m 函數(shù), 它的函數(shù)名和文件名相同,命名規(guī)范是
m文件名、變量名的命名規(guī)范是相同的, 要求是必須以 字母、中文、下劃線_ 開頭,
后面可以接 字母、中文、下劃線_ 、數(shù)字的組合.
function? 素?cái)?shù)判斷結(jié)果 = isprime(n)
素?cái)?shù)判斷結(jié)果 是 輸出參數(shù), n 是輸入?yún)?shù), 有時(shí)候又稱為
輸出形式參數(shù) (輸出形參), 輸入?yún)?shù)n 可以稱為輸入形式參數(shù) (輸入形參).
在調(diào)用 isprime 這個(gè)m函數(shù)的時(shí)候,我們可以使用
b = isprime(20)
b 是輸出實(shí)際參數(shù)( 輸出實(shí)參 ) , 20 是真正的輸入?yún)?shù),在實(shí)際執(zhí)行的時(shí)候,
isprime(n) 的輸入形參n 將會(huì)被賦值為 20.
有了m函數(shù),我們很容易的應(yīng)用素?cái)?shù)判斷的m函數(shù),
我們?nèi)菀讓懗鲵?yàn)證哥德巴赫猜想算法
n = 28;
符合歌猜 = false;
for p = 2:n/2
?? ?if? isprime(p) && isprime(n-p)
?? ??? ?符合歌猜 = true;
?? ??? ?break;
?? ?end
end
if (符合歌猜 == true)
?? ?fprintf("%d 可以寫成兩個(gè)素?cái)?shù)的和: %d = %d + %d \n", n, p, n-p);
end
如果我們?cè)谡{(diào)用 isprime 函數(shù)的時(shí)候,輸入了 isprime(), 此時(shí)遇到的
報(bào)錯(cuò)就不是很明確, 因此,為了我們 isprime 函數(shù)更加的智能, 我們可
以到用戶的輸入的參數(shù)的個(gè)數(shù)進(jìn)行檢查, 用到的是 nargin 這個(gè)系統(tǒng)變量,
?? ?它獲得的是用戶輸入實(shí)參的個(gè)數(shù)。
例如: ?
>> isprime()
則 nargin == 0 ,
因此我們可以修改 isprime 函數(shù)如下:
function? 素?cái)?shù)判斷結(jié)果 = isprime(n)
?? ?if nargin ~= 1
?? ??? ?error("isprime 的輸入實(shí)參需要是一個(gè)正整數(shù)\n");
?? ?end
?? ?
?? ?if? ~( n>0 && mod(n,1) == 0)
?? ??? ?素?cái)?shù)判斷結(jié)果 = false;
?? ??? ?return;
?? ?end
? if( n ==1 )
?? ??? ?素?cái)?shù)判斷結(jié)果 = false;
?? ?elseif (n==2 || n == 3)
?? ??? ?素?cái)?shù)判斷結(jié)果 = true; ?? ??? ?
?? ?else
?? ??? ?%計(jì)算n的平方根
?? ??? ?sqrt_n = sqrt(n);
?? ??? ?%檢測(cè)是否n 能否被小于 sqrt(n) 且比1大的整數(shù)整除
?? ??? ?for m=2:1:sqrt_n
?? ??? ??? ?if mod(n,m) == 0
?? ??? ??? ??? ?素?cái)?shù)判斷結(jié)果 = false;
?? ??? ??? ??? ?return;
?? ??? ??? ?end
?? ??? ?end
素?cái)?shù)判斷結(jié)果 = true;
end % 和 function 配對(duì)
我們?cè)僬{(diào)用 isprime函數(shù)
>> isprime
那么就會(huì)看到輸出的提示信息:
?? ?isprime 的輸入實(shí)參需要是一個(gè)正整數(shù)
?? ?
?? ?function [輸出形式參數(shù)列表? ] = 函數(shù)名(輸入形式參數(shù)列表)
?? ?end
?? ?>> [ 輸出實(shí)參列表 ] = 函數(shù)名(輸入實(shí)慘列表) ?
下面給出另一個(gè)m 函數(shù)例子
?? ?function [y,z] = func10(m,n)
?? ?? y = m + n;
?? ??? ?z = m - n;
?? ?end
調(diào)用func10
?? ?>>? func10(2,3)
?? ?>> [ y1, y2 ] = func10(2,1)
知識(shí)點(diǎn)小結(jié):
error 函數(shù)
return? 終止m函數(shù)
nargin? 系統(tǒng)變量, 用來(lái)獲得輸入實(shí)參的個(gè)數(shù)
input 內(nèi)置函數(shù)
mod??? 取余數(shù)(我在視頻里口誤說(shuō)成取模了) mod(3,2)? 得到1 ,?? rem 取余數(shù), 差異
mod(m,n) rem(m,n)在m, n 是同號(hào)時(shí),結(jié)果相同,異號(hào)時(shí),結(jié)果不同
? rem(7,-4)
ans =
? 1x1 double
?? 3
mod(7,-4)
ans =
? 1x1 double
? -1