C++ 结构体struct

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yyl424525/article/details/89326086

1.C++中结构体与类的区别

在C语言中,结构体不能包含函数。C++中的struct对C中的struct进行了扩充,它已经不再只是一个包含不同数据类型的数据结构了,它已经获取了太多的功能。
struct能包含成员函数;struct能继承;struct能实现多态等 。既然这些它都能实现,那它和class还能有什么区别呢?
最本质的一个区别就是默认的访问控制:默认的继承访问权限。struct是public的,class是private的。

struct A
{
  char a;
};
struct B : A
{
  char b;
};

这个时候B是public继承A的。
如果都将上面的struct改成class,那么B是private继承A的。这就是默认的继承访问权限。
所以我们在平时写类继承的时候,通常会这样写:
class B : public A
就是为了指明是public继承,而不是用默认的private继承。

当然,到底默认是public继承还是private继承,取决于子类而不是基类。 struct可以继承class,同样class也可以继承struct,那么默认的继承访问权限是看子类到底是用的struct还是class。如下:
struct A{};class B : A{}; //private继承
struct C : B{}; //public继承

struct作为数据结构的实现体,它默认的数据访问控制是public的,而class作为对象的实现体,它默认的成员变量访问控制是private的。

当然,在这里还要强调一点的就是,对于访问控制,应该在程序里明确的指出,而不是依靠默认,这是一个良好的习惯,也让代码更具可读性。

其他区别:
(1)“class”这个关键字还用于定义模板参数,就像“typename”。但关键字“struct”不用于定义模板参数。
(2)C++ 中的struct是对C中的struct的扩充,既然是扩充,那么它就要兼容过去C中struct应有的所有特性。也就是说struct可以在定义的时候用{}赋初值,而class不行。因为将struct改成class的时候,访问控制由public变为 private了,那当然就不能用{}来赋初值了。

struct A //定义一个struct
{
   char c1;
   int n2;
   double db3;
};
A a={'p', 7, 3.1415926}; //定义时直接赋值 

事实上,是因为加入这样的函数,使得类的内部结构发生了变化。向上面的struct中加入一个构造函数(或虚函数),可以发现struct也不能用{}赋初值,但加入一个普通函数,仍然可以用{}赋值。事实上,是因为加入构造函数(或虚函数)这样的函数,使得类的内部结构发生了变化。 那么,看到这里,我们发现即使是struct想用{}来赋初值,它也必须满足很多的约束条件,这些条件实际上就是让struct更体现出一种数据机构而不是类的特性。

总结:到底是用struct还是class,完全看个人的喜好,你可以将程序里所有的class全部替换成struct,它依旧可以很正常的运行。从上面的区别,我们可以看出,struct更适合看成是一个数据结构的实现体,class更适合看成是一个对象的实现体。

2.定义、声明、初始化

#include <iostream>    //引用库函数
using namespace std; //使用命名空间
//定义一个名为inflatable的结构体
struct inflatable
{
    char name[20];
    float volume;
    double price;
};

//定义一个没有名字的结构体的同时,声明了两个该类型的变量stud1,stud2.每个变量的其中一个成员也是一个结构体inflatable.
struct {
    int num;
    char sex;
    inflatable inf;
}stud1,stud2;

//定义一个名字为student的结构体的同时,声明了两个该类型的变量stud1,stud2.每个变量的其中一个成员也是一个结构体inflatable.
struct student{
    int num;
    char sex;
    inflatable inf;
}stud3,stud4;

int main()           //主函数,程序执行的入口
{ 
//声明一个结构体变量并作初始化
inflatable in1={"Li Ming",2.0,9};
//定义结构体数组的同时初始化
inflatable guests[2]={
        {"Bambi",0.5,21.55},
        {"Goodzilla",2000,654.214}
    };
return 0;
}

3.结构体与函数

结构型数据的成员作为函数的参数
考虑下面的结构体

struct student{
    int num;
    char sex;
    char name[20];
    float score;
}stud;

假设有若干函数,其函数原型为:

void f1(int);
void f2(float);
void f3(char *);

那么下面的函数调用是合法的:

f1(stud.num);
f2(stud.socre);
f3(stud.name);//传递数组stud.name的值,即第一个元素的地址
f1(stud.name[2]);

如果要将结构型数据的成员的地址传递给函数,就必须在表示结构成员的表达式前使用取地址运算符&;同时,函数的形参也应该是指针类型或者数组类型。例如,假设另有两个函数的原型如下:
void f4(int *);
void f5(float *);
那么,下面的调用形式是正确的:

f3(stud.name);//传递数组stud.name的值,即第一个元素的地址
f3(&stud.name[2]);//传递数组stud.name[2]的地址
f4(&stud.num);//传递成员stud.num的地址
f5(&stud.score);

注:运算符&放在结构型数据名前,而不是放在成员名之前。数组名name本身就是数组的首地址,相应的结构名前不需要使用&。

结构型数据作为函数的参数或返回值
一般情况下,由于结构体变量的成员较多,占用内存也较多,传送时需要消耗大量时间和空间,不建议使用值传递的方式。
常用的方法是采用引用传递或者传递指针参数。采用这两种方法,不需要对实参的成员进行复制,仅传递结构的地址,占用内存少,调用速度快,具有较高的效率。
例如,函数原型为:

void f7(student &s);
void f8(student *s);

相应的调用形式为:

f7(stud);
f8(&stud);

结构体也可以作为函数的返回值,例如:

student * func1(void);//返回函数指针
student func2(void);//返回结构体类型变量

4.结构体与数组

定义结构体数组
和定义结构体变量类似,定义结构体数组时只需声明其为数组即可。如:

struct Student{
     int num;
     char name[20];
     char sex[5];
     int age;
     float score;
};
Student stu[3]; //定义Student类型的数组stu

//或在定义结构体的同时声明数组
struct Student{
...
}stu[3];

//声明的同时还可以初始化
struct Student{
     int num;
     char name[20];
     char sex[5];
     int age;
     float score;
}stu[2]={
{110,"Zhang",'M',24,90},
{111,"Li",'M',23,93}
};

假设有两个函数,其原型如下:

void display(const Student[],int);  
void sortArray(Student[],int); 

上述两个函数都可以接收结构体数组,其中display函数的形参是const类型,只是访问而不修改实参结构体数组,而sortArray函数会修改实参。

5.结构体与指针

结构体指针(结构指针)
结构指针是指指向一个结构体变量的指针。
例如,定义一个结构体指针pStud,并让它指向结构体stud:

Student * pStud,stud;
pStud=&stud;

有了结构体指针,就可以用它方便地访问它所指向的结构变量的各个成员。下面三种访问形式等效:

//结构体指针对结构体中元素的访问需要用“->”访问
pStud->num;
//结构体变量用“.”访问相应的结构体元素
(*pStud).num;
stud.num;

结构数组与指向结构的指针
结构指针可指向结构体数组,它的值是该结构体数组的首地址。假设ps为指向结构体数组的指针变量,则ps也指向该结构体数组的0号元素,ps+1指向1号元素,ps+i指向i号元素。这与普通数组一致。
例如:

struct Student{
     int num;
     char name[20];
     char sex[5];
     int age;
     float score;
}stu[2]={
{110,"Zhang",'M',24,90},
{111,"Li",'M',23,93},
{112,"Wangle",'M',33,43}
};
void display(const Student* const);

Student *pStud=stu;
for(int i=0;i<3;i++)
   display(pStud++);

注意:一个结构指针可以用来访问结构体变量或结构体数组的成员,但是不能让它指向结构成员。例如:

pStud=&stu[1].name;//错误

pStud=stu;//正确,赋予数组首地址
pStud=&stu[0];//正确,赋予0号元素首地址

猜你喜欢

转载自blog.csdn.net/yyl424525/article/details/89326086