c++primer第六章课后习题

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];//括号要对,并且维数必须标明

/**************************************************
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类型
**************************************************/

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)  //错误
2int 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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值