首页 > 编程知识 正文

指针变量作为函数参数通俗易懂,函数解析式

时间:2023-05-04 17:03:05 阅读:25206 作者:1565

c的编程思想之一被称为泛型编程,主要使用的技术是模板

c包括函数模板和http://www.Sina.com/http://www.Sina.com /

函数模板角色:

创建一个用类模板表示的公共函数,但不具体指定函数的返回类型和参数类型

1.函数模板语法

1 .模板类型名称t

2 .声明或定义函数

虚拟的类型

模板:声明模板的创建

typename :后跟的符号是数据类型,表示可以用class替换

t :通用数据类型。 名称是可替换的,通常是大写

语法:

# includeiostreamusingnamespacestd;//两个整数voidswapint(inta,int b ) { int temp=a; a=b; b=temp;//两个浮点数voidswapdouble (双精度,双精度b ) {双精度时间=a; a=b; b=temp; }void test () { int a=10; int b=20; sapint(a,b ); cout'a='aendl; cout'b='bendl; 双精度c=1.1; 双精度d=2.2; swap双精度(c,d ); cout'c='cendl; cout'd='dendl; }int main () { test ); }但是,有很多数据类型,除了int double等以外,还有用户自己定义的结构类型,所以可以看到有无数种。 为了解决这个问题,用模板解决。

代码如下。

//函数模板templatetypename T//typename是classvoidmyswap(ta,T b ) { T temp=a; a=b; b=temp; }模板解释:

让编译器直接判断数据类型,进行运算

# includeiostreamusingnamespacestd; 模板类型名称t//类型名称为classvoidmyswap(ta,T b ) { T temp=a; a=b; b=temp; }void test () { int a=10; int b=20; myswap(a,b ); cout'a='aendl; cout'b='bendl; 双精度c=1.1; 双精度d=2.2; myswap(c,d ); cout'c='cendl; cout'd='dendl; }int main () { test ); } 示例

编译时直接向编译器传达指定的类型

# includeiostreamusingnamespacestd; 模板类型名称t//类型名称为classvoidmyswap(ta,T b ) { T temp=a; a=b; b=temp; }void test () { int a=10; int b=20; myswapint(a,b ); cout'a='aendl; cout'b='bendl; 双精度c=1.1; 双精度d=2.2; myswap双精度(c,d ); cout'c='cendl; cout'd='dendl; }int main () { test ); } ——33543354————————3——33——3————————3——33333——3333——333333——33333333——3333——33——333——33——333——35433333333————

(1).自动类型推导

注意事项:

)1)自动类型导出必须导出一致的数据类型t才能使用

)2)型

板必须要确定出T的数据类型,才可以使用
(1)如:
在前文的test函数中:

void test(){ int a=10; char c='c'; myswap(a,c)//错误}

(2)如:

template<class T>void func(){ cout<<"hello"<<endl;}void test(){ func();}int main(){ test();}

此程序是无法运行的,因为模板没有确定T的数据类型
如果一定要输出,则一定要在调用模板函数时显示数据类型
代码如下:

template<class T>void func(){ cout<<"hello"<<endl;}void test(){ func<int>();//显示数据类型}int main(){ test();}

———————————————————————————————————————

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

#include<iostream>using namespace std;template<class T>void myswap(T &a,T &b){ T temp=a; a=b; b=temp;}//排序算法template<class T>void mysort(T arr[],int len){ int i,j; for(i=0;i<len-1;i++) { int max=i; for(j=i+1;j<len;j++) { if(arr[max]<arr[j]) { max=j;//更新最大值下标 } } if(max!=j) { //交换max和i下标元素 myswap(arr[max],arr[i]); } }}//提供一个打印数组的模板template<class T>void print(T arr[],int len){ for(int i=0;i<len;i++) cout<<arr[i]<<" "; cout<<endl;}void test1(){ char 搞怪的朋友[]="badcfe"; int num=sizeof(搞怪的朋友)/sizeof(char); mysort(搞怪的朋友,num); print(搞怪的朋友,num);}void test2(){ int intArr[]={7,5,1,3,9,2,4,6,8}; int num=sizeof(intArr)/sizeof(int); mysort(intArr,num); print(intArr,num);}int main(){ test1(); test2();}

———————————————————————————————————————

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

这里不做说明

———————————————————————————————————————

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

1.直接上代码

#include<iostream>using namespace std;void myprint(int a,int b){ cout<<"调用的普通函数"<<endl;}template<class T>void myprint(T a,T b){ cout<<"调用的模板"<<endl;}void test(){ int a=10; int b=20; myprint(a,b);}int main(){ test();}

运行结果如下:

上面的例子可以轻松看出一点问题,假如普通函数的语句为myprint(int a,int b);打上分号后 该语句会使得报错,那么这时应该要想到用上函数模板

2.可以通过空模板参数列表 强制调用 函数模板

代码如下:

#include<iostream>using namespace std;void myprint(int a,int b);template<class T>void myprint(T a,T b){ cout<<"调用的模板"<<endl;}void test(){ int a=10; int b=20; //通过空模板参数列表,强制调用函数模板 myprint<>(a,b);}int main(){ test();}

运行结果如下:

3.函数模板也可以发生重载,这点不做程序上的说明,注意下重载的时函数名,里面的变量类型不一定会相同,因此函数调用时会调用变量类型和数量相同的模板函数。

那么第4点所说的“如果函数模板可以产生更好的匹配,优先调用函数模板”是什么意思呢?
上代码:

#include<iostream>using namespace std;void myprint(int a,int b){ cout<<"调用的普通函数"<<endl;}template<class T>void myprint(T a,T b){ cout<<"调用的模板"<<endl;}void test(){ char c1='a'; char c2='b'; myprint(c1,c2);}int main(){ test();}

运行结果如下:

那么为什么会有这样的结果呢?
那是因为在调用普通函数时,编译器会自动把char类型转化为int类型再做交换,但是相比之下,模板函数则不需要做此变换,编译器会自动选择更简单的模板函数的方式调用该函数。

——————————————————————————————————————

6.模板的局限性
例如:

template
void f(T a,T b)
{
a=b;
}

在上述代码中提供的赋值操作,如果传入的a和b是一个数组,就无法实现了

再例如:

template
void f(T a,T b)
{
if(a>b){…}
}

在上述代码中,如果T的数据类型传入的是像Person这样的自定义数据类型,也无法正常运行

因此C++为了解决这种问题,提供模板的重载,可以为这些特定的类型提供具体化的模板

解决方法:
在程序中利用具体化Person的版本实现代码,具体化优先调用
template<>返回值类型 函数名(Person &a,Person &b)
{//写出执行的方式
}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。