結(jié)構(gòu)體(struct)是由一系列具有相同類型或不同類型的數(shù)據(jù)構(gòu)成的數(shù)據(jù)集合,叫做結(jié)構(gòu)。
在C語言中,結(jié)構(gòu)體(struct)指的是一種數(shù)據(jù)結(jié)構(gòu),是C語言中聚合數(shù)據(jù)類型(aggregate data type)的一類。結(jié)構(gòu)體可以被聲明為變量、指針或數(shù)組等,用以實現(xiàn)較復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。結(jié)構(gòu)體同時也是一些元素的集合,這些元素稱為結(jié)構(gòu)體的成員(member),且這些成員可以為不同的類型,成員一般用名字訪問。
結(jié)構(gòu)體定義
結(jié)構(gòu)體的定義如下所示,struct為結(jié)構(gòu)體關(guān)鍵字,tag為結(jié)構(gòu)體的標(biāo)志,member-list為結(jié)構(gòu)體成員列表,其必須列出其所有成員;variable-list為此結(jié)構(gòu)體聲明的變量。
struct tag {
member-list
} variable-list ;
在一般情況下,tag、member-list、variable-list這3部分至少要出現(xiàn)2個。以下為示例:
//此聲明聲明了擁有3個成員的結(jié)構(gòu)體,分別為整型的a,字符型的b和雙精度的c
//同時又聲明了結(jié)構(gòu)體變量s1
//這個結(jié)構(gòu)體并沒有標(biāo)明其標(biāo)簽
struct {
int a;
char b;
double c;
} s1;
//同上聲明了擁有3個成員的結(jié)構(gòu)體,分別為整型的a,字符型的b和雙精度的c
//結(jié)構(gòu)體的標(biāo)簽被命名為SIMPLE,沒有聲明變量
struct SIMPLE{
int a;
char b;
double c;
};
//用SIMPLE標(biāo)簽的結(jié)構(gòu)體,另外聲明了變量t1、t2、t3
struct SIMPLE t1, t2[20], *t3;
//也可以用typedef創(chuàng)建新類型
typedef struct{
int a;
char b;
double c;
} Simple2;
//現(xiàn)在可以用Simple2作為類型聲明新的結(jié)構(gòu)體變量
Simple2 u1, u2[20], *u3;
在上面的聲明中,第一個和第二聲明被編譯器當(dāng)作兩個完全不同的類型,即使他們的成員列表是一樣的,如果令t3=&s1,則是非法的。
定義結(jié)構(gòu)變量的方法
1、先定義結(jié)構(gòu),再說明結(jié)構(gòu)變量。
例如:
struct?stu
{
int num;
char name[20];
int age;
};
struct stu boy1,boy2;
說明了兩個變量boy1和boy2為stu結(jié)構(gòu)類型。
也可以用宏定義使一個符號常量來表示一個結(jié)構(gòu)類型, 例如:
#define STU struct stu
STU
{
int num;
char name[20];
int age;
};
STU boy1,boy2;
2、在定義結(jié)構(gòu)類型的同時說明結(jié)構(gòu)變量。
例如:
struct?stu
{
int num;
char name[20];
int age;
}boy1,boy2;
3、直接說明結(jié)構(gòu)變量。
例如:
struct
{
int num;
char name[20];
int age;
}boy1,boy2;
第三種方法與第二種方法的區(qū)別在于第三種方法中省去了結(jié)構(gòu)名,而直接給出結(jié)構(gòu)變量。
說明了boy1,boy2變量為stu類型后,即可向這兩個變量中的各個成員賦值。
在上述stu結(jié)構(gòu)定義中,所有的成員都是基本數(shù)據(jù)類型或數(shù)組類型。成員也可以又是一個結(jié)構(gòu), 即構(gòu)成了嵌套的結(jié)構(gòu)。
使用結(jié)構(gòu)變量成員的一般形式是:
結(jié)構(gòu)變量名。成員名
例如:
boy1.num
/*即第一個人的學(xué)號 */
如果成員本身又是一個結(jié)構(gòu)則必須逐級找到最低級的成員才能使用。
例如:boy1.birthday.month
即第一個人出生的月份成員可以在程序中單獨(dú)使用,與普通變量完全相同。
結(jié)構(gòu)體初始化
1、結(jié)構(gòu)體的構(gòu)造函數(shù)中初始化
在C++中,結(jié)構(gòu)體與類在使用上已沒有本質(zhì)上的區(qū)別了,所以可以使用構(gòu)造函數(shù)來初始化。如下代碼所示:
struct Stu
{
int nNum;
bool bSex;
char szName[20];
char szEmail[100];
//構(gòu)造函數(shù)初始化
Stu()
{
nNum = 0;
bSex = false;
memset(szName,0,sizeof(szName));
memset(szEmail,0,sizeof(szEmail));
}
};
你可能已經(jīng)發(fā)現(xiàn)了,如果結(jié)構(gòu)體中有大量成員,一個個賦值,相當(dāng)麻煩。那么你可以這樣寫:
struct Stu
{
int nNum;
bool bSex;
char szName[20];
char szEmail[100];
//構(gòu)造函數(shù)初始化
Stu()
{
memset(this,0,sizeof(Stu));
//或者是下面的格式
//memset(&nNum,0,sizeof(Stu));
}
};
如果在結(jié)構(gòu)體中分配了指針,并且指針指向一個堆內(nèi)存,那么就在析構(gòu)函數(shù)中釋放。以上便是在構(gòu)造函數(shù)中初始化。
2、繼承模板類初始化。
首先定義一個模板基類:
template 《typename T》
class ZeroStruct
{
public:
ZeroStruct()
{
memset(this,0,sizeof(T));
}
};
之后定義的結(jié)構(gòu)體都繼承于此模板類。
struct Stu:ZeroStruct《Stu》
{
int nNum;
bool bSex;
char szName[20];
char szEmail[100];
};
這樣也能實現(xiàn)初始化。
3、定義時初始化。
struct Stu
{
int nNum;
bool bSex;
char szName[20];
char szEmail[100];
};
//定義時初始化
Stu stu1 = {0};
在有的結(jié)構(gòu)體中,第一個成員表示結(jié)構(gòu)體的大小,那么就可以這樣初始化:
struct Stu
{
int nSize; //結(jié)構(gòu)體大小
int nNum;
bool bSex;
char szName[20];
char szEmail[100];
};
Stu stu1 = {sizeof(Stu),0};
后面的0,可以省略掉,直接寫成:Stu stu1 = {sizeof(Stu)};后面自動會用0填充。
關(guān)于結(jié)構(gòu)體的類型要注意的幾點(diǎn):
(1)類型與變量是不同的概念,不要混淆。只能對結(jié)構(gòu)體變量中的成員賦值,而不能對結(jié)構(gòu)體類型賦值。
?。?)對結(jié)構(gòu)體變量中的成員(即“域”),可以單獨(dú)使用,它的作用與地位相當(dāng)于同類型的普通變量。
(3)結(jié)構(gòu)體的成員也可以是一個結(jié)構(gòu)體變量。
結(jié)構(gòu)變量的賦值
你可對結(jié)構(gòu)體變量的成員逐個賦值,這種方式和數(shù)組相像,數(shù)組就是逐個元素逐一賦值(對于數(shù)組,除非初始化,否則你別無選擇,只能這樣賦值)。不同于數(shù)組,標(biāo)準(zhǔn)C中結(jié)構(gòu)體變量可以整體賦值。
例一:
#include 《stdio.h》
int main(void)
{
struct student
{
long int num;
int age;
char* name;
}st1={200,18,“zhangsan”};
struct student st2,st3;
printf(“ NO. age name /n”);
printf(“ %ld %d %s/n”,st1.num,st1.age,st1.name);
getch();
st2.num=199;
st2.age=19;
st2.name=“l(fā)isi”;
printf(“ %ld %d %s/n”,st2.num,st2.age,st2.name);
getch();
st3=st2;
printf(“ %ld %d %s/n”,st3.num,st3.age,st3.name);
getch();
printf(“/n/n struct student:%d”,sizeof(struct student));
getch();
return 0;
}
例二:
#include 《stdio.h》
#include 《conio.h》
struct birth
{
int year;
int month;
int day;
};
struct student
{
long int num;
struct birth birthday;
char* name;
}st1={200,{1988,8,8},“zhangsan”};
int main(void)
{
struct student st2;
st2=st1;
printf(“ %ld %s %d/n”,st2.num,st2.name,sizeof(int));
printf(“ year: %d month: %d month: %d/n”,
st2.birthday.year,
st2.birthday.month,
st2.birthday.day);
getch();
return 0;
}
注意
當(dāng)你的結(jié)構(gòu)體變量中有存放多個字符的成員,建議你將它定義為數(shù)組(比如前面的姓名成員,不知道數(shù)組該開辟多大時,也可以定義為指針)。原因是指針變量不能存放實際數(shù)據(jù),僅僅是地址。
評論
查看更多