結構體(struct)的使用
結構體在很多場合中非常常用,可以將若干個不同的數據類型的變量或數組封裝在一起,一存儲自定義的數據結構,方便存儲一些復合數據。
結構體的定義
定義一個結構體的基本格式如下
struct Name{
//一些基本的數據結構或者自定義的數據類型
}
例如,需要存儲一個學生的學號、性別、姓名和專業,就可以這樣定義:
struct studentInfo{
int id;
char gender;//'F'or'M'
char name[20];
char major[20];
}Alice,Bob,stu[1000];
其中studentInfo是結構體的名字,內部定義了id(學號)、gender(性別)、name(名字)和major(專業)。而大括號外定義了studentInfo型的Alice和Bob代表兩個結構體變量;之后的stu[1000]就是當有很多學生時定義的一個結構體數組(如果不在此處定義變量或數組,則大括號外直接跟上分號)
結構體也可以按照基本數據類型那樣定義
studentInfo Alice;
studentInfo stu[1000];
需要注意的是,結構體里面能定義除了自己本身(這樣會引起循環定義的問題)之外的任何數據類型。不過雖然不能定義自己本身,但是可以定義自身類型的指針變量。例如:
struct node{
node n;//不能定義node型變量
node* next;//可以定義node*類型的指針變量
}
訪問結構體內的元素
兩種方法:“.”操作和“->”操作。現在把studentInfo類型定義成下面這樣:
struct studentIfo{
int id;
char name[20];
studentInfo* next;
}stu, *p;
這樣studentInfo中多了一個指針next來指向下一個學生的地址,且結構體變量中定義了普通類型變量stu和指針變量p。
於是訪問stu中變量的寫法如下:
stu.id
stu.name
stu.next
訪問指針變量p中元素的寫法如下:
(*p).id
(*p).name
(*p).next
另一種訪問結構體指針變量內元素的更簡潔的寫法:
p->id
p->name
p->next
使用*或->訪問結構體指針變量內元素的寫法是完全等價的。
結構體的初始化
使用“構造函數”的方法來進行初始化。所謂構造函數就是用來初始化結構體的一種函數,它直接定義在結構體中。構造函數的一個特點就是它不需要寫返回類型,且函數名與結構體名相同
一般對於一個普通定義的結構體,其內部會生成一個默認的構造函數(但是不可見)
struct studentInfo{
int id;
char gender;
//默認生成的構造函數
studentInfo(){}//沒有返回類型,沒有參數,沒有函數體
};
那么,如果想要自己手動提供id和gender的初始化參數,要怎么做?需要提供初始化參數來對結構體內部的變量進行賦值
struct studentInfo{
int id;
char gender;
//把下面參數用以對結構體內部變量進行賦值
studentInfo(int _id, char _gender){
//賦值
id = _id;
gender = _gender;
}
}
其中 _ id和 _ gender都是變量名,只要不和已有變量名沖突就行。
構造函數也可以簡化成一行
x struct studentInfo{
int id; char gender;
studentInfo(int _id, char _gender):id(_id), gender(_gender) {}
}
這樣可以在需要時直接對結構體變量進行賦值了:
studentInfostu = studentIfo(10086, 'M')
注意:如果自己重新定義了構造函數,就不能不經初始化就定義結構體變量。為了既能不初始化就定義結構體變量,又能享受初始化帶來的便捷。我們可以吧studentInfo(){}手動加上。這意味着,只要參數個數和類型不完全相同,就可以定義任意多個構造函數,以適應不同的初始化場合。實例:
struct studentIfo{
int id;
char gender;
//可以不初始化就定義結構體變量
studentInfo(){}
//只初始化gender
studentInfo(char _gender){
gender = _gender;
}
//同時初始化gender和id
studentIfo(int _id, char _gender){
id = _id;
char = _char;
}
};