C++提高编程(模板、STL函数,黑马程序员笔记)

●本阶段主要针对C++泛型编程STL技术做详细讲解,探讨C++ 更深层的使用
 

1模板


1.1模板的概念
模板就是建立通用的模具,大大提高复用性
例如生活中的模板
一寸照片模板: 

模板的特点:
●模板不可以直接使用,它只是一个框架
●模板的通用并不是万能的I
 

1.2函数模板
●C++另- 种编程思想称为泛型编程,主要利用的技术就是模板
●C++提供两种模板机制函数模板和类模板
回1.2.1函数模板语法
函数模板作用:
建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表。
语法:

1| template<typename T>
2|函数声明或定义

解释:
template -- 声明创建模板
typename -- 表面其后面的符号是一种数据类型,可以用class代替
T --- 通用的数据类型,名称可以替换,通常为大写字母

#include <iostream>
//函数模板
template<typename T> //声明一个模板, 告诉编译器后面代码中紧跟着的T不要报错,T是一个通用数据类型
svoid mySwap(T &a, T &b){
T temp=a;
a=b;
b = temp;
}
void test01()
{
inta=10;
intb=20;
//swapInt(a, b);
//利用函数模板交换
//两种方式使用函数模板
//1.自动类型推导,上面写了int,编译器自动识别T就是int
//mySwap(a, b);
//2.显示指定类型
myswap<int>(a,b);
cout<<"a="<a<<<endl:
cout<< "b= "<< b<< endl;
}

 总结:
●函数模板利用关键字template
●使用函数模械有两种方式:自动类型推导、显示指定类型
●模板的目的是为了提高复用性,将类型参数化

1.2.2函数模板注意事项
注意事项:
●自动类型难导,必须推导出一致的数据类型T,才可以使用
●模板必须要确定出T的数据类型,才可以使用
示例:


template<calss T>//typename可以替换class

//注意1
viod tes10()
{
int a=10;
char c='d';
myswap(a,c);//错误,推导不出一致的数据类型
}
//2.注意
template<calss T>
void func()
{cout<<"func调用”<<endl;
}
void test02 ()
{
func<int>();
//fun()错误 
}

1.2.3函数模板案例
案例描述:
●利用函数模板封装一 个排序的函数,可以对不同数据类型数组进行排序
●排序规则从大到小,排序算法为选择排序
●分别利用char数组和int数组进行测试
 

1.24普通函数与函数模板的区别
普通函数与函数模板区别:.
●普通函数调用时可以发生自动类型转换(隐式类型转换)
●函数模板调用时,如果利用自动类型推导,不会发生隐式类型转换
●如果利用显示指定类型的方式,可以发生隐式类型转换

#include <iostream>
using namespace std;
//普通函数
int myadd01(int a,int b){
return a+b;
}
//函数模板
template<class T>
t myadd02(T a,T b)
{
    return a+b;
}

void test 01()
{
 int a=10;
 int b=20;
 char c='c';//c--99;
 cout<<myadd01(a,c)<<endl;
 cout<<myadd02(a,c)<<endl;//会报错
}
int main()
{
    return 0;
}

1.2.5普通函数与函数模板的调用规则
调用规则如下: 
1.如果函数模板和普通函数都可以实现,优先调用普通函数
2.可以通过空模板参数列表来强制调用函数模板
3.函数模板也可以发生重载
4.如果函数模板可以产生更好的匹配优先调用函数模板
 

 函数重载:

1.2.6模板的局限性
局限性:
●模板的通用性并不是万能的

在上述代码中提供的赋值操作,如果传入的a和b是-个数组, 就无法实现了
 1.3类模板
1.3.1类模板语法
类模板作用:
●建立一个通用类,类中的成员数据类型可以不具体制定,用一个虚拟的类型来代表。
语法:

1 template<typenane T>
2类

解释: .
template -声明创建模板
typename --- 表面其后面的符号是一种数据类型, 可以用class代替
T -通用的数据类型,名称可以替换,通常为大写字母

初识STL

2.1 STL的诞生
●长久以来,软件界- -直希望建立- -种可重复利用的东西
●C++的面向对象泛型编程思想,目的就是复用性的提升
●大多情况下,数据结构和算法都未能有一 套标准,导致被迫从事大量重复工作
●为了建立数据结构和算法的一套标准诞生了STL
2.2 STL基本概念
●STL(Standard Template Lbrary,标准模板库)
●STL从广义上分为:容器(container)算法(algorithm)迭代器(iterator)
容器算法之间通过迭代器进行无缝连接。
●STL几乎所有的代码都采用了模板类或者模板函数
 

2.3 STL六大组件
STL大体分为六大组件,分别是:容器、算法。迭代器.仿函数。适配器(配接器) .空间配置器
1.容器:各种数据结构,如vector. list. deque. set, map等用来存放数据。
2.算法:各种常用的算法,如sort, find, copy. for. each等
3.迭代器:扮演了容器与算法之间的胶合剂。
4.仿函数:行为类似函数,可作为算法的某种策略。
5.适配器: - 种用来修饰容器或者仿函数或迭代器接口的东西。
6.空间配置器:负责空间的配置与管理。
 

2.4 STL中容器、算法、迭代器
容器:置物之所也
STL容器就是将运用最广泛的一些数据结构实现出来常用的数据结构:数组,链表树,栈,队列,集合,映射表等
这些容器分为序列式容器和关联式容器两种:
列式容器:强调值的排序,序列式容器中的每个元素均有固定的位置。
关联式容器:二叉树结构,各元素之间没有严格的物理上的顺序关系
 

算法:问题之解法也
有限的步骤,解决逻辑或数学上的问题,这-门学科我们叫做算法(Algorithms)
算法分为:质变算法和非质变算法。
质变算法:是指运算过程中会更改区间内的元素的内容。例如拷贝,替换,删除等等
非质变算法:是指运算过程中不会更改区间内的元素内容,例如查找、计数、遍历、寻找极值等等

迭代器:容器和算法之间粘合剂
提供-种方法,便之能够依序寻访某个容器所含的各个元素,而又无需暴露该容器的内部表示方式。
每个容器都有自己专属的迭代器
迭代器使用非常类似于指针,初学阶段我们可以先理解迭代器为指针

 2.5容器算法迭代器初识
了解STL中容器、算法、迭代器概念之后,我们利用代码感受STL的魅力
STL中最常用的容器为Vector,可以理解为数组,下面我们将学习如何向这个容器中插入数据、并遍历这个容器
2.5.1 vector存放内置数据类型
容器 vector
算法: for. each 
迭代器: vectorint>::iterator

示例:

#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
void myprint(int val)//第三种遍历的时候用
{
    cout<<val<<endl;
}
int main()
{
    //创建一个vector容器,数组
vector<int> v;
//向容器中插入数据
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
// 通过迭代器访问容器中的数据
vector<int>::iterator itBegin=v.begin();//起始迭代器 指向容器中的第一个元素
vector<int>::iterator itEnd=v.end();//结束迭代器 指向容器中最后一个元素的下一位

//第一种遍历方式
while(itBegin!=itEnd)
{
    cout<<*itBegin<<endl;
    itBegin++;
}
//第二种遍历方式 常用
for(vector<int>::iteator it=v.begin();it!=v.end;it++)
{
    cout<<*it<<endl;
}
//第三种遍历方式
for_each(v.begin(),v.end,myprint());
    return 0;
}

2.5.3 Vector容器嵌套容器
学习目标:容器中嵌套容器,我们将所有数据进行遍历输出
 

#include <iostream>
#include <vector>
#include <string>
using namespace std;
void test(){
 vector<vector<int> > v;
 //定义小容器
 vector<int>v1;
  vector<int>v2;
   vector<int>v3;
    vector<int>v4;
    for(int i=0;i<4;i++)
    {
        v1.push_back(i+1);
        v2.push_back(i+2);
        v3.push_back(i+3);
        v4.push_back(i+4);
    }
    //将小容器元素放到大容器中
    v.push_back(v1);
    v.push_back(v2);
    v.push_back(v3);
    v.push_back(v4);

    for(vector<vector<int> >::iterator it=v.begin();it!=v.end();it++)
    {
        for(vector<int>::iterator vit=(*it).begin();vit!=(*it).end();vit++)
        {
            cout<<*vit<<" ";
        }
        cout<<endl;
    }
}
int main()
{
test();

    return 0;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱康代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值