Chapter 1

练习1

Exercise 1: 解释为什么程序 1-7 的交换函数没有把形参 x 和 y 所对应的实参的值交换。如何修改代码,使实参的值得到交换?

void swap (int x, int y) {
    // 交换整数 x 和 y
    int temp = x;
    x = y;
    y = temp;
}

在调用 swap() 函数之前,系统会把实参复制给形参,复制过程是由形参类型的复制构造函数来完成的。当函数运行结束后,形参类型的析构函数负责释放形参。当一个函数运行结束时,形参的值不会被复制到对应的实参中,因此,函数调用不会修改与形参对应的实参的值。如果要使得实参的值得到交换,修改代码如下:

void swap (int &x, int &y) {
    int temp = x;
    x = y; 
    y = temp;
}

Exercise 2: 编写一个模板函数 count,返回值是数组 a[0:n-1] 中 value 出现的次数。测试你的代码。

/*
 * Exercise 2
 * Created by Harrytsz 2019-12-31
 */
#include<iostream>
using namespace std;
template<typename T, unsigned N>
size_t count(T (&a)[N],  T value){
    int ans=0;
    for(size_t i = 0; i < N; i ++){
        if(a[i] == value){
            ans++;
        }
    }
    return ans;
}
int main(){
    int a[5] = {1, 1, 4, 2, 1};
    cout << count(a,  1) << endl; // 3
    //double a[5] = {1.0, 1.0, 4.0, 2.0, 1.0};
    //cout << count(a, 1.0) << endl;
    return 0;
}

Exercise 3: 编写一个模板函数 fill,给数组 a[start : end-1] 赋值 value。测试你的代码。

/*
 * Exercise 3
 * Created by Harrytsz 2019-12-31
 */
#include<iostream>
#include<iomanip>
using namespace std;

template<typename T, unsigned N>
void fill(T (&a)[N], T value) {
    for(size_t i = 0; i < N; i++) {
        a[i] = value;
    }
}

int main(){
    int a[5];
    fill(a, 3); // 3 3 3 3 3
//    float a[5];
//    fill(a, 3.0f); // 3.00 3.00 3.00 3.00 3.00
    for(auto v : a)
        cout << setprecision(2) << fixed << v << " "; // 浮点数类型保留两位小数
    return 0;
}

Exercise 4: 编写一个模板 inner_product,返回值是 ∑i=0n−1a[i]∗b[i]\sum_{i=0}^{n-1}a[i]*b[i]i=0n1a[i]b[i]。测试你的代码。

/*
 * Exercise 4
 * Created by Harrytsz 2019-12-31
 */
#include<iostream>
#include<iomanip>
using namespace std;

template<typename T, unsigned N>
T inner_product(T (&a)[N], T (&b)[N]) {
    T ans=0;
    for(size_t i = 0; i < N; i++){
        ans += a[i] * b[i];
    }
    return ans;
}
int main(){
//    int a[5] = {1, 1, 1, 1, 1};
//    int b[5] = {1, 2, 3, 4, 5}; // 15
    float a[5] = {1.0f, 1.0f, 1.0f, 1.0f, 1.0f};
    float b[5] = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f}; // 15.00
    cout << setprecision(2) << fixed << inner_product(a, b) << endl;
    return 0;
}

Exercise 5 : 编写一个模板函数 iota,使 a[i]=value+ia[i]=value+ia[i]=value+i0≤i<n0 \leq i < n0i<n。测试你的代码。

/*
 * Exercise 5
 * Created by Harrytsz 2019-12-31
 */
#include<iostream>
#include<iomanip>
using namespace std;

template<typename T, unsigned N>
void iota(T (&a)[N], T value) {
    for(size_t i = 0; i < N; i++)
        a[i] = value + i;
}
int main(){
//    int a[5]; // 1 2 3 4 5
    float a[5];
    iota(a, 1.0f); // 1.00 2.00 3.00 4.00 5.00
    for(auto v : a)
        cout << setprecision(2) << fixed << v << " ";
    return 0;
}

Exercise 6: 编写一个模板函数 is_sorted,当且仅当 a[0:n-1] 有序时,返回值是 true。测试你的代码。

/*
 * Exercise 6
 * Created by Harrytsz 2019-12-31
 */
#include<iostream>
using namespace std;

template<typename T, unsigned N>
bool is_sorted(T (&a)[N]) {
    for(size_t i = 0; i < N-1; i++){
        if (a[i] < a[i+1]) continue;
        else return false;
    }
    return true;
}
int main(){
//    int a[5] = {1, 5, 2, 4, 3}; // 0
    float a[5] = {1.0f, 2.0f, 3.0f, 4.1f, 4.2f};
    cout << is_sorted(a) << endl; // 1
    return 0;
}

Exercise 7: 编写一个模板函数 mismatch,返回值是使不等式 a[i]≠b[i]a[i] \ne b[i]a[i]=b[i] 成立的最小索引 i, 0≤i<n0 \leq i < n0i<n

/*
 * Exercise 7
 * Created by Harrytsz 2019-12-31
 */
#include<iostream>
using namespace std;

template<typename T, unsigned N>
size_t mismatch(T (&a)[N], T (&b)[N]) {
    size_t ans = -1;
    for(size_t i = 0; i < N; i++) {
        if(a[i] != b[i]) return i;
    }
    return ans;
}
int main(){
//    int a[5] = {1, 2, 3, 4, 5};
//    int b[5] = {1, 2, 3, 4, 6}; // 4
    float a[5] = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f};
    float b[5] = {1.0f, 2.0f, 3.0f, 4.0f, 6.0f}; // 4
    cout << mismatch(a, b) << endl;
    return 0;
}

Exercise 8: 下面的函数头是具有不同签名的函数吗?为什么?

  • int abc(int a, int b, int c)
  • float abc(int a, int b, int c)

两个函数头具有不同的签名,函数签名是由函数的形参类型和形参个数来共同确定的。这两个函数的签名都是 (int, int, int),所以是相同的签名。

Exercise 9: 假设有一个程序包含了程序 1-1 和程序 1-2 的 abc 函数。下面的语句分别调用了哪一个 abc 函数?哪一条语句会出现编译错误?为什么?

  • cout << abc(1, 2, 3) << endl; // 调用 int 版本
  • cout << abc(1.0F, 2.0F, 3.0F) << endl; // 调用 float 版本
  • cout << abc(1, 2, 3.0F) << endl; // 报错:调用重载函数不明确
  • cout << abc(1.0, 2.0, 3.0) << endl; // 报错:形参类型是 double 而不是 float
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐