matlab中使用結構體

轉自http://hi.baidu.com/dess2211/blog/item/bb9b80185a7f940334fa417c.html
matlab中使用結構體
結構(struct)數組

要在MALTAB中實現比較複雜的編程,就不能不用struct類型。而且在MATLAB中實現struct比C中更爲方便。

4. 3.1 結構數組的創建
MATLAB提供了兩種定義結構的方式:直接應用和使用struct函數。
1. 使用直接引用方式定義結構
與建立數值型數組一樣,建立新struct對象不需要事先申明,可以直接引用,而且可以動態擴充。比如建立一個複數變量x:
x.real = 0; % 創建字段名爲real,併爲該字段賦值爲0
x.imag = 0 % 爲x創建一個新的字段imag,併爲該字段賦值爲0
x =
real: 0
imag: 0
然後可以將旗動態擴充爲數組:
x(2).real = 0; % 將x擴充爲1×2的結構數組
x(2).imag = 0;
在任何需要的時候,也可以爲數組動態擴充字段,如增加字段scale:
x(1).scale = 0;
這樣,所有x都增加了一個scale字段,而x(1)之外的其他變量的scale字段爲空:
x(1) % 查看結構數組的第一個元素的各個字段的內容
ans =
real: 0
imag: 0
scale: 0
x(2) % 查看結構數組的第二個元素的各個字段的內容,注意沒有賦值的字段爲空
ans =
real: 0
imag: 0
scale: []
應該注意的是,x的real、imag、scale字段不一定是單個數據元素,它們可以是任意數據類型,可以是向量、數組、矩陣甚至是其他結構變量或元胞數組,而且不同字段之間其數據類型不需要相同。例如:
clear x; x.real = [1 2 3 4 5]; x.imag = ones(10,10);

數組中不同元素的同一字段的數據類型也不要求一樣:
x(2).real = '123';
x(2).imag = rand(5,1);
甚至還可以通過引用數組字段來定義結構數據類型的某字段:
x(3).real = x(1); x(3).imag = 3; x(3)
ans =
real: [1x1 struct]
imag: 3
下面看一個實際的例子來熟悉直接引用方式定義與顯示結構。
【例4.3.1-1】 溫室數據(包括溫室名、容量、溫度、溼度等)的創建與顯示。
(1) 直接對域賦值法產生結構變量 
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];
(2)顯示結構變量的內容
green_house % 顯示結構變量結構
green_house =
name: '一號溫室'
volume: '2000立方米'
parameter: [1x1 struct]
green_house.parameter % 用域作用符號. 顯示指定域(parameter)中內容
ans =
temperature: [2x4 double]
humidity: [2x4 double]
green_house.parameter.temperature % 顯示temperature域中的內容
ans =
31.2000 30.4000 31.6000 28.7000
29.7000 31.1000 30.9000 29.6000

【例4.3.1-2】在上例的基礎上,創建結構數組用以保存一個溫室羣的數據。
green_house(2,3).name = '六號溫室'; %產生2×3結構數組
green_house % 顯示結構數組的結構
green_house =
2x3 struct array with fields:
name
volume
parameter
green_house(2,3) % 顯示結構數組元素的結構
ans =
name: '六號溫室'
volume: []
parameter: []

2. 使用struct函數創建結構
使用struct函數也可以創建結構,該函數產生或吧其他形式的數據轉換爲結構數組。
struct的使用格式爲:
s = sturct('field1',values1,'field2',values2,…);
該函數將生成一個具有指定字段名和相應數據的結構數組,其包含的數據values1、valuese2等必須爲具有相同維數的數據,數據的存放位置域其他結構位置一一對應的。對於struct的賦值用到了元胞數組。數組values1、values2等可以是元胞數組、標量元胞單元或者單個數值。每個values的數據被賦值給相應的field字段。
當valuesx爲元胞數組的時候,生成的結構數組的維數與元胞數組的維數相同。而在數據中不包含元胞的時候,得到的結構數組的維數是1×1的。例如:
s = struct('type',{'big','little'},'color',{'blue','red'},'x',{3,4})
s =
1x2 struct array with fields:
type
color
x
得到維數爲1×2的結構數組s,包含了type、color和x共3個字段。這是因爲在struct函數中{'big','little'}、{'blue','red'}和{3,4}都是1×2的元胞數組,可以看到兩個數據成分分別爲:
s(1,1)
ans =
type: 'big'
color: 'blue'
x: 3
   s(1,2)
ans =
type: 'little'
color: 'red'
x: 4
相應的,如果將struct函數寫成下面的形式:
s = struct('type',{'big';'little'},'color',{'blue';'red'},'x',{3;4})
s =
2x1 struct array with fields:
type
color
x
則會得到一個2×1的結構數組。
下面給出利用struct構建結構數組的具體實例。
【例4.3.1-3】利用函數struct,建立溫室羣的數據庫。
(1) struct預建立空結構數組方法之一
a = cell(2,3); % 創建2×3的元胞數組
green_house_1=struct('name',a,'volume',a,'parameter',a(1,2))
green_house_1 =
2x3 struct array with fields:
name
volume
parameter
(2)struct預建空結構數組方法之二
green_house_2=struct('name',a,'volume',[],'parameter',[])    
green_house_2 =
2x3 struct array with fields:
name
volume
parameter
(3)struct預建空結構數組方法之三
green_hopuse_3(2,3)=struct('name',[],'volume',[],'parameter',[])
green_hopuse_3 =
2x3 struct array with fields:
name
volume
parameter
(4)struct創建結構數組方法之四
a1={'六號房'};a2={'3200立方米'};
green_house_4(2,3)=struct('name',a1,'volume',a2,'parameter',[]);
T6=[31.2,30.4,31.6,28.7;29.7,31.1,30.9,29.6];             green_house_4(2,3).parameter.temperature=T6;           
green_house_4
ans =
2x3 struct array with fields:
name
volume
parameter

4. 3.2 結構數組的操作

MATLAB中專門用於對結構數組的操作的函數並不多,通過 help datatypes獲取數據類型列表,可以看到其中的結構數據類型的有關的函數,主要如表4.3.1所示。
表4.3.1 結構數組的操作函數
函數名   功能描述   函數名   功能描述
deal   把輸入處理成輸出   fieldnames   獲取結構的字段名
getfield   獲取結構中指定字段的值   rmfield   刪除結構的字段(不是字段內容)
setfield   設置結構數組中指定的字段的值   struct   創建結構數組
struct2cell   結構數組轉化成元胞數組   isfield   判斷是否存在該字段
isstruct   判斷某變量是否是結構類型   
下面舉一些具體的例子說明如果對結構數組加以操作。

【例4.3.2-1】 本例目的:一,演示函數fieldnames , getfield , setfield的使用方法;二,讓讀者感受到結構數組對應用工具包的影響;三,演示struct函數把“對象”轉換爲結構的應用。本例爲獲得一個演練的結構,藉助Toolbox control 工具包中的tf函數,先產生一個用傳遞函數描寫的LTI線性時不變2輸入2輸出系統 。
(1)產生2輸入2輸出系統的傳遞函數陣“對象”
Stf=tf({3,2;[4 1],1},{[1 3 2],[1 1 1];[1 2 2 1],[1 0]})

Transfer function from input 1 to output...
3
#1: -------------
s^2 + 3 s + 2

4 s + 1
#2: ---------------------
s^3 + 2 s^2 + 2 s + 1
Transfer function from input 2 to output...
2
#1: -----------
s^2 + s + 1
1
#2: -
s
(2)爲本例演示,把上述的LTI對象Stf轉換爲結構
SSTF=struct(Stf)       % 把對象轉換成結構,並顯示結構的組成
SSTF =
num: {2x2 cell}
den: {2x2 cell}
Variable: 's'
lti: [1x1 lti]
(3)獲得結構數組SSTF的域名
FN=fieldnames(SSTF) % 獲得域名元胞數組FN
class(FN)     % 檢查FN的類別
FN =
'num'
'den'
'Variable'
'lti'
ans =
cell
(4)獲取SSTF.den(2,1)域的內容
FC=getfield(SSTF,'den',{2,1})     % 相當於FC=SSFT.den(2,1)
FC{1}                   % 與celldisp(FC)的作用大致相當
poly2str(FC{1},'s'),         % 爲了把多項式顯示成習慣的形式
FC =
[1x4 double]
ans =
1 2 2 1
ans =
s^3 + 2 s^2 + 2 s + 1
(5)重新設置SSTF.num(2,1)域的內容
SSTF.num{2,1}                 % 顯示原始情況
SSTF=setfield(SSTF,'num',{2,1},{[1 3 1]}); %   注意“花括號”的使用
SSTF.num{2,1}                     % 顯示被重新設置後的情況
ans =
0 0 4 1
ans =
1 3 1

【例4.3.2-2】本例演示結構數組SSTF的擴充和收縮。(本例以例4.3.2-1的運行爲基礎。)
(1)原結構是一個“單結構”
size(SSTF)
ans =
1 1
(2)演示結構的擴充
SSTF(2,2)=struct(tf(1,[1 1]))     % 把1/(s+1)放在第2行第2列結構中
size(SSTF)
SSTF =
2x2 struct array with fields:
num
den
Variable
lti
ans =
2 2
(3)演示結構數組的收縮:刪除結構數組的第1行
SSTF(1,Smile=[]                   % 收縮成爲 的結構
S22n=SSTF(1,2).num,S22d=SSTF(1,2).den   % 取出第2結構num域和den域的內容
printsys(S22n{1},S22d{1})           % 顯示成習慣的表達形式
SSTF =
1x2 struct array with fields:
num
den
Variable
lti
S22n =
[1x2 double]
S22d =
[1x2 double]
num/den =
1
-----
s + 1

【例4.3.2-3】對結構數組進行域的增添和刪減操作。
(1)創建結構數組
clear,for k=1:10;department(k).number=['No.',int2str(k)];end
department
department =
1x10 struct array with fields:
number
(2)增添域:在數組中任何一個結構上進行的域增添操作,其影響遍及整個結構數組
department(1).teacher=40;department(1).student=300;
department(1).PC_computer=40;
department
department =
1x10 struct array with fields:
number
teacher
student
PC_computer
(3)增添子域的操作隻影響被操作的那個具體結構,而不是影響整個結構數組
department(2).teacher.male=35;department(2).teacher.female=13;
D2T=department(2).teacher     % 第2結構teacher域包含兩個子域
D1T=department(1).teacher     % 第1結構teacher域僅是一個數
D2T =
male: 35
female: 13
D1T =
40
(4)刪除子域的操作也隻影響被操作的那個具體結構
department(2).teacher=rmfield(department(2).teacher,'male');
department(2).teacher
ans =
female: 13
(5)刪除域的操作是對整個結構數組實施的
department=rmfield(department,'student')   % 刪除一個域
department =
1x10 struct array with fields:
number
teacher
PC_computer
department=rmfield(department,{'teacher';'PC_computer'})% 刪除2個域
department =
1x10 struct array with fields:
number

【例4.3.2-4】數值運算操作和函數在結構域上的作用。
n_ex = 5; % 結構數組的長度
for k = 1:n_ex,   % 創建1×5結構數組
ex(k).f = (k-1)*n_ex + [1:5];
end;
ex                           % 顯示結構數組的結構
ex =
1x5 struct array with fields:
f
%顯示結構數組的域中內容
disp([blanks(10) '結構域中內容'])
for k=1:n_ex,disp(ex(k).f),end
結構域中內容
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
class(ex(1).f)                   % 檢查域中內容的類型
ans =
double
% 對各結構域中數值數組相應位置的數據相加求和
sum_f=zeros(1,5)
for k=1:n_ex,sum_f=sum_f+ex(k).f;end,sum_f
sum_f =
55 60 65 70 75
% 對結構數組域中各元素分別求平方根
disp([blanks(20) 'ex.f的平方根值'])
for k=1:n_ex,
disp(sqrt(ex(k).f)),
end
ex.f的平方根值
1.0000 1.4142 1.7321 2.0000 2.2361
2.4495 2.6458 2.8284 3.0000 3.1623
3.3166 3.4641 3.6056 3.7417 3.8730
4.0000 4.1231 4.2426 4.3589 4.4721
4.5826 4.6904 4.7958 4.8990 5.0000

【例4.3.2-5】   指令struct2cell和cell2struct的使用。
(1)創建“帶2個域的 結構數組”
for k=1:5,
ex(k).s=['No.' int2str(k)];
ex(k).f=(k-1)*5+[1:5];
end
(2)顯示結構數組的內容
fprintf('%s\n','ex.s域的內容 ');fprintf('%s\',blanks(4))
for k=1:5;fprintf('%s\\',[ex(k).s blanks(1)]);end
fprintf('%s\n',blanks(1)),fprintf('%s\n','ex.f域的內容 ')
for k=1:5;disp(ex(k).f);end     %顯示ex.f域內容
ex.s域的內容
No.1 \No.2 \No.3 \No.4 \No.5 \
ex.f域的內容
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
(3)把ex結構數組轉換爲元胞數組
C_ex=struct2cell(ex); % 帶2個域的(1×5)結構數組轉換爲(2×1×5)元胞數組
size(C_ex)
fprintf('%s\',[C_ex{1,1,1},blanks(3)])   % 顯示C_ex第1頁第1行第1列內容
fprintf('%5g\',C_ex{2,1,1})         % 顯示C_ex第2頁第1行第1列內容
ans =
2 1 5
No.1 1 2 3 4 5
(4)把元胞數組轉換爲結構數組之一
FS={'S_char';'F_num'};        % 用元胞數組預建域名字符串
EX1=cell2struct(C_ex,FS,1)      % 元胞數組向結構數組轉換
EX1 =
1x5 struct array with fields:
S_char
F_numric
EX1(1)                   % 觀察新結構EX1第一結構的情況
ans =
S_char: 'No.1'
F_numric: [1 2 3 4 5]

(5)把元胞數組轉換爲結構數組之二
EX2=cell2struct(C_ex,'xx',2)
EX2 =
2x5 struct array with fields:
xx
(6)把元胞數組轉換爲結構數組之三
YY=strvcat('y1','y2','y3','y4','y5');EX3=cell2struct(C_ex,YY,3)
EX3 =
2x1 struct array with fields:
y1
y2
y3
y4
y5
EX3(1)                   % 觀察第一結構情況
ans =
y1: 'No.1'
y2: 'No.2'
y3: 'No.3'
y4: 'No.4'
y5: 'No.5'
EX3(2)                   % 觀察第二結構情況
ans =
y1: [1 2 3 4 5]
y2: [6 7 8 9 10]
y3: [11 12 13 14 15]
y4: [16 17 18 19 20]
y5: [21 22 23 24 25]

【例4.3.2-6】   帶子域的結構數組轉換爲元胞數組。本例中的ex結構數組由例4.2.2-5生成,然後再運行以下程序。
ex(1,1).s                 % 原結構ex(1,1).s中的內容
ans =
No.1
% 增設子域,並把ex結構數組擴充爲(3×5)。
ex(1,1).s.sub='SUB 1';         % 原ex(1,1).s中的字符串將因本指令而消失
ex(3,1).s.sub='SUB 3';
ex(3,1).s.num=1/3;
ex(1,1).s                 % 經新賦值後,ex(1,1).s中的內容
ans =
sub: 'SUB 1'
ex(3,1).s                 % 經新賦值後,ex(3,1).s中的內容
ans =
sub: 'SUB 3'
num: 0.3333
C_ex_sub=struct2cell(ex)       % 把結構轉換爲元胞數組
C_ex_sub(:,:,1) =
[1x1 struct] [] [1x1 struct]
[1x5 double] [] []
C_ex_sub(:,:,2) =
'No.2' [] []
[1x5 double] [] []
C_ex_sub(:,:,3) =
'No.3' [] []
[1x5 double] [] []
C_ex_sub(:,:,4) =
'No.4' [] []
[1x5 double] [] []
C_ex_sub(:,:,5) =
'No.5' [] []
[1x5 double] [] []
size(C_ex_sub)             % 觀察新元胞數組的大小
ans =
2 3 5
C_ex_sub{1,1,1}             % 觀察第一元胞中的內容
ans =
sub: 'SUB 1'
C_ex_sub{1,3,1}             % 觀察(1,3,1)元胞中的內容
ans =
sub: 'SUB 3'
num: 0.3333
發佈了23 篇原創文章 · 獲贊 106 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章