结构体

  C++是C语言的继承,它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计。

  在C语言中,结构体是一种数据结构,是C语言中聚合数据类型的一类。结构体可以被声明为变量、指针和数组等,用以实现较复杂的数据结构。结构体同时也是一些元素的集合,这些元素称为结构体的成员,且这些成员可以为不同的类型,成员一般用名字访问。

  C++提供了许多种基本的数据类型(如int、float、double、char等)供用户使用。但是由于程序需要处理的问题往往比较复杂,而且呈多样化,已有的数据类型显得不能满足使用要求。因此C++允许用户根据需要自己声明一些类型,用户可以自己声明的类型还有结构体类型(structure)、共用体类型(union)、枚举类型(enumeration)、类类型(class )等,这些统称为用户自定义类型(user-defined type,UDT)。 

  在一个组合项中包含若干个类型不同(当然也可以相同)的数据项。C和C++允许用户自己指定这样一种数据类型,它称为结构体。它相当于其他高级语言中的记录(record)。
  例如,可以通过下面的声明来建立结构体数据类型。
struct Student      //声明一个结构体类型Student
{
int num;          //包括一个整型变量num
char name[20];         //包括一个字符数组name,可以容纳20个字符
char sex;          //包括一个字符变量sex
float score;        //包括一个单精度型变量
};              //最后有一个分号
  这样,程序设计者就声明了一个新的结构体类型Student(struct是声明结构体类型时所必须使用的关键字,不能省略),它向编译系统声明: 这是一种结构体类型,它包括num, name, sex, score等不同类型的数据项。上面的声明中Student就是结构体类型名。大括号内是该结构体中的全部成员(member),由它们组成一个特定的结构体。在声明一个结构体类型时必须对各成员都进行类型声明即类型名成员名;每一个成员也称为结构体中的一个域(field)。成员表列又称为域表。
  应当说明Student是一个类型名,它和系统提供的标准类型(如int、char、float、double 一样,都可以用来定义变量,只不过结构体类型需要事先由用户自己声明而已。
  结构体相当于一个模型,其中并无具体数据,系统不为之分配实际的内存单元。只有定义了结构体变量,系统才会为之分配内存单元
(1)先声明结构体类型再定义变量名如上面已定义了一个结构体类型Student,可以用它来定义结构体变量。如
struct Student student1, student2;

以上定义了两个结构体变量:student1和student2。它们在内存中各占29个字节:4+20+1+4=29。

  但是这里需要注意:名义上计算大小为29,根据不同编译器,内存存储会有所不同.在存储该结构体时会按照内存对齐进行相关处理,系统默认对齐系数为4(即按int类型对齐,粗略认识可以认为每相邻两个数据成员存储是大小是4的整数倍,请参考下面对比结构体),详情请参考内存对齐,因此该结构体实际大小为:32,具体计算如下:
{
int num;//整型,4个字节
char name[20];//字符数组20个字节,4的整数倍,取20字节
char sex;//字符类型,一个字节,往下不能凑齐4个字节,因此取4个字节
float score;//4个字节
}  
故实际大小为:4+20+4+4=32
 
(2) 在声明类型的同时定义变量
struct Student   //声明一个结构体类型Student
{
int num;      //包括一个整型变量num
char name[20];        //包括一个字符数组name,可以容纳20个字符
char sex;       //包括一个字符变量sex
float score;      //包括一个单精度型变量
}student1,student2; //定义两个结构体类型Student的变量student1,student2
这种形式的定义的一般形式为
struct 结构体名
{
成员表列
}变量名列表;
(3) 直接定义结构体类型变量
其一般形式为
struct  //注意没有结构体类型名
{
成员表列
} 变量名表列;
  这种方法虽然合法,但很少使用。提倡先定义类型后定义变量的第(1)种方法。在程序比较简单,结构体类型只在本文件中使用的情况下,也可以用第(2)种方法。 
 
关于结构体类型,有几点要说明:
(1) 不要误认为凡是结构体类型都有相同的结构。实际上,每一种结构体类型都有自己的结构,可以定义出许多种具体的结构体类型。
(2) 类型与变量是不同的概念,不要混淆。只能对结构体变量中的成员赋值,而不能对结构体类型赋值。在编译时,是不会为类型分配空间的,只为变量分配空间。
(3) 对结构体中的成员(即“域”),可以单独使用,它的作用与地位相当于普通变量。
(4) 成员也可以是一个结构体变量。
(5) 结构体中的成员名可以与程序中的变量名相同,但二者没有关系。
 
初始化:对结构体变量可以在定义时指定初始值
struct Student
{
int num;
char name[20];
char sex;
float score;
}student1={10001,"Zhang Xin",'M',90.5};
也可以采取声明类型与定义变量分开的形式,在定义变量时进行初始化
student2= student1;
 
变量:
(1) 可以将一个结构体变量的值赋给另一个具有相同结构的结构体变量。
例:student1= student2;
(2) 可以引用一个结构体变量中的一个成员的值。
例:student1.num表示结构体变量student1中的成员的值。(引用结构体变量中成员的一般方式为:结构体变量名.成员名)
(3) 如果成员本身也是一个结构体类型,则要用若干个成员运算符,一级一级地找到最低一级的成员。
(4) 不能将一个结构体变量作为一个整体进行输入和输出,只能对结构体变量中的各个成员分别进行输入和输出。
(5) 对结构体变量的成员可以像普通变量一样进行各种运算(根据其类型决定可以进行的运算种类)。
  由于“.”运算符的优先级最高,student1.age++相当于(student1.age)++ 。
(6) 可以引用结构体变量成员的地址,也可以引用结构体变量的地址。
  cout<<&student1;//输出student1的首地址
  cout<<&student1.age;//输出student1.age的地址
  结构体变量的地址主要用作函数参数,将结构体变量的地址传递给形参。
 
指针:一个结构体变量的指针就是该变量所占据的内存段的起始地址。可以设一个指针变量,用来指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址。
① 结构体变量.成员名。如stu.num。
② (*p).成员名。如(*p).num。
③ p->成员名。如p->num。含义是得到P指向的结构体变量的成员num的值。其中“->”称为指向运算符。
p->n++ 得到p指向的结构体变量中的成员n的值,用完该值后使它加1。
++p->n 得到p指向的结构体变量中的成员n的值,并使之加1,然后再使用它。
 
  在C语言中,结构体的成员只能是数据(如上面例子中所表示的那样)。C++中结构体的成员既可以包括数据(即数据成员),又可以包括函数(即函数成员),以适应面向对象的程序设计。

基本用在很多数据,需要一个结构体来封装这些数据。而类的话,是面向对象的思想,可以有很多接口让人调用,私有变量等外部不能调用,还有保护类型的变量。

结构体也可以被认为是一种特殊的类,它不存在任何函数,构造和析构函数也没有,而且是一个公共的的类。

结构体在默认情况下成员是公共的(public),类在默认情况下成员是私有的(private)。

C++结构体内部成员变量及成员函数默认的访问级别是public,而c++类的内部成员变量及成员函数的默认访问级别是private。

C++结构体的继承默认是public,而c++类的继承默认是private。

类要加上public变成共有的才能被访问,而结构本身就是共有的可直接访问。

C定义结构体变量时需要加struct关键字,C++中定义结构体变量时可以不加struct关键字。

原文地址:https://www.cnblogs.com/ST-2017/p/11346427.html