学习目标:
C++11函数
学习内容:
1.函数基础
2.参数传递
3.返回类型和return语句
4.函数重载
5.特殊用途语言特性
6.函数匹配
7.函数指针
题目解析:
6.1
形参在函数的定义中声明
实参是形参的初始值
6.2
(a)返回类型不是函数的类型
(b)函数定义没有返回类型
(c)形参不能同名,函数体缺少左花括号
(d)定义函数体的部分缺少两边的花括号
6.3
int fact(int val, int)
{
int ret = 1;
while (val > 1)
ret *= val--;
return ret;
}
int main()
{
int j = fact(5,9);
cout << "5!是" << j;
return 0;
}
6.4
int fact(int val)
{
int ret = 1;
while (val > 1)
ret *= val--;
return ret;
}
int main()
{
int j;
std::cin >> j;
cout << j << "的阶层是" << fact(j) << " ";
return 0;
}
6.5
int iact(int val)
{
if (val > 0)
val;
else
val = -val;
return val;
}
int main()
{
int j;
std::cin >> j;
cout << iact(j) << " ";
return 0;
}
6.6
形参是局部变量的一种
形参和函数体内部定义的 变量统称为局部变量
局部静态变量的生命周期贯穿函数调用及之后的时间
size_t st( int n)
{
static size_t ctr = 0;
ctr += n;
return ctr;
}
int main()
{
for (size_t i = 0; i != 10; ++i)
cout << st(i) << endl;
return 0;
}
6.7
size_t st(int n)
{
return ++n;
}
int main()
{
int i;
while (std::cin >> i)
cout << st(i) << endl;
return 0;
}
6.8
6.9
6.10
#include<iostream>
void reset(int *ip, int *pp)
{
int ipp = 0;
ipp = *ip;
*ip = *pp;
*pp = ipp;
}
int main() {
int i1 = 1, i2 = 2;
reset(&i1, &i2);
std::cout << i1 << " " << i2;
}
6.11
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::cin;
using std::endl;
void reset(int &i)
{
i = 0;
}
int main()
{
int i = 100;
cout << i << endl;
reset(i);
cout << i;
return 0;
}
6.12
使用引用更易于使用,使用引用形参只需要把形参改成引用类型即可。
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::cin;
using std::endl;
void reset(int &ip, int &pp)
{
int ipp = 0;
ipp = ip;
ip = pp;
pp = ipp;
}
int main() {
int i1 = 1, i2 = 2;
reset(i1, i2);
std::cout << i1 << " " << i2;
}
6.13
f(T)是传值调用
f(T&)是传引用调用
6.14
//引用类型的例子
void reset(int &ip, int &pp)
{
int ipp = 0;
ipp = ip;
ip = pp;
pp = ipp;
}
//不是引用类型的例子
size_t st(int n)
{
return ++n;
}
6.15
s不需要改变实参,occurs需要改变实参
s可能会很大,occurs对象值需要改变,c没有上述两点
不会发生什么只是程序不够完备了
将会报错,occurs是需要改变的值
6.16
如果把普通引用的形参改成常量的引用形参会更好,因为后者可以接受更多实参类型。
bool is_empty(const string& s) { return s.empty(); }
6.17
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::cin;
using std::endl;
bool is_upper(const string &s)
{
for (auto i : s)
{
if (isupper(i)) return true;
}
return false;
}
void is_tolower(string &v)
{
string st;
for (auto &i1 : v)
i1 = tolower(i1);
}
int main()
{
string sss;
if (cin >> sss) {
cout << (is_upper(sss) ? "有大写" : "无大写") << endl;
cout << sss;
is_tolower(sss);
cout << "大写改小写:" << sss << endl;
}
}
6.18
(a)bool compare (matrix &m1, matrix &m2)
(b)vector<int>::iterator chang_val( int i, vector<int>::iterator i2)
6.19
不合法
合法
合法
合法
6.20
无需改变实参值时
可能会报错,比如非常量引用引用字面值
6.21
int map(int i1, int *i2)
{
return i1 > *i2 ? i1 : *i2;
}
int main()
{
int i3 = 1, i4 = 2;
cout << map(i3, &i4) << endl;
}
传入的实参类型是int*
6.22
void ipp(int *&i1, int *&i2)
{
int *i3;
i3 = i1;
i1 = i2;
i2 = i3;
}
int main()
{
int i = 0, j = 1;
int *pi = &i, *pj = &j;
std::cout << pi << " " << pj << std::endl;
ipp(pi, pj);
std::cout << pi << " " << pj << std::endl;
return 0;
}
6.23
暂缓
6.24
如果传入的数组不是含有10个元素的数组,for循环数组可能会导致越界,应改为
viod print (const int (&ia)[10])
6.25
#include <iostream>
void main(int argc, char *argv[])
{
std::string s1 = argv[1], s2 = argv[2];
std::cout << s1 + s2 << std::endl;
}
6.26
#include <iostream>
void main(int argc, char *argv[])
{
std::string s1 = argv[1], s2 = argv[2], s3 = argv[3],
s4 = argv[4], s5 = argv[5];
std::cout << s1 + " " + s2 + " " + s3 + " " + s4 + " " +s5 << std::endl;
}
6.27
int cn(std::initializer_list<int> il)
{
int iv = 0;
for (auto ii : il)
iv += ii;
return iv;
}
int main(int argc, char *argv[])
{
cout << cn({ 1,2,3,4 }) << endl;
}
6.28
const string&
6.29
如果拷贝消耗大,使用引用会更节省性能
6.30
str_subrange没有返回值
str_subrange不是所有控件的返回值
6.31
引用的是函数内的变量时,引用的是函数内的常量时。
6.32
合法,返回数组ia[0]~ia[9]
6.33
#include <iostream>
#include <string>
#include <vector>
#include <initializer_list>
using std::string;
using std::vector;
using std::cout;
using std::cin;
using std::endl;
void vvv(vector<int> ::const_iterator iterator_begin, vector<int>::const_iterator iterator_end)
{
if (iterator_begin != iterator_end)
{
cout << *iterator_begin << " ";
return vvv(++iterator_begin, iterator_end);
}
else
cout << endl;
return;
}
int main()
{
vector<int> i = { 1,2,3,4,5 };
vvv(i.begin(), i.end());
return 0;
}
6.34
如果val大于0,会多乘一个1
如果val小于0,函数将会不断地调用它自身直到程序栈空间耗尽为止
6.35
val–返回未修改的值,使程序进入死循环
6.36
暂缓6.37 6.38
6.39
(a)合法,重复声明可以int calc(int ,int),重复定义不行
(b)非法,不可以在只有返回类型不一致参数数量和类型一致的函数声明
(c)合法,参数类型不一致
6.40
(a)正确
(b)错误,一旦某个形参被赋予默认值,它后面的所有形参都必须有默认值
6.41
(a)非法,函数第一个没有默认实参,必须给实参
(b)合法,等价于char *init (int ht = 24,int wd = 10, char bakgrnd = ‘ ’)
(c)合法,与初衷不符,等价于char *init (int ht = 14,int wd = 42 , char bakgrnd = ‘ ’)
6.42
#include <iostream>
#include <string>
using std::string;
string make_plural(size_t ctr, const string &word, const string &ending = "s")
{
return (ctr > 1) ? word + ending : word;
}
int main()
{
std::cout << make_plural(2, "success", "es") << std::endl;
std::cout << make_plural(2, "failure") << std::endl;
}
6.43
(a)放在头文件中,他可以多次定义为了保证定义的一致
(b)放在头文件中,声明放在头文件中
6.44
inline bool isShorter(const string &s1, const string &s2)
{
return s1.size() < s2.size();
}
int main()
{
string s{ "fs,sf" }, ss{ "fs,ssf,ds" };
std::cout << isShorter(s, ss) << std::endl;
}
6.45
一般代码量小,运行比较规律的改成内联函数比较好。
6.46
不能,不是常量类型,返回值也不是常量表达式
6.47
暂缓
6.48
使用不合理,assert应该判断不合理的情况,改为
string s;
while (cin >> s && s != sought) { } // 空函数体
assert(!cin || s == sought);
6.49
候选函数是调用的同名函数的集合
可行函数是候选函数中匹配到最佳的函数
6.50
(a)不合法,存在二义性
(b)合法,void f(int)
(c)合法,void f(int, int)
(d)合法,void f(double, double)
6.51
#include <iostream>
void f()
{
std::cout << "f()" << std::endl;
}
void f(int)
{
std::cout << "f(int i)" << std::endl;
}
void f(int, int)
{
std::cout << "f(int, int)" << std::endl;
}
void f(double, double)
{
std::cout << "f(double, double)" << std::endl;
}
int main()
{
f(42);
f(43, 42);
f(3.2, 34.4);
f();
return 0;
}
6.52
(a)3.类型提升
(b)4.算数类型转换
6.53
(a)合法,第一条是对非常量的整型引用,第二条是对常量的引用也可以对非常量前者优先级更高
(b)合法,第一条是指向非常量的整型指针,第二条是对常量的指向整型的指针也可以对非常量前者优先级更高
(c)合法,但重复声明
6.54,6.55,6.56
暂缓