4 Structure數(shù)組
Structure數(shù)組也稱結(jié)構(gòu)數(shù)組,另外還有些書籍稱作架構(gòu)數(shù)組。結(jié)構(gòu)是MATLAB提供的一種將選擇的數(shù)據(jù)存儲到一個實體的數(shù)據(jù)類型。一個結(jié)構(gòu)可以由數(shù)據(jù)容器組成,這種容器叫做域,每個域中可以存儲MATLAB支持的數(shù)據(jù)類型。用戶可通過使用存儲數(shù)據(jù)時指定的域名來對域中的數(shù)據(jù)進行訪問。圖3-1是一個包括了a、b和c等3個域的結(jié)構(gòu)數(shù)組S的示意圖。
結(jié)構(gòu)中的每一個域都存儲一個獨立的MATLAB數(shù)組,這個數(shù)組可以屬于任何一個MATLAB或者用戶自定義的數(shù)據(jù)類型,而且可以具有任何合法的數(shù)組尺寸。結(jié)構(gòu)中的一個域可以存儲和另外一個域完全不同類型的數(shù)據(jù),而且數(shù)據(jù)的尺寸也可以完全不同。例如圖3-1所示的結(jié)構(gòu)s的第1個域a中存儲了1′6 double類型的數(shù)組,第2個域b中存儲了1′5字符串類型的數(shù)組,第3個域c中存儲了3′3 double類型的數(shù)組。
和MATLAB其他的數(shù)據(jù)類型相同,結(jié)構(gòu)類型也是一個數(shù)組。在MATLAB中,結(jié)構(gòu)類型稱為struct,若干個結(jié)構(gòu)組成的數(shù)組可以稱為結(jié)構(gòu)數(shù)組。和其他的MATLAB數(shù)據(jù)類型相同,結(jié)構(gòu)數(shù)組可以具有任何尺寸。如圖3-2所示,一個結(jié)構(gòu)數(shù)組s由兩個元素構(gòu)成:s(1)和s(2),每個元素都具有域a、b和c的結(jié)構(gòu)。
圖3-1 結(jié)構(gòu)示意圖
圖3-2 結(jié)構(gòu)數(shù)組示意圖
結(jié)構(gòu)數(shù)組具有很多優(yōu)點,使用結(jié)構(gòu)數(shù)組的理由如下。
(1)一般情況下使用結(jié)構(gòu)數(shù)組(或者下面提到的元胞數(shù)組)的原因是在實際中需要存儲多種混合的數(shù)據(jù)類型和尺寸。因為一般的MATLAB數(shù)組只能存儲同樣尺寸的同種數(shù)據(jù)類型的元素。結(jié)構(gòu)數(shù)組和元胞數(shù)組就是重要的混合數(shù)據(jù)類型存儲手段。
(2)一個結(jié)構(gòu)還提供了在一個實體中存儲特定數(shù)據(jù)的方法,這可以令用戶對數(shù)據(jù)進行整體或者部分訪問與操作。同時用戶可以將函數(shù)直接運用于結(jié)構(gòu),在用戶自定義的M文件函數(shù)之間進行數(shù)據(jù)傳遞,顯示結(jié)構(gòu)任何域中的值,或者進行支持結(jié)構(gòu)類型的任何MATLAB操作。
(3)用戶可以給數(shù)據(jù)以文字標簽,這樣在應(yīng)用中可以清楚地對數(shù)據(jù)所包含的信息進行標注。
4.1 Structure數(shù)組的創(chuàng)建
結(jié)構(gòu)數(shù)組的創(chuàng)建可以使用兩種方法,一種是直接賦值的方法,另外一種是利用struct函數(shù)創(chuàng)建。
1.使用直接賦值法創(chuàng)建結(jié)構(gòu)數(shù)組
每一個結(jié)構(gòu)數(shù)組可以包含若干個域,而每個域又可以是不同類型的數(shù)據(jù)。所謂直接賦值法創(chuàng)建結(jié)構(gòu)數(shù)組,就是采用直接定義結(jié)構(gòu)數(shù)組的域,并將相應(yīng)的數(shù)據(jù)值賦給該元素。
【例3-13】 直接賦值法創(chuàng)建結(jié)構(gòu)數(shù)組示例,以結(jié)構(gòu)數(shù)組保存員工資料數(shù)據(jù)。
>> employee.name='henry';
>> employee.sex='male';
>> employee.age=25;
>> employee.number=12345;
>> employee
employee =
name:'henry'
sex:'male'
age:25
number: 12345employee即是以結(jié)構(gòu)類型存儲的數(shù)據(jù)。結(jié)構(gòu)還可以通過賦值的方式擴展為結(jié)構(gòu)數(shù)組。例如在本例中添加員工lee的基本數(shù)據(jù)可以使用如下命令:
>> employee(2).name='lee';
>> employee(2).sex='female';
>> employee(2).age=23;
>> employee(2).number=98765;
>> employee(2)
ans =
name:'lee'
sex:'female'
age:23
number:98765
>> employee % 查看employee結(jié)構(gòu)數(shù)組
employee =
1x2 struct array with fields:
name
sex
age
number
可以看出,在添加元素之后,employee成為了“1x2 struct”。
【例3-14】 直接賦值法創(chuàng)建含子域結(jié)構(gòu)數(shù)組示例。
在結(jié)構(gòu)數(shù)組的使用過程中,一個結(jié)構(gòu)的域可以進一步存儲子域,操作的方法和域相同,只需名稱書寫過程中用'.'符號加上子域名即可。
>> green_house.name='一號房';
>> green_house.volume='2000 立方米';
>> green_house.parameter.temperature=...
[31.2 30.4 31.6 28.7;29.7 31.1 30.9 29.6]; %子域溫度
>> green_house.parameter.humidity=...
[62.1 59.5 57.7 61.5;62.0 61.9 59.2 57.5]; %子域濕度
green_house =
name: '一號房'
volume: '2000 立方米'
parameter: [1x1 struct]
本例中域parameter所存儲的就是一個結(jié)構(gòu),在parameter中包括子域。
>> green_house.parameter % 顯示域的內(nèi)容
ans =
temperature: [2x4 double]
humidity: [2x4 double]
>> green_house.parameter.temperature % 顯示子域中的內(nèi)容
ans =
31.2000 30.4000 31.6000 28.7000
29.7000 31.1000 30.9000 29.6000
2.使用struct函數(shù)創(chuàng)建結(jié)構(gòu)數(shù)組
除了直接賦值之外,用戶還可以使用struct函數(shù)創(chuàng)建結(jié)構(gòu)數(shù)組。struct函數(shù)可以根據(jù)指定的域及其相應(yīng)的值創(chuàng)建結(jié)構(gòu)體數(shù)組。此函數(shù)的—般形式為:
str_array=struct(‘filed1’,{val1},’filed2’,{val2}…)
str_array=struct(‘filed1’,val1,’filed2’,val2…)
其中'filed1'為域名,val1為該域的值,可能是一個標量或元胞數(shù)組,而使用的元胞數(shù)組必須具有相同的尺寸。
【例3-15】 使用struct函數(shù)創(chuàng)建結(jié)構(gòu)數(shù)組示例1。
>>student=struct('name','henry','age',25,'grade',uint16(1)) % 創(chuàng)建結(jié)構(gòu)數(shù)組
student =
name:'henry'
age:25
grade: 1
>> whos
Name Size Bytes Class Attributes
student 1x1 548 struct
>>student=struct('name',{'richard','jackson'},...
'age',{23,24},'grade',{2,3}) %創(chuàng)建結(jié)構(gòu)數(shù)組
student =
1x2 struct array with fields:
name
age
grade
>> whos
Name Size Bytes Class Attributes
student 1x2 924 struct
>>student=struct('name',{},'age',{},'grade',{})
student =
0x0 struct array with fields:
name
age
grade
>> whos
Name Size Bytes Class Attributes
student 0x0 192 struct
【例3-16】 使用struct函數(shù)創(chuàng)建結(jié)構(gòu)數(shù)組示例2。
>> s = struct('a', {{1 4 7 2 9 3}, 'Anne'},...
'b', {'James', pi}, ...
'c', {magic(3), (1:7)'}); % 使用struct函數(shù)創(chuàng)建結(jié)構(gòu)數(shù)組
>> s(1)
ans =
a:{[1] [4] [7] [2] [9] [3]}
b:'James'
c: [3x3double]
>> s(2)
ans =
a:'Anne'
b:3.1416
c: [7x1double]
另外需要注意的是:在MATLAB中,符號'{}'是用來表示元胞數(shù)組的(這點將在下一節(jié)介紹),而在結(jié)構(gòu)數(shù)組的賦值過程中,符號'{}'則被用來進行參數(shù)傳遞,如果要將元胞數(shù)組賦值給結(jié)構(gòu)數(shù)組,則應(yīng)使用符號'{{}}'。
4.2 Structure數(shù)組的尋訪
本小節(jié)介紹如何通過使用域名和下標對結(jié)構(gòu)數(shù)組進行尋訪。
1.一般結(jié)構(gòu)和域下標
最一般的對結(jié)構(gòu)數(shù)組進行存儲和尋訪的方法是:
structName(sRows, sCols, ...).fieldName(fRows,fCols, ...)
即在結(jié)構(gòu)數(shù)組名后面通過下標對數(shù)組中的某一個結(jié)構(gòu)進行尋訪,然后通過使用小數(shù)點'.'+域名對域進行尋訪。
如果結(jié)構(gòu)是一個標量,則可省略結(jié)構(gòu)名中的下標:
structName.fieldName(fRows, fCols, ...)
2.多層結(jié)構(gòu)數(shù)組的尋訪
在實際應(yīng)用中,經(jīng)常需要在一個域中設(shè)置多個子域,甚至進行多層的嵌套,這些子域中可以存儲MATLAB支持的數(shù)組類型。表3-5列出了尋訪多層結(jié)構(gòu)數(shù)組的語法。
表3-5 多層結(jié)構(gòu)數(shù)組的尋訪
元素類型
尋訪語法
元素類型
尋訪語法
結(jié)構(gòu)數(shù)組S
域A中為一般數(shù)組
S(3,15).A(5,25)
結(jié)構(gòu)數(shù)組S
域A中為元胞數(shù)組
子域B中為一般數(shù)組
S(3,15).A{5,20}.B(50,5)
結(jié)構(gòu)數(shù)組S
域A中為元胞數(shù)組
S(3,15).A{5,20}
結(jié)構(gòu)數(shù)組S
域A中為一般結(jié)構(gòu)
子域B中為元胞數(shù)組
S(3,15).A.B{5,20}
結(jié)構(gòu)數(shù)組S
域A中為一般數(shù)組
子域B中為一般數(shù)組
S(3,15).A(5,20).B(50,5)
3.結(jié)構(gòu)數(shù)組尋訪技巧
在結(jié)構(gòu)數(shù)組的尋訪過程中,使用以下技巧有一定的幫助作用。
使用whos函數(shù)來查看正在處理的數(shù)據(jù)的類型和尺寸。結(jié)合這些信息,用戶可以更準確地對需要的數(shù)據(jù)進行尋訪。
僅輸入表達式中等號右邊的部分,充分利用默認結(jié)果變量名ans。這樣通過不指定輸出結(jié)果的數(shù)據(jù)類型,可以盡量避免指定結(jié)果類型所造成的錯誤,用戶可以使用輸出結(jié)果中MATLAB軟件決定的數(shù)據(jù)類型,這樣在輸出結(jié)果中可以看出需要采用哪種方式來對數(shù)據(jù)進行尋訪。
另外用戶還可以分步對多層結(jié)構(gòu)數(shù)組進行尋訪,而不是一次性尋訪。例如可以將表達式S(5,3).A(4,7).B(:,4)分解成以下形式:
>> x = S(5,3).A; % x是一個結(jié)構(gòu)數(shù)組
>> y = x(4,7).B; % y 也是一個結(jié)構(gòu)數(shù)組
>> z = y(:,4) % z 是一個一般數(shù)組