您的位置:首页 > 编程语言 > C语言/C++

c++primer第六章课后习题

2017-10-26 18:00 411 查看
6.27 用initializer_list 类型传参 求一列数的和

#include <iostream>
#include <string>
#include <initializer_list>
using namespace std;

int fun(std::initializer_list<int> list)
{
int sum = 0;

for (auto i = list.begin(); i != list.end(); i++)
{
sum += *i;
}

return sum;
}

int main()
{
int i = 1, j = 2, k = 3;
cout <<fun({i, j, k}) << endl;  // 注意这里要加花括号
return 0;
}
//返回类型
#include <iostream>
using namespace std;
// 返回引用类型
const string & shoutstring(const string &str1, const string &str2)
{
return str1.size() <= str2.size() ? str1 : str2 ;
}// 都是用的const类型 所以其字符串值不变

// 返回string类型


6.32

知识点1:返回的引用无效:局部临时变量或者局部对象的引用对于返回都是无效的,因为在函数终止之后,局部变量或者对象的引用不再指向有效的内存区域。若是常量在函数调用之前存在,引用即可用。

知识点2:可以对返回值是非常量引用的函数结果赋值。

6.33写一个递归函数,输出vector对象的值

//注意传参
#include <iostream>
#include <vector>
using namespace std;
using iter = vector<int>::iterator;

void fun(iter beg, iter end)  // 递归输出容器的值
{
if (beg != end)
cout << *beg++ << "\n";
else
return ;

fun(beg, end); // 递归
}
int main()
{
int a[5] = {1, 2, 3, 4, 5};
vector<int>b(a, a+5);

fun(b.begin(), b.end());
return 0;
}


6.36:编写一个函数声明,使其返回数组的引用并且该数组包含10个string对象(不要使用尾置返回类型,decltype或者类型别名)

int (*func(int val))[10];//括号要对,并且维数必须标明

/[b]**************************************************[/b]

type (*function_name(parameter list))[dimension]

逐层的理解:func(int i),名为func的函数有一个int型的参数i

(*func(int i)),表明我们可以对函数返回的结果进行解引用操作

(*func(int i))[10],表明对函数的解引用可以得到大小为10的数组

int (*func(int i))[10],表示数组中的元素是int类型

[b]**************************************************[/b]/

string (&func(string (&arrStr)[10]))[10]

6.37 为上一题在写三个声明:

using ArrT = string[10];
ArrT& func1(ArrT& arr);//使用类型别名

auto func2(ArrT& arr) -> string(&)[10]; //使用尾置返回类型

string arrS[10];
decltype(arrS)& func3(ArrT& arr);//使用decltype关键字


函数重载 重点

知识点:如果同一个作用域的几个函数的名字相同但形参不同,我们称之为重载函数

1:如果连个函数只有返回类型不同,则第二个声明错误

int fun(int i)
bool fun(int i)  //错误


2:int fun(const string &);
int fun(string &)  // 正确 指针也是正确的


但是如果是 (const int i) 和(int i) 错误

知识点:知识点1:函数反复调用的过程中重复出现的形参,这样的值被称为默认实参。该参数在使用过程中可以被用户指定,也可以使用默认数值

知识点2:调用含有默认实参的函数时,可以包含该实参,也可以省略该实参。

知识点3:一旦某个形参被赋予了默认值,其后所有形参都必须有默认值。

知识点4:顺序很重要!在设计函数时,将默认值的形参放在后面。

知识点5:在给定的作用域中,一个形参只能被赋予一次默认实参,且局部变量不能作为默认实参。

6.40:a正确 b错误 char background 缺少默认参数

6.41 a错误 应该为ht赋值, b正确, c 合法但是wd会被赋值成*

6.42

#include <iostream>
#include<string>
#include<vector>
using namespace std;

string make_plural(size_t ctr, const string& word, const string& ending = "s")//此处觉得题目描述有误,应该是第三个形参赋予"s",应为是字符串。
{
//size_t表示的是unsigned int
return (ctr > 1) ? word+ending : word;
}
int main(int argc, char *argv[])
{
cout<<"两单词的单数形式:"<<make_plural(1,"success","es")<<"  "<<make_plural(1,"failure")<<endl;
cout<<"两单词的复数形式:"<<make_plural(2,"success","es")<<"  "<<make_plural(2,"failure")<<endl;
return 0;//代表执行成功
}


6.47 目前还不太懂

#include <iostream>
#include <vector>
#include <string>
using namespace std;

void digui(vector<int> &vec)
{
#ifndef NDEBUG
cout << "vector size:" << vec.size() << endl;
#endif
if (!vec.empty())
{
auto tmp = vec.back();
vec.pop_back();
digui(vec);
cout << tmp << " ";
}
}
int main()
{
vector<int> vec{1,2,3,4,5,6};  // 从方法在后面
digui(vec);
return 0;
}


函数匹配知识点:

选定调用函数的候选集,选出可行函数(

特征:1形参数量与本次调用提供的实参数量相等 2 每个实参的类型与对应的形参类型相同,或者能转换成形参的类型)

如果函数含有默认实参,则在调用时传入的实参可能少于它的实际使用实参数量

对于fun(1, 2.2)

声明为:fun(int,int)和fun(double double)报错

fun(long) 和fun(float) fun(3.14)二义性报错

因为就第一个实参来说选前一个好,就第二个实参来说选第二个好;这样会造成二义性所以错误

重载时最好避免强制类型转换

6.49:候选函数:选定本次调用对应的重载函数集,集合中的函数称为候选函数

6.51

#include <iostream>
using namespace std;

void f()
{
cout << i << " "<< j << endl;
}

void f(int i)
{
cout << i << endl;
}

void f(int i, int j)
{
cout << i << " " << j << endl;
}

void f(double i, double j)
{
cout << i << " " << j << endl;
}
int main()
{
f(2.56, 42); // 编译器报错
f(42);
f(42, 0);
f(2.56, 3.14);
return 0;
}


难点:————————

函数指针和指针函数

http://blog.sina.com.cn/s/blog_9e2e84050101cche.html

http://www.cnblogs.com/shenlian/archive/2011/05/21/2053149.html

http://wenku.baidu.com/view/e9efb70879563c1ec5da7153.html

指针函数:int * p (形参) 其返回值是一个int *类型 ,即返回指针的函数

函数指针 int (*p) (形参); int f(int); p = &f;

int (*f(int)) (int );

p 是指向返回值为 int的函数 的指针

上面就p而言 一个是函数名(指针函数), 一个是指针变量(函数指针)

6.54

知识点1:函数指针指向的是函数并非对象。想要声明一个指向函数的指针只要用指针替代函数名即可

知识点2:当我们把函数名当作一个值使用时,函数自动的转换为指针,直接赋予或者取址皆可。可以直接使用只想该函数的指针调用该函数。

知识点3:给指针赋予nullptr或者0时,指针不指向任何函数。

知识点4:函数重载时,指针的类型必须与重载函数精确匹配,包括形参类型数量和返回值类型。

知识点5:虽然不能返回一个函数,但是可以返回一个指向函数的指针。

bool (*p)(const string &, const string &)// p是一个指向一个函数返回值为bool 的指针,

int (*f(int))(int, int);//f有形参列表,f是个函数,f的返回值为指针,指针本身又有参数列表,因此指针指向的是函数,该函数的类型为int
//难点
#include <iostream>
#include<string>
#include<vector>
using namespace std;

int f(int a, int b)
{
return a+b;
}//声明定义该函数

int main(int argc, char** argv)
{
typedef int(*p)(int a, int b);  //声明函数指针,未初始化,p为指向函数的指针。使用typedef的声明语句定义的不再是变量而是类型别名
//就是将变量转化为类型别名的一种方式,p原来是指向函数的指针变量,现在变成了指向函数的指针变量的类型别名
vector<p> a;
return 0;
}
//或者:
//这个更加全面
int func(int a, int b);

using pFunc1 = decltype(func) *;
typedef decltype(func) *pFunc2;
using pFunc3 = int (*)(int a, int b);
using pFunc4 = int(int a, int b);
typedef int(*pFunc5)(int a, int b);
using pFunc6 = decltype(func);

std::vector<pFunc1> vec1;
std::vector<pFunc2> vec2;
std::vector<pFunc3> vec3;
std::vector<pFunc4*> vec4;
std::vector<pFunc5> vec5;
std::vector<pFunc6*> vec6;


6.56
#include <iostream>
#include <vector>
#include <string>
using namespace std;

//typedef  int(*p)(const int i, const int j);

int sum(const int i, const int j) // 加
{
return i+j;
}

int sub(const int i, const int j) // 减
{
return i - j;
}

int mul(const int i,const int j) // 乘
{
return i*j;
}

int di(const int i, const int j)  // 除
{
return i/j;
}

//vector<p> a{sum, sub, mul, div};
int main()
{

typedef int(*p)(const int i, const int j);
// 声明函数指针,未初始化 p为指向函数指针。使用typedef声明语句定义的不再是变量而是类型名
//就是将变量转化类型别名的一种方法,p原来是指向函数的指针变量,现在变成了指向函数的指针变量的类型别名
vector<p> a{sum, sub, mul,di};

for (auto i = a.begin(); i != a.end(); i++)
{
cout << (*i)(4, 2) << "  " << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: