文章目录
- 1. 结构体的定义
- 2. 结构体的声明与初始化
- 2.1 直接声明
- 2.1.1 赋值初始化
- 2.1.2使用初始化列表
- 2.2 使用指针声明
- 3. 结构体的构造函数
- 4. 结构体的自引用
- 4.1 定义结构体时引用自己
- 4.2 声明
- 5. 重载输入输出函数
1. 结构体的定义
//方式一:
// 定义一个结构体
struct Person{
string name;
int age;
};
// 方式二:
// 定义一个结构体,同时声明一个对象
struct Student{
string name;
int age;
}student;
// 方式三
//定义一个结构体,同时声明一个对象,并初始化
struct Man{
string name;
int age;
}man{"Bob", 33};
//方式四 使用typedef
typedef struct Women{
string name;
int age;
}Women;
// 该方法完成了两步
//第一步定义一个struct Women
/*
struct Women{
string name;
int age;
};
*/
//第二步
// typedef Struct Women Women
2. 结构体的声明与初始化
2.1 直接声明
Person zhang_san //定义变量
Person boys[5] //定义数组
2.1.1 赋值初始化
Person zhang_san;
zhang_san.name = "zhang san";
zhang_san.age = 18;
std::cout <<" " << zhang_san.name << " " << zhang_san.age << std::endl;
2.1.2使用初始化列表
Person wang_er={"wang er", 12};
std::cout << " " << wang_er.name << " " << wang_er.age << std::endl;
Person boys[2] = {{"lili", 12}, {"fangfang", 12}};
std::cout << " " << boys[0].name << " " << boys[0].age << std::endl;
2.2 使用指针声明
Person* zhang_san;
⚠️注意: 声明一个结构体指针记得初始化,一定要初始化,不初始化会出事
Person* li_si;
li_si->name = "li si";
li_si->age = 19;
std::cout << " " << li_si->name << " " << li_si->age << std::endl;
这份代码会报一个错:空指针访问异常,这是因为li_si这个指针还没有初始化,因此他没有内存空间,自然就不存在有name和age这个参数
正确的写法是:
Person p;
p.name ="ming_ming";
p.age = 13;
Person *ming_ming;
ming_ming = &p;
std::cout << "指针: " << ming_ming->name << " " << ming_ming->age << std::endl;
// 注意当p的值发生变化时,ming_ming的值也会变化
p.age = 16;
std::cout << "指针: after change " << ming_ming->name << " " << ming_ming->age << std::endl;
或者
Person *zhang = new Person();
zhang->name = "zhang";
zhang->age = 12;
std::cout << "指针: 2 " << zhang->name << " " << zhang->age << std::endl;
3. 结构体的构造函数
结构体的构造函数与 class类似
typedef struct Student{
string name;
int age;
float score;
Student(string name, int age, float score){
this->name = name;
this->age = age;
this->score = score;
} //构造函数一
Student(string _name, int _age) :
name(_name),
age(_age)
{
this->score = 0;
} // 构造函数二
Student(){ }
//一旦自定义构造函数了,那么默认不可见的构造函数就被覆盖了,所以需要显示默认构造函数
}Student;
// 声明
Student born("bron", 18);
std::cout << " " << born.name << " " << born.age << " " << born.score << std::endl;
//使用指针声明
Student *kiity = new Student ("kiity", 19, 100);
std::cout << " " << kiity->name << " " << kiity->age << " " << kiity->score << std::endl;
这里使用指针声明结构体时可以直接采用 new
4. 结构体的自引用
4.1 定义结构体时引用自己
以A-star算法中定义 节点为例, 节点数据类型需要储存节点位置信息(x,y), 节点代价信息(f, g, h), 节点的父节点(这也是一个节点数据类型)
typedef struct Node{
int x;
int y;
float f;
float h;
float g;
Node * father_node;
Node(int x, int y){
this->x = x;
this->y = y;
this->g = 0;
this->h = 0;
this->f = 0;
this->father_node = NULL;
}
Node(){}
Node(int x_, int y_, Node *father ): x(x_), y(y_), g(0.0), f(0.0), h(0.0), father_node(father){ }
//重载输入
friend istream &operator >>(istream&, Node &n){
cin >> n.x >> n.y;
// 顺便初始化其他值
n.h = 0;
n.g = 0;
n.f = 0;
n.father_node = NULL;
return cin;
}
//重载输出
friend ostream &operator << (ostream&, Node &n){
if (n.father_node == NULL){
cout << " [ " << n.x << " , " << n.y << " ] -- " << "GHF: " << n.g << " , "
<< n.h << " , " << n.f << " -- { NULL } ";
} else{
cout << " [ " << n.x << " , " << n.y << " ] -- " << "GHF: " << n.g << " , "
<< n.h << " , " << n.f <<" -- { "
<< n.father_node->x << " , " << n.father_node->y << " } ";
}
return cout;
}
};
4.2 声明
Node start_node(0, 0);
std::cout <<start_node << std::endl;
Node new_node(1, 1, &start_node);
std::cout << "new " << new_node << std::endl;
//如果star_node改变,new_node也会改变
start_node.x = 2;
start_node.y = 2;
std::cout << "new after change: " << new_node << std::endl;
Node *father_node = &start_node; //father_node 取的是star_node的地址,所以,star_node 改变father_node 也随之改
std::cout << "指针 :" << *father_node << std::endl;
Node *this_node = new Node(5, 5, father_node);
std::cout << "指针 :" << *this_node << std::endl;
//如果father node指向 的值改变, this_node 也会改变
start_node.x = 8;
start_node.y = 8;
std::cout << "指针 after change :" << *this_node << std::endl;
5. 重载输入输出函数
查看4