【C/C++学院】0815-函数包装器/CPP类型转换/函数模块/动态数组

函数包装器管理内嵌函数

#include<iostream>
#include<functional>

//函数包装器
//第一,设计执行接口,接口设计关卡(),计数
//第二,函数包装器依赖于函数模板,实现通用泛型
//第三,函数代码可以内嵌在另外一个函数,实现函数怀孕
//函数包装器,用于管理内嵌函数,外部函数调用


//函数包装器, T数据类型, F是函数
template<typename T,typename F>
T run(T v, F f)
{
	static int count = 0;
	count++;//计数器
	std::cout << "run  一个参数的包装器 执行" << count << "次" << std::endl;
	if (count > 1)
	{
		T  vx(0);
		return  vx;
	}
	return f(v);//函数传入参数
}

template<typename T, typename F>
T run(T v1, T v2, F f) 
{
	return f(v1,v2);//函数传入参数
}


void main()
{
	using  std::cout;  //C++11. namespace,专门引用一个关键字,不需要std
	using  std::endl;
	using  std::function;
	//using namespace std;
	using  std::cin;

	double db = 12.9;//double *2
	int  num1 = 19;
	int  num2 = 29;

	function<double(double)> fun1 = [](double u)
	{
		return u * 2; 
	};
	function<double(double)> fun2 = [](double u)
	{
		return u*u;
	};
	function<int(int, int)> fun3 = [](int u1,int u2)
	{
		return u1 + u2;
	};
	
	cout << run(db, fun1) << endl;//调用
	cout << run(db, fun2) << endl;//调用
	cout << run(num1,num2, fun3) << endl;//调用
	cin.get();//等价于你输入一字符getchar;

}

函数包装器管理外部函数

#include<iostream>
#include<functional>

template<typename T, typename F>
T run(T v1, T v2, F f)
{
	return f(v1, v2);//函数传入参数
}

int  cheng(int a, int b)
{
	return a*b;
}

void main()
{
	using  std::cout;  //C++11. namespace,专门引用一个关键字,不需要std
	using  std::endl;
	using  std::function;
	//using namespace std;
	using  std::cin;

	int  num1 = 19;
	int  num2 = 29;
	function<int(int, int)> fun4 = cheng; //fun4函数指针

	cout << run(num1, num2, fun4) << endl;//调用
	cin.get();//等价于你输入一字符getchar;

}

函数模板根据类型覆盖

函数模板覆盖

#include<iostream>

//函数模板实现通用,可以根据自有数据类型,进行优化

//结构体没有私有变量可以直接赋值初始化
//所有成员都是公有的类型可以赋值初始化
struct info
{
	char name[40];
	double db;
	int data;	
};

template<typename T>
void swap(T &a, T &b)
{
	std::cout << "通用函数模板" << std::endl;
	T temp = a;
	a = b;
	b = temp;//交换两个变量
}
//模板为空,明确参数类型,覆盖函数模板的类型,
void  swap(info &info1, info &info2)
{
	std::cout << "特有函数模板" << std::endl;
	//通用模板可以实现通用,针对自己的数据类型做出优化
	info temp = info1;
	info1 = info2;
	info2 = temp;
}


void main()
{
	info info1 = { "yincheng", 20.9, 10 };
	info info2 = { "chengyin",9.2, 1 };
	swap(info1, info2);
	std::cout << info1.name << info1.db << info1.data << std::endl;
	std::cout << info2.name << info2.db << info2.data << std::endl;
	std::cin.get();
}


void main1()
{
	int num1 = 100;
	int num2 = 10;
	swap(num1, num2);//实现交换
	std::cout << num1 << "  " << num2 << std::endl;
	char  ch1 = 'Z';
	char  ch2 = 'A';
	swap<char>(ch1, ch2);
	std::cout << ch1 << "  " << ch2 << std::endl;

	std::cin.get();//getchar
}

处理类的私有

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>

//函数模板实现通用,可以根据自有数据类型,进行优化

//结构体可以直接赋值(没有私有变量)

//所有成员都是公有的类型可以赋值(一开始初始化)
//如果类有私有成员变量,不可以用{}初始化

//类的对象之间默认是可以直接赋值

//类,结构体都有一个默认赋值操作= 浅拷贝 ,交换数据

//深拷贝用的最多,函数模板的覆盖
class info
{
public:
	char name[40];
	char *p;
	int data;
private:
	int num;
public:
	void set(int X)
	{
		this->num = X;//通过接口设置私有变量
	}
	int get()
	{
		return this->num;//返回值,副本机制
	}
};

template<typename T>
void swap(T &a, T &b)
{
	std::cout << "通用函数模板" << std::endl;
	T temp = a;
	a = b;
	b = temp;//交换两个变量
}


//模板为空,明确类型,
template<>
void  swap(info &info1, info &info2)
{
	std::cout << "特有函数模板" << std::endl;
	//通用模板可以实现通用,针对自己的数据类型做出优化
	//计数器,对象交换计数器
	info temp = info1;
	info1 = info2;
	info2 = temp;//
}

void main()
{
	info info1;
	info info2;
	std::strcpy(info1.name, "yincheng");
	std::strcpy(info2.name, "chengyin ");
	info1.data = 102;
	info2.data = 201;//初始化
	info1.p = new char[10];
	std::strcpy(info1.p, "魔王");

	//info2.p = nullptr;//C++的空指针
	info2.p = new char[100];
	std::strcpy(info2.p, "da魔王");
	info1.set(89);
	info2.set(98);

	swap(info1, info2);

	std::cout << info1.name << "   "<< info1.data  <<"   "<<info1.get()<< std::endl;
	std::cout << info1.p << std::endl;
	std::cout << info2.name << "   "<<info2.data  <<"    "<<info2.get()<< std::endl;
	std::cout << info2.p << std::endl;
	std::cin.get();
}

CPP类型转换 四种cast

#include<iostream>
#include<stdio.h>

void main1()
{
	double db = 10.9;
	float fl= db;//默认数据类型转换
	std::cin.get();
}

void main2()
{
	void *p = new int[10];
	int *pint =(int*) p;//C语言风格
}

//static_cast<需要转换的数据类型>(要转换的数据)80% static_cast
void main3()
{
	//int n = static_cast<int>(78.98);
	printf("\n%d", 98.87);
	printf("\n%d",static_cast<int>( 98.87));
	printf("\n%f", 98);
	printf("\n%f", static_cast<float>(98));

	int *p = static_cast<int*> (malloc(100));
	std::cin.get();
}
//const int num = 10,可以修改无法生效,编译的时候不读内存
//const int *p指向变量限定权限,只读不可写,
//const_cast去掉常量指针属性 %5
void main4()
{
	int num[3] = { 1, 2, 3 };
	const int *p = num;
	std::cout << *p << *(p + 1) << *(p + 2) << std::endl;
	//*p = 10;
	//*(p + 1) = 20;
	int *pnew = const_cast<int *>(p);
	*pnew = 10;

	std::cin.get();
}
//reinterpret_cast %1  专业转换指针,最安全
void  main()
{
	//指针。强类型,类型决定了数据的解析方式,内存占多大
	int num = 3;
	char *p = reinterpret_cast<char *>(&num);
	for (int i = 0; i < 4; i++)
	{
		printf("%c,%d,%p\n", *(p+i), *(p+i), p+i);
	}
	std::cin.get();
}
//dynamic_cast 类的指针之间的转换

函数模板重载调用规则

函数模板与普通函数的选择问题

#include <iostream>

//函数模板可以对类型进行优化重载,根据类型会覆盖
//如果仍然要使用模板函数,需要实例化
template<class T>
T add(T a,T b)
{
	std::cout << " T add" << std::endl;
	return a + b;
}

int add(int a, int b)
{
	std::cout << " int add" << std::endl;
	return a + b;
}

void main()
{
	int a = 10, b = 20;
	double db1 = 10.9, db2 = 10.8;
	add(db1, db2);
	add(a,b);
	add<int>(a, b);//进行实例化,

	std::cin.get();
}

函数可变参数通用类型模板函数 

可变参数高级模板

#include<iostream>
#include<cstdarg>

void showall(){};//预留一个

template <typename T>
void show(T t, ...)
{
	std::cout << t << std::endl;
}

template <typename T,typename...Args>
void showall(T t, Args...args)
{
	std::cout << t << std::endl;
	showall( args...);
}

void main()
{
	int num1 = 10, num2 = 9, num3 = 11;
	double db1 = 10.8, db2 = 10.9;
	char str[40] = "yincheng";
	char ch = 'A';
	show(num1);
	showall(num2,num3);
	showall(num2, num3,num1,str,ch);

	std::cin.get();
}

通用函数可变参数模板

#include <iostream>


//通用可变参数模板    处理不限定个数的参数,处理不同类型
void showall()//空函数,接口,最后结束递归  新版本编译
{

}

template<typename T,typename...Args>
void showall(const T &value, const Args &...args)
{
	std::cout << value << std::endl;
	showall(args...);//继续传递
}

//设计可以修改原来的数据的  T &value,  Args &...args
//设计可以修改副本    T value,  Args ...args
//设计不可以可以改原来的数据不可以修改副本 const T value,  const Args ...args
//设计引用原来的数据不可以修改 const  T &value,  const Args &...args

void main()
{
	int num1 = 10, num2 = 9, num3 = 11;
	double db1 = 10.8, db2 = 10.9;
	char str[40] = "yincheng";
	char ch = 'A';
	showall(num1);
	std::cout << "\n\n\n";
	showall(num1,num2,num3);
	std::cout << "\n\n\n";
	showall(db1, db2, num1, ch);
	std::cout << "\n\n\n";
	showall(db1, db2, num1, ch,str);

	std::cin.get();
}

cpp新数组

#include <iostream>
#include<array>
#include<string>
#include<stdlib.h>

void main1()
{
	double db[4] = { 1.1, 2.2, 3.3, 4.4 };
	//std::array数据类型,double元素类型,4个数
	std::array<double, 4>  dbnew1 = { 10.1, 10.2, 10.3, 10.4 };
	std::array<double, 4>  dbnew2 = dbnew1;//可以实现数组之间整体操作
	for (int i = 0; i < 4; i++)
	{
		std::cout << db[i] << "   " << dbnew1[i]<<"    "<<dbnew2[i] << std::endl;
	}

	std::cin.get();
}

void main2()
{
	std::array<std::string, 5> string1 = { "calc", "notepad", "tasklist", "mspaint", "write" };

	for (int i = 0; i < 5; i++)
	{
		std::cout << string1[i] << std::endl;
		system(string1[i].c_str());
	}
	std::cin.get();
}

void main()
{
	std::string str1 = "task";
	std::string str2 = "list";
	std::string str3 = str1 + str2;
	system(str3.c_str());
	std::cin.get();
}

高级数组array_vector 

#include<iostream>
#include<array>
#include<vector>//C++的标准库
#include<string>//C++字符串

using  std::array;//静态数组,栈上,
using std::vector;//动态数组,堆上,
using std::string;

//使用C++风格数组不需要管理内存。
//array注意不要栈溢出
//array适用于任何类型

void main1()
{
	//
	array<int, 5> myint = { 1, 2, 3, 4, 5 };
	array<int, 1024 * 256> myint1;
	vector<double> myvector; //动态数组
	for (int i = 0; i < 1024 * 1024; i++)
	{
		myvector.push_back(i);//
	}

	std::cin.get();
}

void main2()
{
	array<int, 5> myint1 = { 1, 2, 3, 4, 5 };
	array<int, 5> myint2 = { 11, 12, 13, 14, 15 };
	array<int, 5> myint3 = { 21, 22, 23, 24, 25 };
//	array<array<int, 5>, 3> myint = {myint1,myint2,myint3};
	array<array<int, 5>, 3> myint = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
	for (int i = 0; i < myint.size();i++)//数组大小
	{
		for (int j = 0; j < myint1.size(); j++)
		{
			std::cout << "  "<<myint[i][j];
		}
		std::cout << "\n";
	}

	std::cin.get();
}

void main3()
{
	vector <string>  string1;//动态字符串数组
	//可以反复利用
	string1.push_back("notepad");
	string1.push_back("calc");
	string1.push_back("mspaint");
	string1.pop_back();//删除一个
	//string1.clear();//清空
	for (int i = 0; i < string1.size(); i++)//遍历动态数组
	{
		//system(string1[i].c_str());
	}
}

void main5()
{
	vector <string>  string1;//动态字符串数组
	string1.push_back("notepad");
	string1.push_back("calc");
	string1.push_back("mspaint");

	vector<string>::iterator ibegin, iend;//迭代器
	ibegin = string1.begin();//数据起始点
	iend = string1.end();//结束

	for (;ibegin!=iend;ibegin++)
	{
		string tempstr = *ibegin;//获取指针指向的数据
		system(tempstr.c_str());//执行指令
	}
}

void  main6()
{
	array<int, 5> myint = { 1, 2, 3, 4, 5 };
	array<int,5>::iterator ibegin, iend;//正向迭代器
	ibegin = myint.begin();
	iend = myint.end();
	while (ibegin!=iend)
	{
		std::cout << *ibegin << std::endl;
		ibegin++;
	}
	array<int, 5>::reverse_iterator rbegin, rend;
	rbegin = myint.rbegin();
	rend = myint.rend();
	while (rbegin!=rend)
	{
		std::cout << *rbegin << std::endl;
		rbegin++;

	}

	std::cin.get();
}

void main7()
{
	vector <string>  string1;//动态字符串数组
	string1.push_back("notepad");
	string1.push_back("calc");
	string1.push_back("mspaint");
	//反向迭代器
	vector<string>::reverse_iterator rbegin = string1.rbegin();
	vector<string>::reverse_iterator rend = string1.rend();
	//rend--;rend最后不指向数据,指向数据的结尾的下一个节点
A:	if (rbegin!=rend)
	{
		system((*rend).c_str());//执行指令
		//rbegin++;
		rend--;
		goto A;
	}
}

Lambda  [ret](int x){xxx;}

高级表达式以及增删查改

#include<iostream>
#include<vector>
#include<algorithm>//算法  	lambda表达式,不仅仅适用与array ,也适用于vector

void main1()
{
	std::vector<int> myvector;
	myvector.push_back(11);
	myvector.push_back(22);
	myvector.push_back(33);
	myvector.push_back(3);
	myvector.push_back(4);
	myvector.push_back(5);
	int res=0;//结果
	//&res直接操作一个变量,res等价于返回值,x代表参数,每次充当迭代器指向的元素,大括号就是代码
	std::for_each(myvector.begin(), myvector.end(), [&res](int x){res += x; });
	std::cout << res;
	std::cin.get();
}

void main()
{
	std::vector<int> myvector(5);//分配5个空间,默认初始化为0

	myvector.push_back(1);//增
	myvector.push_back(11);
	myvector.push_back(111);
	myvector.push_back(1111);
	myvector.push_back(2);
	myvector.pop_back();//弹出一个元素,删除最后一个
	myvector.insert(myvector.begin() +1, 999);//插入,
	myvector.erase(myvector.begin()+5);//根据迭代器的位置
	//myvector.clear();//删除所有元素
	for (int i = 0; i < myvector.size(); i++)
	{
		if (1)
		{
			//查询,修改
		}
		std::cout << myvector.at(i) << std::endl;
	}

	system("pause");
}

void main123123()
{
	//可以实现动态无规则数组管理
	std::vector<int> myvetor1;
	myvetor1.push_back(12);
	myvetor1.push_back(13);
	myvetor1.push_back(14);

	std::vector<int> myvetor2;
	myvetor2.push_back(22);

	std::vector<int> myvetor3;
	myvetor3.push_back(32);
	myvetor3.push_back(37);

	std::vector<std::vector<int>> allvecor;
	allvecor.push_back(myvetor1);
	allvecor.push_back(myvetor2);
	allvecor.push_back(myvetor3);
	for (int i = 0; i < allvecor.size(); i++)
	{
		for (int j = 0; j < allvecor[i].size(); j++)
		{
			std::cout <<"  "<< allvecor[i][j];
		}
		std::cout << "\n";
	}
	
	std::cin.get();
}

动态不规则数组以及增删查改 

#include<iostream>
#include<array>
#include<vector>//C++的标准库
#include<string>//C++字符串

using  std::array;//静态数组,栈上,
using std::vector;//动态数组,堆上,
using std::string;

//使用C++风格数组不需要管理内存。
//array注意不要栈溢出
//array适用于任何类型

void main1()
{	
	array<int, 5> myint = { 1, 2, 3, 4, 5 };
	array<int, 1024 * 256> myint1;
	vector<double> myvector; //动态数组
	for (int i = 0; i < 1024 * 1024; i++)
	{
		myvector.push_back(i);//
	}

	std::cin.get();
}

void main2()
{
	array<int, 5> myint1 = { 1, 2, 3, 4, 5 };
	array<int, 5> myint2 = { 11, 12, 13, 14, 15 };
	array<int, 5> myint3 = { 21, 22, 23, 24, 25 };
//	array<array<int, 5>, 3> myint = {myint1,myint2,myint3};
	array<array<int, 5>, 3> myint = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
	for (int i = 0; i < myint.size();i++)//数组大小
	{
		for (int j = 0; j < myint1.size(); j++)
		{
			std::cout << "  "<<myint[i][j];
		}
		std::cout << "\n";
	}

	std::cin.get();
}

void main3()
{
	vector <string>  string1;//动态字符串数组
	//可以反复利用
	string1.push_back("notepad");
	string1.push_back("calc");
	string1.push_back("mspaint");
	string1.pop_back();//删除一个
	//string1.clear();//清空
	for (int i = 0; i < string1.size(); i++)//遍历动态数组
	{
		//system(string1[i].c_str());
	}
}

void main5()
{
	vector <string>  string1;//动态字符串数组
	string1.push_back("notepad");
	string1.push_back("calc");
	string1.push_back("mspaint");

	vector<string>::iterator ibegin, iend;//迭代器
	ibegin = string1.begin();//数据起始点
	iend = string1.end();//结束

	for (;ibegin!=iend;ibegin++)
	{
		string tempstr = *ibegin;//获取指针指向的数据
		system(tempstr.c_str());//执行指令
	}
}

void  main6()
{
	array<int, 5> myint = { 1, 2, 3, 4, 5 };
	array<int,5>::iterator ibegin, iend;//正向迭代器
	ibegin = myint.begin();
	iend = myint.end();
	while (ibegin!=iend)
	{
		std::cout << *ibegin << std::endl;
		ibegin++;
	}
	array<int, 5>::reverse_iterator rbegin, rend;
	rbegin = myint.rbegin();
	rend = myint.rend();
	while (rbegin!=rend)
	{
		std::cout << *rbegin << std::endl;
		rbegin++;

	}

	std::cin.get();
}

void main7()
{
	vector <string>  string1;//动态字符串数组
	string1.push_back("notepad");
	string1.push_back("calc");
	string1.push_back("mspaint");
	//反向迭代器
	vector<string>::reverse_iterator rbegin = string1.rbegin();
	vector<string>::reverse_iterator rend = string1.rend();
	//rend--;rend最后不指向数据,指向数据的结尾的下一个节点
A:	if (rbegin!=rend)
	{
		system((*rend).c_str());//执行指令
		//rbegin++;
		rend--;
		goto A;
	}
}

动态数组任意位置插入 

#include<iostream>
#include<vector>
#include<algorithm>//算法  	lambda表达式,不仅仅适用与array ,也适用于vector

void main1()
{
	std::vector<int> myvector;
	myvector.push_back(11);
	myvector.push_back(22);
	myvector.push_back(33);
	myvector.push_back(3);
	myvector.push_back(4);
	myvector.push_back(5);
	int res=0;//结果
	//&res直接操作一个变量,res等价于返回值,x代表参数,每次充当迭代器指向的元素,大括号就是代码
	std::for_each(myvector.begin(), myvector.end(), [&res](int x){res += x; });
	std::cout << res;
	std::cin.get();
}

void main()
{
	std::vector<int> myvector(5);//分配5个空间,默认初始化为0

	myvector.push_back(1);//增
	myvector.push_back(11);
	myvector.push_back(111);
	myvector.push_back(1111);
	myvector.push_back(2);
	myvector.pop_back();//弹出一个元素,删除最后一个
	myvector.insert(myvector.begin() +1, 999);//插入,
	myvector.erase(myvector.begin()+5);//根据迭代器的位置
	//myvector.clear();//删除所有元素
	for (int i = 0; i < myvector.size(); i++)
	{
		if (1)
		{
			//查询,修改
		}
		std::cout << myvector.at(i) << std::endl;
	}

	system("pause");
}

多元数组 tuple

#include<iostream>
#include<map>
//多元数组
//tuple必须是一个静态数组,
//配合vector, array

void main(void)//void在参数内部意味着参数为空,不写也意味着为空
{
	int int1 = 10;
	double double1 = 99.8;
	char ch = 'A';
	char *str = "hellochina";
	std::tuple<int, double, char, const char *> mytuple(int1, double1, ch, str);
	const int num = 3;
	auto data0 = std::get<0>(mytuple);
	auto data1 = std::get<1>(mytuple);
	auto data2 = std::get<2>(mytuple);
	auto data3 = std::get<num>(mytuple);//下标只能是常量
	std::cout <<typeid( data3).name()  << std::endl;
	decltype(data0) dataA;//获取数据类型再次创建
	//mytuple.swap(mytuple);array.vetor都有交换的公能
	std::cout << data0 <<"  " << data1 <<"  "<< data2 << "   " <<data3 << std::endl;

	std::cin.get();
}

new限定区域分配内存的语法

#include<iostream>
#include<new>

const int buf(512);//限定一个常量整数512
int N(5);//数组的长度
char buffer[buf] = {0};//静态区

//p1,p3,p5作为指针变量在栈区,存储的地址指向堆区
//手动释放内存

//p2,p4,p6作为指针变量在栈区,存储的地址在静态区。缓冲区。
//自动释放内存,用于分配用完了就不会再用的数据
//避免内存泄漏,自动释放内存。牺牲了内存访问独立性,

using namespace std;
void main()
{
	double *p1, *p2;
	std::cout << "\n\n\n";
	p1 = new double[N];//分配内存,N个元素的大小
	p2 = new (buffer)double[N];//指定区域分配内存
	for (int i = 0; i < N; i++)
	{
			p1[i] = p2[i] = i + 10.8;//对于数组初始化
			std::cout << "p1===   " << &p1[i] << "  " << p1[i];
			std::cout << "   p2===   " << &p2[i] << "  " << p2[i] << std::endl;
	}

	double *p3, *p4;
	std::cout << "\n\n\n";
	p3 = new double[N];//分配内存,N个元素的大小
	p4 = new (buffer)double[N];//指定区域分配内存	
	for (int i = 0; i < N; i++)
	{
		p3[i] = p4[i] = i + 10.8 ;//对于数组初始化
		std::cout << "p3===   " << &p3[i] << "  " << p3[i];
		std::cout << "   p4===   " << &p4[i] << "  " << p4[i] << std::endl;
	}

	double *p5, *p6;
	std::cout << "\n\n\n";
	p5 = new double[N];//分配内存,N个元素的大小
	p6 = new (buffer)double[N];//指定区域分配内存
	for (int i = 0; i < N; i++)
	{
		p6[i] = p5[i] = i + 10.8;//对于数组初始化
		std::cout << "p5===   " << &p5[i] << "  " << p5[i];
		std::cout << "   p6===   " << &p6[i] << "  " << p6[i] << std::endl;
	}

	std::cin.get();
}

函数模板重载

#include<iostream>
#include<array>
using  std::array;

template<typename T>
void showarray(array<T,10> myarray,int n)
{
	using namespace std;
	cout << "TTTTT" << endl;
	for (int i = 0; i < n;i++)
	{
		cout << myarray[i] <<" ";
	}
	cout << endl;
}

template<typename T>
void showarray(array<T*, 10>  myarray, int n)
{
	using namespace std;
	cout << "T*T*T*T*T*" << endl;
	for (int i = 0; i < n; i++)
	{
		cout << *myarray[i] << " ";
	}
	cout << endl;
}

void main()
{
	array<int, 10> intarray = { 1, 2, 3, 4, 5,6,7,8,9,10 };
	array<int*, 10> pintarray ;
	for (int i = 0; i < 10; i++)
	{
		pintarray[i] = &intarray[i];
	}
	array<int**, 10> ppintarray;
	for (int i = 0; i < 10; i++)
	{
		ppintarray[i] = &pintarray[i];
	}
	showarray(intarray, 10);
	showarray(pintarray, 10);
	showarray(ppintarray, 10);

	std::cin.get();
}













你可能感兴趣的:(【C/C++学院】0815-函数包装器/CPP类型转换/函数模块/动态数组)