【C++】泛型算法(一)指针的算术运算

STL

【C++】泛型算法(一)指针的算术运算_第1张图片
泛型算法即通过function template技术,达到“与操作对象的类型互相独立”的目的。

指针的算术运算

#include 
using namespace std;
#include 

任务1
给定一个储存任何类型数字的vector,以及一个整数值,
如果此值存在于vector内,必须返回一个指针指向该值;
反之则返回0,表示此值并不在vector内。

int* find(const vector<int> &vec, int value)
{
	for (int ix = 0; ix < vec.size(); ++ix)
	{
		if (vec[ix] == value)
		{
			return &vec[ix];
		}
	}
	return 0;
}

任务2
该函数升级为可以处理任何类型

//方法:将泛型算法find()以函数模板的形式呈现
template<typename elemType>
elemType* find(const vector<elemType> &vec, const elemType &value)
{
	for (int ix = 0; ix < vec.size(); ++ix)
	{
		if (vec[ix] == value)
		{
			return &vec[ix];
		}
	}
	return 0;
}

任务3
让该函数同时可以处理vector与array内的任意类型元素
将任务三拆分为子任务3.1和3.2

//子任务3.1
//将array的元素传入find(),而不指定array的类型
//3.1.1
//解法一:增加一个参数,用来表示array的大小
//从0开始访问每个元素,依次处理至size-1个元素
template <typename elemType>
elemType* find(const elemType *array, int size, const elemType &value)
//此时,传递给find()的array是以第一个元素的指针传入的,如何通过特定位置进行元素访问?
//3.1.1.1
//下标运算符[ ]访问:
//array的起始地址加上索引值产生该元素的地址,然后该地址再被dereference以返回元素值
template <typename elemType>
elemType* find(const elemType *array, int size, const elemType &value)
{
	if (!array || size < 1)
		return 0;
		
	for (int ix = 0; ix < size; ++ix)
		if (array[ix] == value)
			return &array[ix];
			
	return 0;
}

//3.1.1.2
//指针 *访问:
template <typename elemType>
elemType* find(const elemType *array, int size, const elemType &value)
{
	if (!array || size < 1)
		return 0;
		
	for (int ix = 0; ix < size; ++ix, ++array)//++array会令array指向下一个元素
		if (*array == value)
			return array;
			
	return 0;
}
//注意!*(array+2)
//array+2产生的地址是array的地址(若为1000)加上两个整数元素的大小(4 byte)(即1008)
//3.1.2
//解法二:使用第二个指针来取代参数size
template <typename elemType>
elemType* find(const elemType *first, const elemType *last, const elemType &value)
{
	if (!first || !last)
		return 0;
		
       //当first不等于last,就把value拿来和first所指的元素作比较,
       //如果两者相等,返回first,否则first+1,令它指向下一个元素
       
	for (; first != last; ++first)
		if (*first == value)
			return first;
			
	return 0;
}

//如何调用find()?
int ia[3] = {1, 1, 2};
int *pi = find(ia, ia+3, ia[2]);
//子任务3.2
//将vector的元素传入find(),而不指定vector的类型
//3.2解法:使用一对用来表示“起始地址/结束地址”的参数传入find();
//不同之处在于vector可以是空的,因此调用前先确定vector不为空。
//
//将“取第一个元素的地址”的操作包装为函数
//begin()返回0或者是vector第一个元素的地址
vector<string> svec;

template <typename elemType> 

inline elemType* begin(const vector<elemType> &vec)
    {return vec.empty() ? 0:&vec[0];}

inline elemType* end(const vector<elemType &vec)
    {return vec.empty() ? 0:&vec.end();}
    
//调用find()
find(begin(svec), end(svec), search_value);

任务4 如何扩展find()的功能,令它也能支持list类别
分析:指针的算数运算必须首先假设所有元素都储存在连续空间,因此指针的算术运算不适用于list
解决:在底层指针的行为之上提供一层抽象,取代程序原本的“指针直接操作”方式。
该技巧把底层指针的处理通通放在此抽象层中,让用户无须直接面对指针操作进而处理标准库中的所有容器类。

你可能感兴趣的:(C++基础,算法,c++,笔记)