C++ Primer Plus(第六版)编程练习 第5章 循环和关系表达式

1. 编写一个要求用户输入两个整数的程序。该程序将计算并输出这两个整数之间(包括这两个整数)所有整数的和。这里假设先输入较小的整数。例如,如果用户输入的是2和9,则程序将指出2~9之间所有整数的和为44。

本题要求用户输入两个int类型的数,第一个较小,第二个较大,程序将把这两个数之间的所有整数做一个累加,并将累加结果输出。所以我们只需要使用一个for循环,并使得判断条件为从输入的较小整数到较大整数。

稍微需要注意的是对于请求用户输入,我认为最好是把较小整数和较大整数分开输入,这样也就比较方便分开储存,从而对于之后的操作都比较简便。具体算法设计请见下面代码。

代码如下:

// 5.1.cpp: 定义控制台应用程序的入口点。
//

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

int main()
{
    using namespace std;

    int min, max;
    cout << "Please enter two numbers:" << endl;
    cout << "Min: ";
    cin >> min;
    cout << "Max: ";
    cin >> max;
    int sum = 0;
    for (int i = min; i <= max; i++)
	 sum = sum + i;
    cout << "The total sum of " << min << " to " << max << " is " << sum << endl;

    system("pause");
    return 0;
}

运行结果如下图所示:



2. 使用array对象(而不是数组)和long double(而不是long long)重新编写程序清单5.4,并计算100!的值。

本题要求用户将程序清单5.4的部分内容进行修改后计算一个阶乘。我们只需要按照题目的要求,使用array对象的方法来声明参数,声明为long double类型的数即可。至于计算100!的算法,我们使用程序清单5.4相同的思路即可,即初始化前两个数为1,从第三个数开始使用for循环,并与之前的乘积结果相乘。这里要注意该程序清单的算法是直接再使用一个for循环来循环输出不同数的阶乘,而我们这里只需要输出100的阶乘即可,所以我们将ArSize定为101,最后需要对计数的i做一个i=i-1的操作。

代码如下:

// 5.2.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <array>

int main()
{
    using namespace std;

    const int ArSize = 101;
    array<long double, ArSize> factorials;
    int i;
    factorials[1] = factorials[0] = 1;
    for (i = 2; i < ArSize; i++)
	factorials[i] = i * factorials[i - 1];
    i = i - 1;
    cout << i << "! = " << factorials[i] << endl;
    system("pause");
    return 0;
}

运行结果如下图所示:



3. 编写一个要求用户输入数字的程序。每次输入后,程序都将报告到目前为止,所有输入的累计和。当用户输入0时,程序结束。

本题是要求用户输入数字,程序将所有输入的数字都累加起来并输出累加结果,直到输入为0时停止。所以本题的for循环的判断条件比较不同。首先判断条件没有一个特定的初始化,其次判断是否结束的表达式不是一个变量大于小于等于一个特定数值的方式,最后每次循环之后的操作不是将一个变量的值定幅度地变大或变小。

我们来看看for循环通常的组成部分:

for(initialization; test-expression; update-expression)

     body

通常情况下,初始化并不是必须的,很明显本题中就没有特定的初始化,所以initialization可以直接为空;接下来对于判决条件,本题是用户输入数字0时停止,所以test-expression就是input != 0; 其中假设input为用户输入的数字;最后对于每次循环后的更新操作,很明显就是再输入一个数字了,因此update-expression就是cin >> input。

明确了这个for循环的组成,其他部分就不难了。

代码如下:

// 5.3.cpp: 定义控制台应用程序的入口点。
//

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

int main()
{
    using namespace std;

    int num;
    int sum = 0;
    cout << "Please enter your number:" << endl;
    cin >> num;
    for (; num != 0; cin >> num)
    {
	sum = sum + num;
	cout << "Now the total sum is " << sum << endl;
    }

    cout << "Done\a\n";
    system("pause");
    return 0;
}

运行结果如下图所示:



4. Daphne以10%的单利投资了100美元。也就是说,每一年的利润都是投资额的10%,即每年10美元:

利息 = 0.10 X 原始存款

而CLeo以5%的复利投资了100美元。也就是说,利息是当前存款(包括获得的利息)的5%:

利息 = 0.05 X 当前存款

Cleo在第一年投资100美元的盈利是5%——得到了105美元。下一年的盈利是105美元的5%——即5.25美元,依此类推。请编写一个程序,计算多少年后,Cleo的投资价值才能超过Daphne的投资价值,并显示此时两个人的投资价值。

本题是比较两种不同的投资方式,直到方式2超过方式1为止,所以for循环里面的判决条件就是value2 >= value1就可以了,初始化和更新表达式肯定都是年份,然后for循环的循环体就是使用两个不同的计算公式来计算方式1和方式2的投资价值了。

代码如下:

// 5.4.cpp: 定义控制台应用程序的入口点。
//

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

int main()
{
    using namespace std;

    double money[2] = { 100,100 };
    int y;
    cout << "Daphne and Cleo both have $100 at first." << endl;
    for (y = 0; money[0] >= money[1]; y++)
    {
	money[0] = 0.1 * 100 + money[0];
	money[1] = 0.05 * money[1] + money[1];
    }
    cout << y << " years later Cleo will have more money than Daphne." << endl;
    cout << "At that time Cleo will have $" << money[1] << ", while Daphne will have $" << money[0] << ".\n";
	
    system("pause");
    return 0;
}

运行结果如下图所示:



5. 假设要销售《C++ For Fools》一书。请编写一个程序,输入全年中每个月的销售量(图书数量,而不是销售额)。程序通过循环,使用初始化为月份字符串的char*数组(或string对象数组)逐月进行提示,并将输入的数据储存在一个int数组中。然后,程序计算数组中各元素的总数,并报告这一年的销售情况。

本题抛开实际的应用场景,就是要求用户输入12个类型为int类型的数字,然后将这12个数字保存在一个int类型的数组中,再计算该数组的所有元素的总和并输出。但是输入的提示要求使用char*数组或string对象来提示用户。其实核心思想就是一个循环输入,一个很简单的循环12次的for循环就可以了,只需要对提示内容稍作操作就行。

代码如下:

// 5.5.cpp: 定义控制台应用程序的入口点。
//

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

int main()
{
    using namespace std;

    const int num = 11;
    int sell[num + 1];
    int total = 0;
    const char * months[num + 1] =
    {
	"January",
	"February",
	"March",
	"April",
	"May",
	"June",
	"July",
	"August",
	"September",
	"October",
	"November",
	"December"
    };

    for (int i = 0; i <= num; i++)
    {
	cout << months[i] << ": ";
        cin >> sell[i];
	total += sell[i];
    }

    cout << "So this year we sold " << total << " books for all.\n";
	
    system("pause");
    return 0;
}

运行结果如下图所示:



6. 完成编程练习5,但这一次使用一个二维数组来存储输入——3年中每个月的销售量。程序将报告每年销售量以及三年的总销售量。

本题要求对上一题进行拓展,拓展为3年的销售量,将原来的连续输入拓展为一个3*12的二维数组,其实只需要在上一题的代码中做一些简单的修改就可以了。首先就是最后要输出的数组改成一个二维的,然后再多声明一个长度为3的数组来储存每一年的销售量,再声明一个int类型整数来储存3年的总销售量。

对于循环体,我们现在需要使用一个两层的循环了,外层为年份,内层为月份,分别循环3次和12次,在最内层的循环体中,首先请求用户输入对应的年份和月份的销售量,再将其储存在二维数组的相对应的元素中。

代码如下:

// 5.6.cpp: 定义控制台应用程序的入口点。
//

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

int main()
{
    using namespace std;

    const int year = 3;
    const int month = 12;
    const char * months[month] =
    {
	"January",
	"February",
	"March",
	"April",
	"May",
	"June",
	"July",
	"August",
	"September",
	"October",
	"November",
	"December"
    };
    int sell[month][year];
    int sum[3] = { 0, 0, 0 };
    int totalsum = 0;

    for (int i = 0; i < year; i++)
    {
	cout << "The " << i + 1 << " year:" << endl;
	for (int j = 0; j < month; j++)
	{
	    cout << months[j] << ": ";
	    cin >> sell[j][i];
	    sum[i] = sum[i] + sell[j][i];
	}
    }

    totalsum = sum[0] + sum[1] + sum[2];

    cout << "The 1st year's saleroom is " << sum[0] << ".\n";
    cout << "The 2nd year's saleroom is " << sum[1] << ".\n";
    cout << "The 3rd year's saleroom is " << sum[2] << ".\n";
    cout << "The total saleroom of the 3 years is " << totalsum << ".\n";

    system("pause");
    return 0;
}

运行结果如下图所示:



7. 设计一个名为car的结构,用它存储下述有关汽车的信息:生产商(存储在字符数组或string对象中的字符串)、生产年份(整数)。编写一个程序,向用户询问有多少辆汽车。随后,程序使用new来创建一个由相应数量的car结构组成的动态数组。接下来,程序提示用户输入每辆车的生产商(可能是由多个单词组成)和年份信息。请注意,这需要特别小心,因为它将交替读取数值和字符串(参见第4章)。最后,程序将显示每个结构的内容。该程序的运行情况如下:

How many cars do you wish to catalog? 2

car #1:

Please enter the make: Hudson Hornet

Please enter the year made: 1952

Car #2:

Please enter the make: Kaiser

Please enter the year made: 1951

Here is your collection:

1952 Hudson Hornet

1951 Kaiser

本题要求用户使用new来动态分配内存,交替输入每辆车的生产商和生产年份信息,最后再一起输出。首先定义一个能够完成任务的结构体,然后请求用户输入车辆数量,使用new的方法来分配内存,分配长度就是车辆的数量,接下来使用for循环来提示用户并输入车辆信息,最后再输出。这里注意生厂商信息是允许由多个单词组成,那么对于char数组我们要使用cin.getline()函数,对于string对象我们要使用getline()函数。

代码如下:

// 5.7.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <string>

int main()
{
    using namespace std;

    int num;
    cout << "How many cars do you wish to catalog? ";
    cin >> num;

    struct car
    {
	string brand;
	int year;
    };
	
    car * user = new car [num];

    for (int i = 0; i < num; i++)
    {
	cout << "Car #" << i + 1 << ":\n";
	cout << "Please enter the make: ";
	getline(cin, user[i].brand);
	getline(cin, user[i].brand);
	cout << "Please enter the year made: ";
	cin >> user[i].year;
    }

    cout << "Here is your collection:" << endl;
    for (int i = 0; i < num; i++)
	cout << (*(user + i)).year << " " << (*(user + i)).brand << endl;

    system("pause");
    return 0;
}
这里注意一下,代码中我连续使用了两个getline()函数:
getline(cin, user[i].brand);
getline(cin, user[i].brand);

这是因为如果只使用一个该语句,还不等你输入,程序会直接把后面的提示输入车辆生成年份的语句一并输出出来,正常解决办法是在getline()函数前面加一个cin.get()函数,使整个循环体如下所示:

 for (int i = 0; i < num; i++)
    {
	cout << "Car #" << i + 1 << ":\n";
	cout << "Please enter the make: ";
	cin.get();
	getline(cin, user[i].brand);
	cout << "Please enter the year made: ";
	cin >> user[i].year;
    }

或者在循环外面加一个cin.get()函数,并在循环体内部的最后面也加一个cin.get()函数,这两种写法都是完全正确的。

导致不给你输入的机会就直接一并输出生成年份的原因,是在循环之前, 我们有

int num;
cout << "How many cars do you wish to catalog? ";
cin >> num;

该语句最后一个cin输入会使缓冲区里多一个回车符,这是会出现在先使用cin>>而后使用getline()函数时发生的问题;所以我们需要加一个cin.get()函数将缓冲区中多余的回车符消耗掉,之所以加在循环体内部,是因为循环体里面也有一个cin输入,所以每次执行getline()函数之前都需要消耗一个缓冲区中多余的回车符,因而加在循环体内部来循环消耗;之前说的在循环体外面加一个,在循环体里面的最后加一个,其实效果是一样的,只是第一次消耗是在循环之外消耗的,后来每次都是在循环内部消耗的,只是这样写比较规范,每次出现cin输入就赶紧在其后使用cin.get()来解决问题。

那么我在这里使用了一个很奇特的方法,连写两句getline()函数,这也是我无意间发现的。我认为这是由于getline(cin, str)函数也是用于输入,当缓冲区中多余的回车符碰到这个函数时,会和碰到cin.get()函数一样,直接消耗掉,所以会接着执行下一个getline()函数,于是就正常完成了我们的任务。

运行结果如下:



8. 编写一个程序,它使用一个char数组和循环来每次读取一个单词,直到用户输入done为止。随后,该程序指出用户输入了多少个单词(不包括done在内)。下面是该程序的运行情况:

Enter words (to tstop, type the word done):

anteater birthday category dumpster

envy finagle geometry done for sure

You entered a total of 7 words.

您应在程序中包含头文件cstring,并使用函数strcmp()来进行比较测试。

本题要求使用一个char数组来储存单词,并使用循环来读取单词,知道输入done为止,所以循环的判决条件一定是word = "done"。而题目后面要求了使用strcmp()函数来比较测试,所以循环的判决条件就是strcmp(word, "done") != 0,因为当输入word为done时strcmp()函数的值就会是0。

接下来最大的问题就是输入的单词是靠中间的空格来分隔的,所以每出现一个空格就会多一个单词,以此来计数。在这里我使用了bool()函数,因为如果输入空格,bool()函数的值就是true,所以以此作为一个判据来计数。

在这里我使用了while循环,因为本题的循环不需要初始化也不需要循环后更新,使用while循环最合适。

代码如下:

// 5.8.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <cstring>

int main()
{
    using namespace std;
	
    char word[100];
    cout << "Enter words (to stop, type the word done):" << endl;
    cin >> word;
    int count = 0;

    while (strcmp(word, "done") != 0)
    {
	if (bool(cin >> word) == true)
	count++;
    }
	

    cout << endl << "You entered a total of " << count << " words." << endl;

    system("pause");
    return 0;
}

运行结果如下图所示:



9. 编写一个满足前一个练习中描述的程序,但使用string对象而不是字符数组。请在程序中包含头文件string,并使用关系运算符来进行比较测试。

根据题目要求,本题只需要对上一题的代码做一些简单的修改就可以了。首先就是将字符数组改成使用string对象,由于是string对象,所以我们不能再使用strcmp()函数了,因为此时不再是字符串了。所以我们将while()循环内的判决条件改为word != "done"就可以了。

代码如下:

// 5.9.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <string>

int main()
{
    using namespace std;

    string word;
    int count = 0;
    cout << "Enter words (to stop, type the word done):" << endl;
    cin >> word;

    while (word != "done")
    {
	if (bool(cin >> word) == true)
	    count++;
    }
	
    cout << "You entered a total of " << count << " words." << endl;

    system("pause");
    return 0;
}

运行结果如下图所示:



10. 编写一个使用嵌套循环的程序,要求用户输入一个值,指出要显示多少行。然后,程序将显示相应行数的星号,其中第一行包括一个星号,第二行包括两个星号,依此类推。每一行包含的字符数等于用户指定的行数,在星号不够的情况下,在星号前面加上句点。该程序的运行情况如下:

Enter number of rows: 5

....*

...**

..***

.****

*****

本题要求我们输入一个int类型的整数,然后根据所述的方式来显示对应的行数,每一行的点数和星号数都是规定好的,非常好理解。这种情况我们肯定是要用多层循环的,外层循环是判断当前处于哪一行,而内部循环分别输出句点和星号。

代码如下:

// 5.10.cpp: 定义控制台应用程序的入口点。
//

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

int main()
{
    using namespace std;

    cout << "Enter numbers of rows: ";
    int row;
    cin >> row;

    int i;
    for (i = 1; i <= row; i++)
    {
	int j;
	int k;
	for (j = 1; j <= (row - i); j++)
	    cout << ".";
	for (k = 1; k <= i; k++)
	    cout << "*";
	cout << endl;
    }
	
    system("pause");
    return 0;
}

运行结果如下图所示:


猜你喜欢

转载自blog.csdn.net/leowinbow/article/details/80940987
今日推荐