关于C++中结构体(史上最超级详细)
什么是结构体
结构体是程序员定义的数据类型,可以容纳许多不同的数据值。
声明结构体的方式
声明方式跟类的方式大致相同,其区别如下:
- 使用关键字struct而不是关键字class
- 尽管结构体可以包含成员函数,但它们很少这样做。所以,通常情况下结构体声明只会声明成员变量。
- 结构体声明通常不包括public或private的访问修饰符。
- 类成员默认情况是私有的,而结构体的成员则默认为public。程序员通常希望它们保持公开,只需使用默认值即可。
struct PayRoll { int empNumber; string name; double hours,payRate,grossPay; };
结构体的初始化
当初始结构体变量时,可以通过两种方式初始化它:使用初始化列表或者构造函数。
初始化列表
初始化结构体变量成员的最简单的方法是使用初始化列表。初始化列表是用于初始化一组内存位置的值列表。列表中的项目用逗号分隔并用大括号括起来。
例如,假设已经声明了以下Date结构体:
struct Date{ int day,month,year; }
定义和初始化Date变量的方式是:先指定变量名,后接赋值运算符和初始化列表,如下所示:
Date birthday = {1, 11, 2019};
可以按以下方式赋值
Date birthday = {1, 11};
但不能按以下方式赋值,因为以下方式是非法的
此举意图跳过month成员初始化,这是不合法的,c++不通过这种成员方法。
Date birthday = {1, 2019};
还有一点很重要,就是不能在结构体声明中初始化结构体成员因为结构体声明只是创建一个新的数据类型,还不存在这种类型的变量。例如,以下声明是非法的:
//非法结构体声明 struct Date { int day = 1, month = 11, year = 2019; };
因为结构体声明只声明一个结构体“看起来是什么样子的”,所以不会在内存中创建成员变量。只有通过定义该结构体类型的变量来实例化结构体,才有地方存储初始值。
构造函数初始化结构体
虽然初始化列表易于使用,但它有两个缺点:
- 如果有某个成员未被初始化,那么在这种情况下,跟随在该成员后面的成员都不能初始化。
- 如果结构体包括任何诸如字符串之类的对象,那么在许多编译器上都将无法运行。
在这些情况下,可以使用构造函数来初始化结构体成员变量,这和初始化类成员变量是相同的。与类构造函数一样,结构体的构造函数必须是与结构体名称相同的公共成员函数,并且没有返回类型。因为默认情况下,所有结构体成员都是公开的,所以不需要使用关键字public。
以下是一个名为Employ的结构体声明语句,它包含一个具有两参数的构造函数
,以便在创建一个Employ变量而不向其传递任何参数时,提供默认值:
struct Employ{ string name; //员工姓名 int vacationDays; //允许的年假 int daysUsed; //已使用的年假天数 Employ(string n = "",int d = 0){ name=n; vacationDays=10; daysUsed=d; } }
还有其它的初始化方式:
struct Node{ int k; int to; int cost; Node(int to,int k,int costt=0):k(k),to(to),cost(costt){} //带有默认参数的变量需要放 }
以下是测试代码:
#include <iostream> #include <bits/stdc++.h> using namespace std; struct test { int a; double b; int *q[12]; test(int q,double qq):a(q),b(qq){}; test():a(10),b(20.1234567){ for (int i = 0; i < 12; ++i) { q[i]=NULL; } } }; int main(){ test t; int o=120; t.q[5]=&o; cout<<t.a<<" "; cout<<fixed<<setprecision(7)<<t.b<<endl; cout<<t.q[5]<<" "<<*t.q[5]<<endl; system("pause"); return 0; }