结构体详解
关于结构体最基础部分的知识,就不在这篇文章中介绍了,具体可以看我之前发布过的结构体初阶和初始结构体和指针,二者选一个看就可以了,里面介绍了结构体的概念,如何创建结构体和结构体的初始化,包括嵌套结构体还有访问方式
1.结构体的成员函数
这里直接给大家介绍在C++中才能使用的结构体的成员函数,不知道大家在刚知道这个概念的时候会不会觉得有点惊讶呢?在结构体中还能包含函数,如果你你是第一次知道这个概念,你可能会好奇我在结构体中定义一个函数有什么作用呢?我这里就先展示它的其中一个用处就是用来初始化成员变量
#include<iostream>
#include<string>
using namespace std;
struct blog
{
string title;
int num;
void init_blog()
{
title = "prince";
num = 1000;
}
};
int main()
{
struct blog b;
b.init_blog();
cout << b.num << ' ' << b.title << endl; //prince 1000
}
1.1 构造函数
在C++的结构体中,会有一些默认的成员函数,比如说构造函数,它的特点就是只要结构体在主函数中被声明,函数就一定会被调用,你不需要在主函数中额外去调用,并且函数名字会与结构体的名称一致
struct blog
{
string title;
int num;
blog() //函数名与结构体名保持一致
{ //无需写返回类型
title = "prince";
num = 1000;
}
};
int main()
{
blog b ;
cout << b.title << ' ' << b.num << endl; //输出prince 1000
return 0;
}
1.2 析构函数
析构函数也是结构体的默认成员函数之一,与构造函数不同的是它是在结构体被销毁的时候调用的,主要用于一些结构体变量中资源的清理工作,如果你没有办法理解是什么意思的话,那就说明你的段位其实还没有到达这个等级,你无需深究,你只需要知道有这么一回事就可以了
它的名字也是受到规定的:结构体名前面加一个~
struct blog
{
string title;
int num;
~blog()
{ //无需写返回类型
cout << "调用析构函数" << endl;
num = 0;
}
};
int main()
{
{
blog b ;
} //加大括号的目的是使结构体销毁
//输出 调用析构函数
return 0;
}
2. 运算符重载
你可能会好奇为什么我会在这个地方讲运算符的重载,这章标题不是结构体详解吗?其实是因为我们在输出结构体的时候是没有办法一整个的去用 cout 打印的,我们只能去选择其中某个成员变量单独去用 cout 打印
那有没有什么操作能够实现我用一个cout就能把结构体的所有的变量打印出来呢?是有的,就是运算符的重载
struct blog
{
string title;
int num;
blog() //构造函数
{
title = "why we sleep";
num = 100;
}
};
//返回类型 表示重载运算符 <<
ostream& operator << (ostream& ost, const blog & b)
{ //第一个参数 cout 第二个参数 结构体blog
ost << "标题:" << b.title << endl;
ost << "数量:" << b.num << endl;
return ost;
}
int main()
{
blog b;
cout << b << endl;
return 0;
}
这段代码具体是什么意思呢?其实解释起来会有一些困难。如果你真的想学会它,我的建议是你需要按着这个样式去写一遍
首先我们先看主函数这里,当我们在调用 << 这个运算符时, 它就会跳到我的重载运算符的这个函数这里,首先是这个 ostream&,你可能不理解它是什么意思,它的意思其实是输出流,在这里所表达的意思是返回类型为输出流,不理解没关系,我们接着往下看
然后是operator这个单词的意思是操作员,然后后面跟了 << 操作符,它所表达的意思是我要重载的对象是这 << 操作符,
然后我们来看到参数部分,又是 ostream&,我们知道我们下函数传参的时候,首先要确定这个数据的数据类型,在这里它的数据类型为输出流,那你可能会好奇,那原函数中哪个元素它的数据类型为输出流呢?cout, 如果你是第一次接受这个概念,你可能会感觉特别惊讶,
那了解这个以后,你就应该可以理解在这个函数中我们所有要用到 cout 的地方都可以用 ost 来替代。然后第二个参数呢就是结构体,这个大家应该都能理解是为什么
3. 结构体排序 —— sort
3.1 sort 函数介绍

大家千万不要觉得这个函数会很复杂,只是它这里的英文写的过于的冗长了
我下面呢就来简单的介绍一下这个函数,首先要使用这个函数必须要包含头文件 <algorithm>,也就是算法头文件,其次这个函数不返回任何值,并且默认是将给定的内容进行升序排序,也就是从小到大排,第一个参数是第一个数据的指针或迭代器, 第二个参数是最后一个数据之后的迭代器或指针
int main()
{
int arr[10] = {3,2,1,4,5,6,7,8,0,9};
sort(arr, arr + 10);
for(int i = 0; i < 10; i++)
{
cout << arr[i] << ' ';
//输出 0 1 2 3 4 5 6 7 8 9
}
return 0;
}
这个函数也可以为字符数组进行排序,依据 ASCII 码值为标准
int main()
{
string s = "djsifbgsabz";
sort(s.begin(), s.end());
cout << s << endl;
//输出 abbdfgijssz
return 0;
}
3.2 自定义排序
其实这个函数还可以传第三个参数,第三个参数是一个函数,用于自定义排序标准,按照规定这个函数必须返回一个布尔类型的值,听完我的描述你可能对于这个函数仍然没有什么思路,这个我就以一个降序的自定义为例,演示一下如何使用
bool comp(int x, int y)
{
return x > y; //这种写法等同于 if(x > y)
} // return true;
// else
// return false;
//表示的意思是 x > y,则 x 会被放在 y 之前
int main()
{
string s = "djsifbgsabz";
sort(s.begin(), s.end(), comp);
cout << s << endl;
//输出 zssjigfdbba
return 0;
}
你可能会感到疑惑,为什么 comp 判断 x > y 返回 ture,sort就知道要将 x 放在前面,这就涉及到sort的工作原理了
-
如果
comp(a, b)返回true
→ 认为a应该 排在b前面(即a的次序更靠前)。 -
如果返回
false
→ 认为a不应该排在b前面(通常是b排在a前面,或二者等价)
传进两个参数,若返回 true 则把第一个参数排在第二个之前,若返回 false ,则反之。
4. 结构体中重载()运算符-仿函数
其实在 sort 中第三个参数是比较函数或函数对象,而仿函数的另一个名字就是函数对象,什么意思呢?看看下面的代码示例你就明白了
struct cmp
{
bool operator() (int x, int y) //重载()运算符
{
return x > y;
}
}cmp; //创建结构体变量
int main()
{
int arr[] = {1,0,4,3,2,5,6,7,9,8};
int sz = sizeof(arr) / sizeof(arr[0]);
sort(arr, arr + sz, cmp); //把结构体以参数的形式传入 sort
//结构体发挥着函数的作用(仿函数)
for(int i = 0; i < sz; i++)
{
cout << arr[i] << ' ';
} //输出9 8 7 6 5 4 3 2 1 0
return 0;
}
5. 结构体排序
除了给这种常见的单一的数据类型排序以外,我们还可以通过比较函数自定义的方式给结构体这种复合的数据类型排序
如果你是第一次的听到这个观点,你可能会去思考结构体的排序应该如何排呢?如果你是第一次的听到这个观点,你可能会去思考结构体的排序应该如何排呢?其实原理非常简单,你想怎么排就怎么排,以下面的这段代码为例,我就是以结构体中的名字中的字符串顺序排列
struct comp
{
string name;
int age;
};
bool cmp_name(comp& s1, comp& s2) //按照字符的 ASCII 码值排序
{
return s1.name > s2.name; //降序
}
int main()
{
comp arr[] = {{"liu", 19}, {"qipei", 18}}; //q > l qipei > liu
sort(arr, arr + 2, cmp_name);
for(int i = 0; i < 2; i++)
{
cout << arr[i].name << ' ' << arr[i].age << endl;
}
//输出qipei 18
//liu 19
return 0;
}
更多推荐


所有评论(0)