詳解C++中的指針構造體數組和指向構造體變量的指針。本站提示廣大學習愛好者:(詳解C++中的指針構造體數組和指向構造體變量的指針)文章只能為提供參考,不一定能成為您想要的結果。以下是詳解C++中的指針構造體數組和指向構造體變量的指針正文
C++構造體數組
一個構造體變量中可以寄存一組數據(如一個先生的學號、姓名、成就等數據)。假如有10個先生的數據須要加入運算,明顯應當用數組,這就是構造體數組。構造體數組與之前引見過的數值型數組的分歧的地方在於:每一個數組元素都是一個構造體類型的數據,它們都分離包含各個成員項。
界說構造體數組和界說構造體變量的辦法相仿,界說構造體數組時只需聲明其為數組便可。如:
struct Student //聲明構造體類型Student { int num; char name[20]; char sex; int age; float score; char addr[30]; }; Student stu[3]; //界說Student類型的數組stu
也能夠直接界說一個構造體數組,如:
struct Student { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu[3];
或
struct { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu[3];
構造體數組的初始化與其他類型的數組一樣,對構造體數組可以初始化。如:
struct Student { int num; char name[20]; char sex; int age; float score; char addr[30]; }stu[3]={ {10101,″Li Lin″, ′M′, 18,87.5, ″103 Beijing Road″}, {10102,″Zhang Fun″,′M′,19,99, ″130 Shanghai Road″}, {10104,″Wang Min″,′F′, 20,78.5, ″1010 Zhongshan Road″} };
界說數組stu時,也能夠不指定元素個數,即寫成以下情勢:
stu[ ]={{…},{…},{…}};
編譯時,體系會依據給出初值的構造體常量的個數來肯定數組元素的個數。一個構造體常量應包含構造體中全體成員的值。
固然,數組的初始化也能夠用以下情勢:
Student stu[ ]={{…},{…},{…}}; //已事前聲清楚明了構造體類型Student
由上可以看到,構造體數組初始化的普通情勢是在所界說的數組名的前面加上 ={初值表列};
構造體數組運用舉例
上面舉一個簡略的例子來講明構造體數組的界說和援用。
【例】對候選人得票的統計法式。設有3個候選人,終究只能有1人被選為引導。今有10小我加入投票,從鍵盤前後輸出這10小我所投的候選人的名字,請求最初輸入這3個候選人的得票成果。
可以界說一個候選人構造體數組,包含3個元素,在每一個元素中寄存有關的數據。法式以下:
#include <iostream> using namespace std; struct Person //聲明構造體類型Person { char name[20]; int count; }; int main( ) { //界說Person類型的數組,內容為3個候選人的姓名和以後的得票數 Person leader[3]={"Li",0,"Zhang",0,"Fun",0}; int i,j; char leader_name[20]; //leader_name為投票人所選的人的姓名 for(i=0;i<10;i++) { cin>>leader_name; //前後輸出10張票上所寫的姓名 for(j=0;j<3;j++) //將票上姓名與3個候選人的姓名比擬 //假如與某一候選人的姓名雷同,就給他加一票 if(strcmp(leader_name,leader[j].name)==0) leader[j].count++; } cout<<endl; for(i=0;i<3;i++) //輸入3個候選人的姓名與最初得票數 { cout<<leader[i].name<<":"<<leader[i].count<<endl; } return 0; }
運轉情形以下:
Zhang↙ (每次輸出一個候選人的姓名) Li↙ Fun↙ Li↙ Zhang↙ Li↙ Zhang↙ Li↙ Fun↙ Wang↙ Li:4 (輸入3個候選人的姓名與最初得票數) Zhang:3 Fun:2
法式界說一個全局的構造體數組leader,它有3個元素,每元素包括兩個成員,即name(姓名)和count(得票數)。在界說數組時使之初始化,使3位候選人的票數都先置零。
在這個例子中,也能夠不消字符數組而用string辦法的字符串變量來寄存姓名數據,法式可修正以下:
#include <iostream> #include <string> using namespace std; struct Person { string name;//成員name為字符串變量 int count; }; int main( ) { Person leader[3]={"Li",0,"Zhang",0,"Fun",0}; int i,j; string leader_name;// leader_name為字符串變量 for(i=0;i<10;i++) { cin>>leader_name; for(j=0;j<3;j++) if(leader_name==leader[j].name) leader[j].count++//用“==”停止比擬 } cout<<endl; for(i=0;i<3;i++) { cout<<leader[i].name<<":"<<leader[i].count<<endl; } return 0; }
運轉情形與前雷同。明顯後一個法式節儉內存空間,應用更便利,易讀性更好。然則 有些C++體系不克不及對包括string成員的構造體變量初始化,須要作一些修正能力運轉, 讀者可上機試一下。
C++指向構造體變量的指針
一個構造體變量的指針就是該變量所占領的內存段的肇端地址。可以設一個指針變量,用來指向一個構造體變量,此時該指針變量的值是構造體變量的肇端地址。指針變量也能夠用來指向構造體數組中的元素。
經由過程指向構造體變量的指針援用構造體變量中的成員
上面經由過程一個簡略例子來講明指向構造體變量的指針變量的運用。
【例】指向構造體變量的指針的運用。
#include <iostream> #include <string> using namespace std; int main( ) { struct Student//聲明構造體類型student { int num; string name; char sex; float score; }; Student stu;//界說Student類型的變量stu Student *p=&stu;//界說p為指向Student類型數據的指針變量並指向stu stu.num=10301;//對stu中的成員賦值 stu.name="Wang Fun";//對string變量可以直接賦值 stu.sex='f'; stu.score=89.5; cout<<stu. num<<" "<<stu.name<<" "<<stu.sex<<" "<< stu.score<<endl; cout<<p -> num<<" "<<(*p).name<<" "<<(*p).sex<<" "<<(*p).score<<endl; return 0; }
法式運轉成果以下:
10301 Wang Fun f 89.5 (經由過程構造體變量名援用成員)
10301 Wang Fun f 89.5 (經由過程指針援用構造體變量中的成員)
兩個cout語句輸入的成果是雷同的。
為了應用便利和使之直不雅,C++供給了指向構造體變量的運算符->,例如p->num表現指針p以後指向的構造體變量中的成員num。
p->num 和(*p).num等價。
異樣
p->name等價於(*p).name。
也就是說,以下3種情勢等價:
構造體變量.成員名。如stu.num。
(*p).成員名。如(*p).num。
p->成員名。如p->num。
“->”稱為指向運算符。
請剖析以下幾種運算:
用構造體變量和指向構造體變量的指針組成鏈表
鏈表是一種罕見的主要的數據構造。下圖表現最簡略的一種鏈表(單向鏈表)的構造。
鏈表有一個“頭指針”變量,圖中以head表現,它寄存一個地址。該地址指向一個元素。鏈表中的每個元素稱為“結點”,每一個結點都應包含兩個部門:
一是用戶須要用的現實數據,
二是下一個結點的地址。
可以看到鏈表中各元素在內存中的存儲單位可所以不持續的。要找某一元素,可以先找到上一個元素,依據它供給的下一元素地址找到下一個元素。
可以看到,這類鏈表的數據構造,必需應用構造體變量和指針能力完成。
可以聲明一個構造體類型,包括兩種成員,一種是用戶須要用的現實數據,另外一種是用來寄存下一結點地址的指針變量。
例如,可以設計如許一個構造體類型:
struct Student { int num; float score; Student *next; //next指向Student構造體變量 };
個中成員num和score是用戶須要用到的數據,相當於圖7.8結點中的A, B, C, D。next是指針類型的成員,它指向Student類型數據(就是next地點的構造體類型)。用這類辦法便可以樹立鏈表。見圖。
圖中每個結點都屬於Student類型,在它的成員next中寄存下一個結點的地址,法式設計者不用曉得各結點的詳細地址,只需包管能將下一個結點的地址放到前一結點的成員next中便可。
上面經由過程一個例子來講明若何樹立和輸入一個簡略鏈表。
【例】樹立一個如圖所示的簡略鏈表,它由3個先生數據的結點構成。輸入各結點中的數據。
#define NULL 0 #include <iostream> using namespace std; struct Student { long num; float score; struct Student *next; }; int main( ) { Student a,b,c,*head,*p; a. num=31001; a.score=89.5; //對結點a的num和score成員賦值 b. num=31003; b.score=90; //對結點b的num和score成員賦值 c. num=31007; c.score=85; //對結點c的num和score成員賦值 head=&a; //將結點a的肇端地址賦給頭指針head a.next=&b; //將結點b的肇端地址賦給a結點的next成員 b.next=&c; //將結點c的肇端地址賦給b結點的next成員 c.next=NULL; //結點的next成員不寄存其他結點地址 p=head; //使p指針指向a結點 do { cout<<p->num<<" "<<p->score<<endl; //輸入p指向的結點的數據 p=p->next; //使p指向下一個結點 } while (p!=NULL); //輸入完c結點後p的值為NULL return 0; }
本例是比擬簡略的,一切結點(構造體變量)都是在法式中界說的,不是暫時開拓的,也不克不及用完後釋放,這類鏈表稱為靜態鏈表。對各結點既可以經由過程上一個結點的next指針去拜訪,也能夠直接經由過程構造體變量名a, b, c去拜訪。
靜態鏈表則是指各結點是可以隨時拔出和刪除的,這些結點並沒有變量名,只能先找到上一個結點,能力依據它供給的下一結點的地址找到下一個結點。只要供給第一個結點的地址,即頭指針head,能力拜訪全部鏈表。好像一條鐵鏈一樣,一環扣一環,中央是不克不及斷開的。
樹立靜態鏈表,要用到前面引見的靜態分派內存的運算符new和靜態撤消內存的運算符delete。