第六章 函数
来源:互联网 发布:仓管软件免费版 编辑:程序博客网 时间:2024/06/07 00:39
一、参数传递
1、在C++中建议使用引用类型的形参替代指针类型的形参。使用引用同时也能避免参数传递时的拷贝,可以提高效率。如果某些类型不支持拷贝操作(如IO类型),函数只能通过引用形参访问该类型对象。如果函数无须改变引用形参的值,最好将其使命为常量引用。
// 比较两个string对象的长度 bool isShorter(const string &s1, const string &s2) { return s1.size() < s2.size(); }
2、指针或引用形参与const:形参的初始化方式和变量的初始化方式是一样的。
3、数组形参:
char str[] = "Fuck you!"; // 以下三个函数形式都可以用str数组传参,在函数中都可以使用形参对str数组进行访问 print(const char str[]) print(const char str[10]) print(const char *str)
以上函数在使用形参的时候并不知道实参数组的大小,所以可能引发数组越界。所以产生了以下三种管理指针形参的技术:
- 使用标记指定数组长度
void print(const char *str){ if(str)while(*str)// 只要指针所指的字符不是空字符标记 cout << *str++; cout << endl;}// 以上对于像int类型的数组就不太适用了
- 使用标准库规范:传递数组首元素和尾后元素的指针
int ia[] = {1,2,3,4,5,6};void print(const int *beg, const int *end){ while(beg != end) cout << *beg++; cout << endl;}// 使用C++ 11标准提供的begin()和end()函数获取数组的首元素指针和尾后指针并作为实参调用函数print(begin(ia), end(ia));
- 显式传递一个表示数组大小的形参
// const int ia[] 等价于 const int *iavoid print(const int ia[], size_t size){ for(size_t i = 0; i != size; ++i) {cout << ia[i]; } cout << endl;}// 调用printprint(ia, end(ia) - begin(ia));
函数参数允许定义为数组的引用:
void print(int (&ia)[10]);// 定义时的小括号比不可少,纬度是类型的一部分 int i = 0, j[2] = {0,1}, k[10] = {0,1,2,3,4,5,6,7,8,9}; print(&i);// 错误:数组长度不是10 print(j);// 错误:数组长度不是10 print(k);// 正确
4、传递多维数组参数
// 由于多维数组就是数组的数组,在传递多维数组时应该用以下的方式定义 void print(int (*matrix)[10], int rowSize);// 传递的数组是由10个整数构成的数组 voed print(int matrix[][10], int rowSize);// 与上是等价定义
5、含有可变形参的函数
- 实参类型相同:传递initializer_list的标准库类型(头文件<initializer_list>),提供以下操作:
initializer_list<T> list; // 默认初始化
initializer_list<T> list{a,b,c,d}; // list的元素是对应初始值的副本;列表中的元素是const类型的
list2(list);
list2 = list;
list.size(); // 列表中元素的数量
list.begin(); // 返回list中首元素的指针
list.end(); // 返回指向list中尾元素下一位置的指针 - 省略符形参
- 可变参数模版
二、因为数组不能拷贝赋值,所以函数不能返回数组。不过,函数可以返回数组的指针或引用。定义一个返回数组的指针或引用的函数的方法如下:
typedef int iarrT[10];// 含有10个整数的数组类型 using iarrT = int[10];// 与上等价定义 iarrT* function(int i);// 使用类型别名定义 int (*function(int i))[10];// 这种原始定义太繁琐 auto function(int i) -> int(*)[10];// C++11中的尾置返回类型 decltype(iarrT) *function(int i);// 使用C++11中的decltype类型推断定义
三、特殊用途语言特性
1、默认实参:一旦某个形参被赋予了默认值,它后面的所有形参都必须有默认值。
2、内联函数:内联函数可以避免函数调用的开销。一般来说,内联机制用于优化规模较小、流程直接、频繁调用的函数。很多编译器都不支持内联递归函数,而且一个几十行上百行的代码也不大可能在调用点内联的展开。
constexpr函数:是指能用于常量表达式的函数。约定:函数的参数和返回值都得是字面值类型,而且函数中必须有且只有一条return语句,函数内可以有其他语句,只要这些语句在运行时不执行任何操作就行。constexpr函数返回的不一定是常量表达式。
通常把内联函数和constexpr函数定义在头文件内。
3、assert(expr)。assert宏在头文件cassert中定义。
NDEBUG预处理变量。#define NDEBUG 后,不在运行assert语句。除了用assert以外,还可以结合使用#ifndef NDEBUG、#endif编写自己的条件调试代码。
预处理器定义了另外4个对调试程序很有用的名字:__FILE__、__LINE__、__TIME__、__DATE__。
四、函数指针
bool lengthCompare(const string &str1, const string &str2); bool (*pf)(const string &, const string &);// *pf两端的括号必不可少 pf = lengthCompare; pf = &lengthCompare;// 取地址符是可选的 bool b1 = pf("hello", "goodbye"); bool b2 = (*pf)("hello", "goodbye"); bool b3 = lengthCompare("hello", "goodbye");
- 第六章 –函数
- 第六章 函数
- 第六章 函数
- 第六章函数
- 第六章 函数
- 第六章-函数
- 第六章 函数
- 第六章 函数
- 第六章 函数
- 第六章—函数
- 第六章分组函数
- 第六章 认识函数
- 第六章函数
- 第六章 函数
- 第六章 函数
- 第六章: 自定义函数
- 【第六章】 函数
- partone---第六章 函数
- JQuery mouseover与mouseenter,mouseout与mouseleave的区别
- hdu2027 统计元音
- Android在浏览器启动APP
- Mounting HGFS shares: FAILED
- Julia:关于split的用法
- 第六章 函数
- 开发中应该注意的小细节二
- BestCoder Round #2 1001 TIANKENG’s restaurant(区间内查找)
- C# DataGridView 代码实现选中一行数据
- Android国际化
- 抽屉原理入门
- 浏览器的时钟精度
- ORACLE 毫秒与日期的相互转换
- Qt QTreeWidget 树形结构实现 .