C++ Primer 中文版(第 5 版)- 第六单元

第六单元

练习 6.1

编写你自己的fact函数,上机检查是否正确。注:阶乘。

#include <iostream>

int fact(int i)
{
    if(i<0)
    {
        std::runtime_error err("Input cannot be a negative number");
        std::cout << err.what() << std::endl;
    }
    return i > 1 ? i * fact( i - 1 ) : 1;
}

int main()
{
    std::cout << std::boolalpha << (120 == fact(5)) << std::endl;
    return 0;
}

用std::boolalpha,可以输出 "true"或者 “false”。

练习 6.2

编写一个与用户交互的函数,要求用户输入一个数字,计算生成该数字的阶乘。在main函数中调用该函数。

#include <iostream>
#include <string>

int fact(int i)
{
    return i > 1 ? i * fact(i - 1) : 1;
}

void interactive_fact()
{
    std::string const prompt = "Enter a number within [1, 13) :\n";
    std::string const out_of_range = "Out of range, please try again.\n";
    for (int i; std::cout << prompt, std::cin >> i; )
    {
        if (i < 1 || i > 12)
        {
            std::cout << out_of_range; 
            continue;
        }
        std::cout << fact(i) << std::endl;
    }
}

int main()
{
    interactive_fact();
    return 0;
}
练习 6.3

编写一个函数输出其实参的绝对值。

#include <iostream>

int abs(int i)
{
   return i > 0 ? i : -i;
}

int main()
{
   std::cout << abs(-5) << std::endl;
   return 0;
}
练习 6.4

说明形参、局部变量以及局部静态变量的区别。编写一个函数,同时达到这三种形式。
解:
形参定义在函数形参列表里面;局部变量定义在代码块里面; 局部静态变量在程序的执行路径第一次经过对象定义语句时初始化,并且直到程序终止时才被销毁。

// 例子
int count_add(int n)       // n是形参
{
    static int ctr = 0;    // ctr 是局部静态变量
    ctr += n;
    return ctr;
}

int main()
{
    for (int i = 0; i != 10; ++i)  // i 是局部变量
      cout << count_add(i) << endl;

    return 0;
}
练习 6.5

编写一个函数,当它第一次被调用时返回0,以后每次被调用返回值加1。

#include <iostream>
int generate()
{
    static int ctr = 0;
    return ctr++;
}

int main()
{
    
    for (int i=0; i<10; i++) {
       std::cout<< generate()<<std::endl;
    }
    return 0;
}
练习 6.6

编写一个名为Chapter6.h 的头文件,令其包含6.1节练习中的函数声明。


int fact(int val);
int func();

template <typename T>

T abs(T i)
{
    return i >= 0 ? i : -i;
}
练习 6.7

编写你自己的fact.cc 和factMain.cc ,这两个文件都应该包含上一小节的练习中编写的 Chapter6.h 头文件。通过这些文件,理解你的编译器是如何支持分离式编译的。

#include "Chapter6.h"
#include <iostream>

int fact(int val)
{
    if (val == 0 || val == 1) return 1;
    else return val * fact(val-1);
}

int func()
{
    int n, ret = 1;
    std::cout << "input a number: ";
    std::cin >> n;
    while (n > 1) ret *= n--;
    return ret;
}

#include "Chapter6.h"
#include <iostream>

int main()
{
    std::cout << "5! is " << fact(5) << std::endl; 
    std::cout << func() << std::endl; 
    std::cout << abs(-9.78) << std::endl;
}
练习 6.8

编写一个函数,使用指针形参交换两个整数的值。 在代码中调用该函数并输出交换后的结果,以此验证函数的正确性。

#include <iostream>
#include <string>

void swap(int* lhs, int* rhs)
{
	int tmp;
	tmp = *lhs;
	*lhs = *rhs;
	*rhs = tmp;
}

int main()
{
	for (int lft, rht; std::cout << "Please Enter:\n", std::cin >> lft >> rht;)
	{
		swap(&lft, &rht);
		std::cout << lft << " " << rht << std::endl;
	}

	return 0;
}
练习 6.9

编写并验证你自己的reset函数,使其作用于引用类型的参数。注:reset即置0。

#include <iostream>

void reset(int &i)
{
    i = 0;
}

int main()
{
    int i = 42;
    reset(i);
    std::cout << i  << std::endl;
    return 0;
}
练习 6.10

改写程序,使其引用而非指针交换两个整数的值。

#include <iostream>
#include <string>


void swap(int& lhs, int& rhs)
{
    int temp = lhs;
    lhs = rhs;
    rhs = temp;
}

int main()
{
    for (int left, right; std::cout << "Please Enter:\n", std::cin >> left >> right; )
    {
        swap(left, right);
        std::cout << left << " " << right << std::endl;
    }

    return 0;
}
练习 6.11

编写一个函数,令其接受两个参数:一个是int型的数,另一个是int指针。 函数比较int的值和指针所指的值,返回较大的那个。

#include <iostream>
using std::cout;

int larger_one(const int i, const int *p)
{
    return (i > *p) ? i : *p;
}

int main()
{
    int i = 6;
    cout << larger_one(7, &i);

    return 0;
}
练习 6.12

编写一个函数,令其交换两个int指针。

#include <iostream>
#include <string>

void swap(int*& lft, int*& rht)
{
    auto tmp = lft;
    lft = rht;
    rht = tmp;
}

int main()
{
    int i = 42, j = 99;
    auto lft = &i;
    auto rht = &j;
    swap(lft, rht);
    std::cout << *lft << " " << *rht << std::endl;

    return 0;
}
练习 6.13
#include <iostream>
using std::cout; using std::endl; using std::begin; using std::end;

void print(const int *pi)
{
    if(pi)
        cout << *pi << endl;
}

void print(const char *p)
{
    if (p)
        while (*p) cout << *p++;
    cout << endl;
}

void print(const int *beg, const int *end)
{
    while (beg != end)
        cout << *beg++ << endl;
}

void print(const int ia[], size_t size)
{
    for (size_t i = 0; i != size; ++i) {
        cout << ia[i] << endl;
    }
}

void print(int (&arr)[2])
{
    for (auto i : arr)
        cout << i << endl;
}

int main()
{
    int i = 0, j[2] = { 0, 1 };
    char ch[5] = "pezy";
    
    print(ch);
    print(begin(j), end(j));
    print(&i);
    print(j, end(j)-begin(j));
    print(j);
    
    return 0;
}
练习 6.14

编写一个函数,它的参数是initializer_list类型的对象,函数的功能是计算列表中所有元素的和。

#include <iostream>
#include <initializer_list>

int sum(std::initializer_list<int> const& il)
{
    int sum = 0;
    for (auto i : il) sum += i;
    return sum;
}

int main(void)
{
    auto il = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    std::cout << sum(il) << std::endl;

    return 0;
}
练习 6.15

编写一个递归函数,输出vector对象的内容。

#include <iostream>
#include <vector>
using std::vector; using std::cout;
using Iter = vector<int>::const_iterator;

void print(Iter first, Iter last)
{
    if (first != last)
    {
        cout << *first << " ";
        print(++first, last);
    }
}

int main()
{
    vector<int> vec{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    print(vec.cbegin(), vec.cend());

    return 0;
}
练习 6.16

给make_plural函数的第二个形参赋予默认实参’s’, 利用新版本的函数输出单词success和failure的单数和复数形式。

#include <iostream>
#include <string>

using std::string;
using std::cout;
using std::endl;

string make_plural(size_t ctr, const string& word, const string& ending = "s")
{
	return (ctr > 1) ? word + ending : word;
}

int main()
{
	cout << "single: " << make_plural(1, "success", "es") << " "
		<< make_plural(1, "failure") << endl;
	cout << "plural : " << make_plural(2, "success", "es") << " "
		<< make_plural(2, "failure") << endl;

	return 0;
}
练习 6.17

改写6.3.2节练习中使用递归输出vector内容的程序,使其有条件地输出与执行过程有关的信息。 例如,每次调用时输出vector对象的大小。 分别在打开和关闭调试器的情况下编译并执行这个程序。

#include <iostream>
#include <vector>
using std::vector; using std::cout; using std::endl;

void printVec(vector<int> &vec)
{
#ifndef NDEBUG
    cout << "vector size: " << vec.size() << endl;
#endif
    if (!vec.empty())
    {
        auto tmp = vec.back();
        vec.pop_back();
        printVec(vec);
        cout << tmp << " ";
    }
}

int main()
{
    vector<int> vec{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    printVec(vec);
    cout << endl;

    return 0;
}
练习 6.18

编写函数f的4版本,令其各输出一条可以区分的消息。 验证上一个练习的答案,如果你的回答错了,反复研究本节内容直到你弄清自己错在何处。

#include <iostream>
using std::cout; using std::endl;

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

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

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

void f(double, double)
{
    cout << "f(double, double)" << endl;
}

int main()
{
    f(42);
    f(42, 0);
    f(2.56, 3.14);
    
    return 0;
}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 《C Primer 中文版(第5)》是一本非常经典的C语言学习教材,其分为18章,内容从简单的语法讲解到高级语言特性,非常全面。书中通过大量实例介绍了C语言的各种基础概念,例如:变量、函数、数组、指针和结构体等,包含了语言的所有核心要点,并且通过编程实践帮助读者快速掌握语法知识。此外,本书着重于C语言与C++语言的区别与联系,介绍了C语言与C++语言的相似点与不同之处,帮助读者更好地理解这两种语言。书中的练习题有助于巩固所学知识,提高编程思维。本书不仅适用于有编程基础的读者,还适合初学者学习。总之,《C Primer 中文版(第5)》是一本高质量的教材,不论是学习编程还是提高技能都是必读的书籍之一。 ### 回答2: 《C Primer 中文版》第五是一本C语言入门的经典教材。它通过清晰而详细的讲解和大量的实例案例,帮助读者真正理解C语言的基础知识和编程技巧。本书共分为18章,从C语言基础数据类型、算术运算符和控制语句开始讲起,一直解释到高级操作,如函数指针和位运算等。 此外,本书还介绍了C语言中常用的数据类型、函数、指针、字符串、结构体、共用体、位操作以及文件操作等知识点。不仅如此,每一章节结尾还提供了大量的练习题目,并配有答案和解析,有助于提高读者的理解和实战能力。 值得一提的是,本书特别适合初学者学习。在阐述概念的同时,作者以简单易懂的方式呈现实际应用场景,让读者理解问题的本质和解决方案,避免了知识的孤立性和抽象性,提高了学习效率。 总之,《C Primer 中文版》第五是一本入门级的C语言教材,涵盖了C语言基础知识和编程技巧,可供初学者参考和学习。本书适合自学或作为课程的教材使用。建议学习者掌握C语言基础后,再深入学习与实践。 ### 回答3: 《C Primer中文版(第5)》是一本C语言入门级别的教材,主要介绍了C语言的基本概念、语法规则、程序设计方法以及C语言的特点和应用领域等方面的内容。本书内容丰富、系统性强,适合初学者从零起步学习。 本书共分为18章,内容包括基本数据类型、数组、字符序列和字符串、指针、函数、结构体和联合体、动态内存分配、位运算、输入和输出、预处理器和C库等。同时,本书也介绍了一些实际应用案例,例如文件操作和排序算法等,可以帮助读者更好地理解和应用C语言。 除了书籍内容之外,本书还有一些非常实用的附录,例如C语言关键字和标识符、ASCII码表、格式说明符和转义字符等,可以帮助读者更加深入地了解C语言的具体使用方法。 总之,《C Primer中文版(第5)》是一本很好的C语言入门教材,无论是初学者还是对C语言有一定了解的读者都可以从中获得很多帮助和收获。同时,本书语言简洁清晰,结构合理,对于初学者来说,是一本很好的自学教材。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

为啥全要学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值