函数模板
函数模板不是一个具体的函数,编译器不能为其生成可执行代码。定义函数模板后只是一个对函数功能框架的描述,当他具体执行时,将根据传递的实际参数决定其功能。
函数模板的定义
template //template 关键字 定义模板返回类型 函数名 (形式参数表){... //函数体}
注:
- <> : 表示模板参数(模板类型参数【class /typedef + 自定义合法标识符】和模板非类型参数【通常为一个常数】)
函数模板的声明
可分两部分:template部分和函数名部分
template //T 表示泛型类型void func(T t) { ... //函数实现 (函数体)}
定义求和函数模板
template //定义模板类型 type Sum(type x ,type y) //定义函数模板{return x+y ;}int ir= Sum(5,10); //调用函数模板,实现整数相加double dr =Sum(5.5,10.5) ; //调用函数模板 ,实现实数相加//int/double ir =Sum(5.5 , 10 ) ; //错误:编译器产生歧义,类型必须统一int ir = Sum(5.5,10);//显示标识模板类型,避免歧义。
模板函数
即用函数模板生成实际可执行的函数。
区别:
- 函数模板是一个“框架”,他不是真正可以编译生成代码的程序。
- 模板函数是把函数模板中的类型参数实例化后生成的函数,它和普通函数本质是相同的,可以生成可执行的代码。
函数模板的作用
函数模板代替普通函数实现抽象操作,减少重复劳动和维护、调试开销。
宏定义
理解:
宏定义又称宏替换,简称“宏”。宏定义是指在 程序中出现一个宏定义的宏名时,在该程序编译之前,先将宏名用被定义的字符串替换,之后才能进行编译。此替换过程称为宏定义。
标识符:
#define
简单宏定义:
#define //例如: #define PI 3.141592653 // 把程序中出现的PI全部换成3.141592653 然后编译#define AUTHOR "JianYunFeng" //“”内的内容不会被替换,且字符串双引号必须完整 --注1。#define 0X 12ab //错误 ,宏名必须为合法的用户标识符(可为关键字)--注2
注:
- 宏名一般用大写
- 宏定义末尾不加分号
- 宏定义写在函数的外面,作用域为其后的程序,通常在文件的开头。
- 可以用#undef命令终止宏定义的作用域。
- 宏定义可以嵌套。
- 字符串“”中不能嵌套宏定义
带参宏定义:
#define () (宏体)//例如:#define J(x,y,z) ((x)^(x)+(y)^(y)+(z)^(z))
注:
- 宏名和参数的括号间不能有空格
- 宏定义只做替换,不做计算及求解
- 宏的替换过程不存在类型,也没有类型转换。
优点:
- 使用宏可提高程序的通用性和易读性,减少不一致性,减少输入错误和便于修改
- 宏定义不分配内存,但是变量定义分配内存,可以节省内存空间。
- 函数只有一个返回值,利用宏规则可以设法得到多个值
- 宏展开不占用运行时间,只占用编译时间,函数调用占用运行时间(包括分配内存、保留现场、值传递、返回值)
缺点:
- 宏展开是源程序变长,函数调用不会。
宏定义中的#的用法
作用:
#用于给参数添加双引号“”。
语法:
#define STR (str) #str//例如:#define STR(ME#AUTHOR) me#author //添加 ----替换后--- "me#author“
注:
- #define STR( ) ) /STR( , ) 等 ,) 和 , 都不会被当做参数。
- 参数过多,编译器会自动省去
宏定义中的##的用法
作用:
##用于左边加引用
语法:
#define STR(str) L##str // -- 翻译过后--Lstr//例如:STR("I love U") ---结果: L"I love U"#define FUN(a,b) vo##a##b()// FUN(id ma ,in) --结果为: void main()
宏定义中# 和## 的用法
1.使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起。
2.合并匿名变量
3.填充结构
4.记录文件名
5.得到一个数值类型所对应的字符串缓冲大小
本文部分内容参考至网络,如有错误,敬请指正,如有侵权,请联系修改,如有疑问,欢迎提出讨论,谢谢。