c++ primer 题解 2021.01.01

178 阅读2分钟

1.2:改写程序,让它返回-1。返回值-1通常被当作程序错误的标识。重新编译并运行你的程序,观察你的系统如何处理main返回的错误标识。

更改后的程序

int main() {
    return -1;
}

编译

$ g++ ./main.cpp -o main.out

运行

$ ./main.out

*运行后程序未输出任何信息,使用 echo $?*查看状态,输出:255

$  echo $?
255

1.3:编写程序,在标准输出上打印Hello,World。

#include <iostream>

int main() {
    std::cout << "Hello World" << std::endl;
    return 0;
}

1.4:我们的程序使用加法运算符+来将两个数相加。编写程序使用乘法运算符*,来打印两个数的积。

#include <iostream>

int main() {
    int x = 10;
    int y = 20;
    std::cout << x * y << std::endl;
    return 0;
}

1.5:我们将所有输出操作放在一条很长的语句中。重写程序,将每个运算对象的打印操作放在一条独立的语句中。

#include <iostream>

int main() {
    std::cerr << "Enter two numbers" << std::endl;
    int v1 = 0, v2 = 0;
    std::cin >> v1 >> v2;
    std::cout << "The product of ";
    std::cout << v1;
    std::cout << " and ";
    std::cout << v2;
    std::cout << " is ";
    std::cout << v1 * v2;
    std::cout << std::endl;
    return 0;
}

1.6:解释下面程序片段是否合法。

std::cout << "The sum of " << v1;
		  << " and " << v2;
		  << " is " << v1 + v2 << std::endl;

不合法,此处的运算符<<需要接收两个参数,分别为basic_ostreamconst char *显然第二行开始并不符合正确用法

改正

std::cout << "The sum of " << v1;
std::cout << " and " << v2;
std::cout << " is " << v1 + v2 << std::endl;

1.7:编译一个包含不正确的嵌套注释的程序,观察编译器返回的错误信息。

int main() {
    /*
     * 注释对 /*  */ 不能嵌套
     * "不能嵌套" 几个字会被当作源码
     * 像剩余程序一样处理
     */
    return 0;
}

编译

$ g++ ./main.cpp -o ./main.out
./main.cpp:5:18: warning: '/*' within block comment [-Wcomment]
     * 注释对 /*  */ 不能嵌套
              ^
./main.cpp:5:25: error: use of undeclared identifier '不能嵌套'
     * 注释对 /*  */ 不能嵌套
                     ^
1 warning and 1 error generated.

1.8:指出下列哪些输出语句是合法的(如果有的话):

1. std::cout << "/*";
2. std::cout << "*/";
3. std::cout << /* "*/" */;
4. std::cout << /* "*/" /* "/*" */;

1 2 4 合法,对 4 进行改正

std::cout << /* "*/" */";

1.9:编写程序,使用while循环将50到100的整数相加。

#include <iostream>

int main() {
    int start = 50;
    int sum = 0;
    while (start <= 100) {
        sum += start;
        start++;
    }
    std::cout << "The sum from 50 to 100 is " << sum << std::endl;
    return 0;
}

1.10:除了++运算符将运算对象的值增加1之外,还有一个递减运算符(--)实现将值减少1。编写程序,使用递减运算符在循环中按递减顺序打印出10到0之间的整数。

#include <iostream>

int main() {
    int start = 10;
    while (start >= 0) {
        std::cout << start << std::endl;
        start--;
    }
    return 0;
}

1.11:编写程序,提示用户输入两个整数,打印出这两个整数所指定的范围内的所有整数。

#include <iostream>

int main() {
    std::cerr << "Enter two numbers" << std::endl;
    int v1 = 0, v2 = 0;
    std::cin >> v1 >> v2;
    // guarantee v1 is smaller than v2
    if (v1 > v2) {
        v1 = v1^v2;
        v2 = v1^v2;
        v1 = v1^v2;
    }

    while (v1 <= v2) {
        std::cout << v1 << ",";
        v1++;
    }
    std::cout << std::endl;
    return 0;
}

1.12:下面的for循环完成了什么功能?sum的终值是多少?

int main() {
    int sum = 0;
    for (int i = -100; i <= 100; ++i) {
        sum += i;
    }
    return 0;
}

完成从-100到100的累加操作,结果为0

1.13:使用for循环重做1.4.1节中的所有练习。

用for实现1.9:
int main() {
    int sum = 0;
    for (int i = 50; i <= 100; ++i) {
        sum += i;
    }
    return 0;
}
用for实现1.10
int main() {
    for (int i = 10; i >= 0; --i) {
        std::cout << i << std::endl;
    }
    return 0;
}
用for实现1.11
int main() {
    std::cerr << "Please enter two numbers" << std::endl;
    int v1, v2;

    std::cin >> v1 >> v2;

    if (v1 > v2) {
        v1 = v1 ^ v2;
        v2 = v1 ^ v2;
        v1 = v1 ^ v2;
    }

    for (; v1 <= v2; ++v1) {
        std::cout << v1 << std::endl;
    }

    return 0;
}

1.14:对比for循环和while循环,两种形式的优缺点各是什么?

for 和 while 在功能上基本等价,可以互相转换。不同点是while总是先判断条件,也比较适合循环次数未知的操作。

1.15:编写程序,包含第14页“再探编译”中讨论的常见错误。熟悉编译器生成的错误信息。

wikipedia: Compilation error

1.16:编写程序,从cin读取一组数,输出其和。

int main() {

    int sum = 0;
    int val = 0;

    while (std::cin >> val) {
        sum += val;
    }

    std::cout << "The sum of the input numbers is "
              << sum <<
              std::endl;

    return 0;
}

1.17:如果输入的所有值都是相等的,本节的程序会输出什么?如果没有重复值,输出又会是怎样的?

如果所有值都相等,则程序不会有任何输出。如果没有重复值,则每个值输出一条语句。

1.18:编译并运行本节的程序,给它输入全都相等的值。再次运行程序,输入没有重复的值。

输入:42 42 42 42 42 42,全相同的值,程序不会输出任何信息。

输入:1 2 3 4 5 6,程序输出6条语句,每个值对应一条。

1.19:修改你为1.4.1节练习1.10(第11页)所编写的程序(打印一个范围内的数),使其能处理用户输入的第一个数比第二个数小的情况。

#include <iostream>

int main() {
    std::cerr << "Enter two numbers" << std::endl;
    int v1 = 0, v2 = 0;
    std::cin >> v1 >> v2;
    // guarantee v1 is smaller than v2
    if (v1 > v2) {
        v1 = v1^v2;
        v2 = v1^v2;
        v1 = v1^v2;
    }

    while (v1 <= v2) {
        std::cout << v1 << ",";
        v1++;
    }
    std::cout << std::endl;
    return 0;
}

1.21:编写程序,读取两个ISBN相同的Sales_item对象,输出它们的和

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

int main() {
    Sales_item item1, item2;
    std::cerr << "请输入两条 ISBN 相同的销售记录" << std::endl;
    std::cin >> item1 >> item2;
    // 如果两条销售记录isbn相同
    if (compareIsbn(item1, item2)) {
        std::cout << item1 + item2 << std::endl;
    } else {
        std::cerr << "两条记录 isbn 不相同" << std::endl;
    }
    return 0;
}

1.22:编写程序,读取多个具有相同ISBN的销售记录,输出所有记录的和。

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

int main() {
    Sales_item total, item;
    if (std::cin >> total) {
        while (std::cin >> item) {
            if (compareIsbn(total, item)) {
                total += item;
            } else {
                std::cerr << "isbn 不相同" << std::endl;
                return -1;
            }
        }
        std::cout << "当前汇总结果:" << total << std::endl;
    } else {
        std::cerr << "输入了错误的销售记录";
        return -1;
    }
    return 0;
}

1.23:编写程序,读取多条销售记录,并统计每个ISBN(每本书)有几条销售记录。

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

int main() {
    Sales_item item1, item2;
    int num = 1;
    if (std::cin >> item1) {

        while (std::cin >> item2) {
            if (compareIsbn(item1, item2)) {
                num++;
            } else {
                std::cout << "isbn 为 "
                          << item1.isbn()
                          << " 的销售记录总共 "
                          << num
                          << " 条"
                          << std::endl;
                item1 = item2;
                num = 1;
            }
        }
        std::cout << "isbn 为 "
                  << item1.isbn()
                  << " 的销售记录总共 "
                  << num
                  << " 条"
                  << std::endl;
    } else {
        std::cerr << "输入了错误的销售记录";
        return -1;
    }
    return 0;
}

1.24:输入表示多个ISBN的多条销售记录来测试上一个程序,每个ISBN的记录应该聚在一起。

01 25 26 
01 25 36
01 25 26
02 25 36
isbn 为 01 的销售记录总共 3 条
02 14 36
02 1425 36
03 25 36
isbn 为 02 的销售记录总共 3 条
fd 25fdas fda
isbn 为 03 的销售记录总共 1 条

1.25:借助网站上的Sales_item.h头文件,编译并运行本节给出的书店程序。

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

int main() {
    Sales_item total; // 保存下一条交易记录的变量
    // 读入第一条交易记录,并确保数据可以处理
    if (std::cin >> total) {
        Sales_item trans; // 保存和的变量
        // 读入并处理剩余交易记录
        while (std::cin >> trans) {
            // 如果我们仍在处理相同的书
            if (total.isbn() == trans.isbn())
                total += trans; // 更新销售总额
            else {
                // 打印下一本书的结果
                std::cout << total << std::endl;
                total = trans; // total 现在表示下一本书的销售总额
            }
        }
        std::cout << total << std::endl; // 打印最后一本书的结果
    } else {
        // 没有输入!警告读者
        std::cerr << "No data?!" << std::endl;
        return -1; // 表示失败
    }
    return 0;
}

运行程序

01 25 26
01 25 06
01 25 35
01 24 236
12 35 65
01 99 7339 74.1313
02 55 66
12 35 2275 65
fda 121fdas 15
02 55 3630 66