2018.1.3 第六章
main 函数命令处理
agv第一个字符串是程序名,从第二个开始才是真正接受的参数
//编写main函数,接受两个参数,把实参的内容连成一个string输出
//#include "stdafx.h"
#include<iostream>
#include<cstring>//c风格字符串函数头文件
//strlen(s),strcmp(s1,s2),strcat(s1,s2)
using namespace std;
int main(int argc, char** argv)
//第二个形参为c风格字符串,第一个参数代表字符串个数
{
strcat_s(argv[1], 200, argv[2]);//第二个参数缓冲区大小
puts(argv[1]);
cout << endl;
system("pause");
return 0;
}
2018.1.4
6.26 含有可变形参的函数
动机:有时候我们无法提前预知向函数传递几个实参
处理不同实参数量的函数,C++提供了两方法:
(1)initializer_list 模板类型,此时所有的实参类型相同
(2)可变参数模板,可实现实参类型不同的情况(后面再讨论)
1、 initializer_list形参
initializer_list有点像vector类,但是inilializer_list对象元素永远是常量。
#include "stdafx.h"
#include<iostream>
#include<string>
//#include<inilializer_list>//无法打开,该编译器不支持该类
#include<vector>
using namespace std;
//输出错误信息函数
void error_msg(vector<string> alam) {//由于vs15中inilializer_list类文件不支持,故用vector类来模拟
for (auto beg = alam.begin();beg != alam.end();++beg)
cout << *beg << ' ';//单词之间用空格符隔开
cout << endl;
}
int main()
{
string expect="huangbin", actual="huangbin";
if (expect != actual)//不相等,则两者都输出
error_msg({ "functonX", expect, actual });//三个参数
else //相等则表示正常
error_msg({ "functionX", "okay" });//调入两个参数
system("pause");
return 0;
}
输出结果:
##### 省略符形参
6.3 返回类型和return语句
return语句有两种形式:
//无返回值
return;//只能用在返回值为void的函数中,可以用在提前退出,
//有返回值类型
return expression;
- 1
- 2
- 3
- 4
6.3.2 有返回值函数
返回值类型必须与函数返回值类型相等,或者能隐形的转换
值是如何被返回的
拷贝word或者两种之和,复制给调用点临时变量
如果返回时引用类型,则是返回值得别名,所以引用类型或者指针的返回类型千万不能是局部对象。因为函数执行完后,该变量都被销毁,成为也指针。
该函数运行会发生异常,编译不会报错!
返回类类型的函数和调用运算符
引用返回左值
调用一个返回类型为引用的函数得到左值,可以给它复制:
列表初始化返回值
C++11新标准规定,函数可以返回花括号包围的列表,该列表也用来对返回的临时变量进行初始化。
例子:
- 1
如果返回类型是类类型,则由类本身定义初始值如何使用。
主函数main的返回值
如果函数的返回值不为空,则必须返回一个值。但是main函数是个例外,允许main函数没有return语句,因而在函数末尾编译器隐式插入一条return 0语句。
递归循环计算阶乘
int factorial (int val)
{
if (val>1)
return factorial (val-1)*val;
return 1;
}
6.3.3 返回数组指针
定义返回数组指针或引用类型的函数,方法一;
(1)类型别名
- 1
- 2
- 3
声明一个返回数组的指针的函数
- 1
- 2
- 3
第2种方法,不用类型别名:
- 1
- 2
第3种方法;使用位置返回类型(C++11)
- 1
第4种方法:decltype()
- 1
- 2
同理引用类型定义:
- 1
- 2
- 3
- 4
与数组进行对比来看
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
6.4 函数的重载
重载和const形参
- 1
- 2
- 3
- 4
- 5
- 6
6.4.1 重载与作用域
调用函数首先总是在同一区域内找是否有该函数声明,如果找到了,就会忽略外层的同名函数,尽管内层函数参数不匹配,外层匹配。也不会去调用外层的同名函数。
6.5特殊用途的语言特性
6.5.1 默认实参
- 1
- 2
如果调用者不给的实参,则该函数,就用默认值。
不过注意:一旦某个形参被赋予了默认值,它后面的形成必须有默认值
所以要想最后个实参传值,前面的形成必须也给传值。
所以设计默认实参时,最好把那些不怎么改动的形参放在形参列表后面,经常需要个性化的形参放在前面。
6.5.2 内联函数和constexpr函数
6.5.3 内联函数和constexpr函数
#define chapter6
#ifndef chapter6
{}
#endif
6.6 函数匹配
6.6.1 实参类型转换
6.7 函数指针
使用函数指针bool (*pf)(int,int)
以上三个式子含义相同bool b1=pf(1,2); bool b2=*pf(1,2); bool b3=LengthCompare(1,2);
using F=int(int*,int);
using PF=int(*)(int*,int);
PF fl(int);
F *fl(int);//两者等价
//也可以定义如下
int (*fl(int))(int*,int);
//使用尾置返回类型方式
auto fl(int) -> int(*)(int*,int);