转载公众号: iDoitnow ,用于学习笔记使用。
目录
第二章课后习题答案
复习题
1.c++程序模块叫什么?
叫做函数。
2.下面的预处理编译器指令是做什么用的?
#include<iostream>
在最终编译之前,将iostream里的文件内容替换该编译指令。
3.下面语句是做什么用的?
using namespace std;
使程序使用std名称空间的定义。
4.什么语句可以用来打印“Hello,world”,然后打印新的一行?
cout<<"Hello,world\n"; //或者cout<<"Hello,world"<<endl;
5.什么语句可以用来创建名为cheeses的整数变量?
int cheeses;
6.什么语句可以用来将32赋值给变量cheeses?
cheeses=32;
7.什么语句可以用来将键盘输入的值读入变量cheeses中?
cin>>cheeses;
8.什么语句可以用来打印“We have X varieties of cheeses”,其中X为变量cheese的当前值。
cout<<"We have "<<cheeses<<"varieties of cheeses"<<endl;
9.下面的函数原型指出关于函数的哪些信息?
int froop(double t);
void rattle(int n);
int prune(void);
-
int froop(double)
指出函数在调用时需要输入一个double类型的参数,函数返回一个int类型值。 -
void rattle(int n)
指出函数在调用的时候需要输入一个int类型参数,且该函数无返回值。 -
int prune(void)
指出函数不接收任何输入参数,函数返回一个int值。
10.定义函数时,什么情况下不必使用关键字return?
当函数的返回值类型为void的时,不用在函数中使用return。
11.假设你编写的main()函数包含如下代码:cout<<"Please enter your PIN:",而编译器指出cout是一个未知标识符。导致这种问题的原因很可能是什么?指出3种修复这种问题的方法。
可能原因:
没有#include<iostream>
,或未使用using namespace std
。
解决方法:
1.添加#include<iostream>
,在main()函数外使用using namespace std
;
2.添加include<iostream>
,使用using std::cout<<"Please enter your PIN:"
;
3.添加include<iostream>
,使用std::cout << "Please enter your PIN:"
;
编程练习
1.编写一个c++程序,它显示您的姓名和地址。
#include<iostream>
using namespace std;
int main()
{
cout<<"My name is iDoit,my address is BLABLA.."<<endl;
return 0;
}
2.编写一个c++程序,它要求用户输入一个以long为单位的距离,然后将它转换为码(一long等于200码)。
#include<iostream>
using namespace std;
int main()
{
int longNum=0;
cout<<"Please enter distance(long): ";
cin>>longNum;
cout<<"You input "<<longNum<<" long"<<endl;
cout<<longNum<<"long = "<<longNum*220<<" 码"<<endl;
return 0;
}
3.编写一个c++程序,他使用3个用户定义的函数(包括main(),并生成下面的输出:
Three blind mice
Three blind mice
See how they run
See how they run
其中一个函数要调用两次,该函数生成前两行;另外一个函数也调用两次,并生成其余的输出。
#include<iostream>
using namespace std;
void A_function()
{ cout<<"Three blind mice"<<endl; }
void B_function()
{ cout<<"See how they run"<<endl; }
int main()
{
A_function();
A_function();
B_function();
B_function();
return 0;
}
4.编写一个程序,让用户输入其年龄,然后显示该年龄包含多少个月,如下图所示:
Enter your age:29
#include<iostream>
using namespace std;
int main()
{
int age;
cout<<"Enter your age:";
cin>>age;
cout<<"your age include "<<age*12<<" months."<<endl;
return 0;
}
5.编写一个程序,其中main()调用一个用户定义的的函数(以摄氏温度值为参数,并返回相应的华氏温度值)。该程序按下面的格式要求用户输入摄氏温度值,并显示结果:
Please enter a Celsius value:20
20 degrees Celsius is 69 degrees Fahrenheit.
下面是转换公式:
华氏温度=1.8*摄氏温度+32.0
#include<iostream>
using namespace std;
double CtoF(double C)
{
double F=1.8*C+32.0;
return F;
}
int main()
{
double celsiusValue,fahrenheitValue;
cout<<"Please enter a Celsius value: ";
cin>>celsiusValue;
fahrenheitValue=CtoF(celsiusValue);
cout<<celsiusValue<<" degrees Celsius is "<<fahrenheitValue<<" degress Fahrenheit"<<endl;
}
6.编写一个程序,其main()调用一个用户的函数(以光年为参数,并返回对应天文单位的值)。该程序按下面的格式要求用户输入光年值,并显示结果:
Enter the number of light years: 4.2
4.2 light years =265608 astronomical units.
天文单位是从地球到太阳的平均距离(约150000000公里或93000000英里),光年是光一年走的距离(约10万亿公里或6万亿英里)(除太阳外,最近的恒星大约离地球4.2光年)。请使用double类型,转换公式为:1光年=63240天文单位。
#include<iostream>
using namespace std;
double LYtoAU(double lightYears)
{
double astroUnits=lightYears*63240;
return astroUnits;
}
int main()
{
double lightYears;
cout<<"Enter the number of light years: ";
cin>> lightYears;
double astroYears=LYtoAU(lightYears);
cout<<lightYears<<" light Years ="<<astroYears<<" astronomical units"<<endl;
return 0;
}
7.编写一个程序,要求用户输入小时数和分钟数,在main()函数中,将这两个值传递给一个void函数,后者以下面这样的格式显示这两个值:
Enter the number of hours: 9
Enter the number of minutes: 28
Time: 9:28
#include<iostream>
using namespace std;
void Time(int hours,int minutes)
{
cout<<"Time: "<<hours<<":"<<minutes<<endl;
}
int main()
{
int hours,minutes;
cout<<"Enter the number of hours: ";
cin>>hours;
cout<<"Enter the number of minutes: ";
cin>>minutes;
Time(hours,minutes);
return 0;
}
第三章课后习题答案
复习题
1.为什么c++有多种整形?
有多种整形类型,可以根据特定需求选择最合适的类型。例如,可以使用short来存储空格,使用long来确保存储容量,也可以寻找可提高特定计算的速度的类型。
2.声明与下述描述相符的变量。
a.short整数,值为80
b.unsigned int整数,值为42110
c.值为3000000000的整数
short a=80; //or short int a=80;
unsigned int b=42110; //or unsigned b=42110;
unsigned long long c=3000000000; //or unsigned long c=3000000000;
//(注意:不要指望int变量能够存储300000000)
3.c++提供了什么措施来防止超出整形的范围?
c++没有提供自动防止超出整型限制的功能,可以使用头文件climits来确定限制情况。
4.33L与33之间有什么区别?
常量33L的类型为long,常量33类型为int。
5.下面两条c++语句是否等价?
char grade =45;
char grade = 'A';
这两条语句并不真正等价,虽然对于某些系统来说,他们是等效的。最重要的是,只有在使用ASCII码的系统上,第一条语句才将得分设置为字母A,而第二条语句还可用于使用其他编码的系统。其次,65是一个int常量,而‘A’是一个char常量。
6.如何使用c++来找出编码88表示的字符?指出至少两种方法。
//method 1
char c=88;
cout<<c<<endl;
//method 2
cout.put(char(88));
//method 3
cout<<char(88)<<endl; //new-style type cast value to char
cout<<(char)88<<endl; //old-style type cast value to char
7.将long赋值给float变量会导致舍入误差,将long值赋给double变量呢?将long long值赋给double变量呢?
这个问题取决于这两个类型的长度。如果long为4个字节,则没有损失。因为最大的long值是20亿,及有10位数。由于double提供至少13位有效数字,因而不需要进行任何舍入。long long类型可提供19位有效数字,超过了double保证的13位有效数字。
8.下列c++表达式的结果分别是多少?
a.89+2 b.63/4
c.3/46 d.6.03/4
e.15%4
a=74;b=4;c=0;d=4.5;e=3
9.假设x1和x2是两个double变量,你要将他们作为整数相加,再将结果赋给一个整型变量。请编写一条完成这项任务的c++语句。如果要将他们作为double值相加并转换为int呢?
int a=(int)x1+(int)x2;
int a=int(x1)+int(x2);
要将他们作为double类型相加,在进行转换,可采取下述方式之一:
int a=(int)(x1+x2);
int a=int(x1+x2);
10.下面每一条语句的变量都是什么类型?
a.auto cars=15;
b.auto iou=150.37f;
c.auto level='B';
d.auto crat=U'/U00002155';
e.auto fract=8.25f/2.5;
a. int
b. float
c. char
d. char32_t
e. double
编程练习
1.编写一个小程序,要求用户使用一个整数指出自己的身高(单位为英寸),然后将身高转换为英尺,该程序使用下划线字符来指示输入位置。另外,使用一个const符号来表示转换因子。
#include <iostream>
const double Inch_per_feet = 12.0;
using namespace std;
int main(void)
{
cout << "Please enter your height:_____\b\b\b\b\b";
double ht_inch;
cin >> ht_inch;
double ht_feet = ht_inch/Inch_per_feet;
cout << "Your height is:" << ht_feet << " feets<<endl";
return 0;
}
2.编写一个程序,要求以几英尺几英寸的方式输入其身高,并以磅为单位输入其体重。(使用3个变量来存储这些信息。)该程序报告其BMI(Body Mass Index ,体重指数)。为了计算BMI,该程序以英寸的方式指出用户的身高(一英尺为十二英寸),并将以英寸为单位的身高身高转换为以米为单位的身高(1英寸=0.0254米)。然后,将以磅为单位的体重转换为千克为单位的体重(1千克=2.2磅)。最后,计算相应的BMI-体重(千克)除以身高(米)的平方。用符号常量表示各种转换因子。
#include <iostream>
using namespace std;
const double Inch_per_feet = 12.0;
const double Meter_per_inch = 0.0254;
const double Pound_per_kilogram = 2.2;
int main()
{
cout << "Enter your height of feet:";
double ht_feet;
cin >> ht_feet;
cout << "Enter your height of inch:";
double ht_inch;
cin >> ht_inch;
double ht_meter = (ht_feet*Inch_per_feet + ht_inch)*Meter_per_inch;
cout << "Enter your weight in pound: ";
double wt_pound;
cin >> wt_pound;
double wt_kilogram = wt_pound / Pound_per_kilogram;
double BMI = wt_kilogram / ht_meter/ht_meter;
cout << "BMI:" << BMI << endl;
system("pause");
return 0;
}
3.编写一个程序,要求用户以度分秒的方式输入一个纬度,然后以度为单位显示该纬度。1度为60分,1分等于60秒,请以符号常量的方式表示这些值。对于每个输入值,应使用一个独立的变量存储它。下面是该程序运行时的情况:
Enter a latitude in degrees,minutes,and seconds:
First,enter the degrees:37
Next,enter the minutes of arc:51
Finally,enter the seconds of arc:19
37 degrees,51 minutes,19 seconds =37.8553 degrees
#include <iostream>
using namespace std;
const double Minute_per_degree = 60.0;
const double Second_per_minute = 60.0;
int main()
{
cout << "Enter a latitude in degrees,minutes,and seconds:"<<endl;
cout << "First,enter the degrees:";
int degrees;
cin >> degrees;
cout << "Next,enter the minutes of arc:";
int minutes;
cin >> minutes;
cout << "Finally,enter the seconds of arc:";
int seconds;
cin >> seconds;
double Degree = degrees + minutes / Minute_per_degree + seconds / Second_per_minute / Minute_per_degree;
cout << degrees << " degrees, " << minutes << " minutes, " << seconds << " seconds = " << Degree<< " degrees";
system("pause");
return 0;
}
4.编写一个程序,要求用户以整数方式输入秒数(使用long或long long变量存储),然后以天、小时、分钟和秒的方式显示这段时间。使用符号常量来表示每天有多少小时、每小时有多少分钟以及每分钟有多少秒。该程序的输出应与下面类似:
Enter the number of seconds:3160000
3160000 seconds = 365 days,17 hours,46 minutes,40 seconds
#include <iostream>
using namespace std;
const int Sec_per_min = 60;
const int Min_per_hour = 60;
const int Hour_per_day = 24;
int main()
{
cout << "Enter the number of seconds:";
long long total_sec;
cin >> total_sec;
int sec = total_sec%Sec_per_min;
int total_min = total_sec / Sec_per_min;
int min = total_min%Min_per_hour;
int total_hour = total_min / Min_per_hour;
int hour= total_hour%Hour_per_day;
int day = total_hour / Hour_per_day;
cout << total_sec << " seconds = " << day << " days," << hour << " hours," << min << " minutes," << sec << " seconds";
system("pause");
return 0;
}
5.编写一个程序,要求用户输入全球当前的人口和美国当前的人口(或其他国家的人口)。将这些信息存储在long long变量中,并让程序显示美国(或其他国家)的人口占全球人口的百分比。该程序的输出与下面类似:
Enter the world's population:6898758899
Enter the population of the US:310783781
The population of the US is 4.50492% of the world population.
#include <iostream>
using namespace std;
const int Sec_per_min = 60;
const int Min_per_hour = 60;
const int Hour_per_day = 24;
int main()
{
cout << "Enter the world's population:";
long long tW_population;
cin >> tW_population;
cout << "Enter the population of the US:";
long long US_population;
cin >> US_population;
cout << "The population of the Us is " << double(US_population) / double(tW_population) *100<< "% of the world population";
system("pause");
return 0;
}
6.编写一个程序,要求用户输入驱车里程(英里)和使用汽油量(加仑),然后指出汽车耗油量为一加仑的里程。如果愿意,也可以让程序要求用户以公里为单位输入距离,并以升为单位输入汽油量,然后指出欧洲风格的结果-即每100公里的耗油量(升)。
#include <iostream>
using namespace std;
int main()
{
cout << "Please enter the distance(miles):";
double distance;
cin >> distance;
cout << "Please enter volume of gasoline(gallon):";
double volume;
cin >> volume;
cout << "You can run " << distance / volume << " miles per gallon" << endl;
system("pause");
return 0;
}
7.编写一个程序,要求每个用户按欧洲风格输入汽车的耗油量(每100公里消耗汽油量(升 )),然后将其转换为美国风格的耗油量-每加仑多少英里。注意,除了使用不同的单位计量外,美国方法(距离/燃料)与欧洲方法(燃料/距离)相反。100公里等于62.14英里,1加仑等于3.875升。因此,19mpg大约合12.41/100km,127mpg大约合8.71/100km。
#include <iostream>
using namespace std;
int main()
{
cout << "Please enter fuel consumption per 100 km(UN):";
double UN;
cin >> UN;
cout <<" Gallons per mile(US) : "<< 1 / UN*62.14*3.875;
system("pause");
return 0;
}
第四章课后习题答案
复习题
1.如何声明下述数据?
a. actor是由30个char组成的数组
b. betsie是由100个short组成的数组
c. chuck是由13个float组成的数组
d. dipsea是由64个long double组成的数组
char actor[30];
short betsie[100];
float chuck[13];
long double dipsea[64];
2.使用模板类array而不是数组来完成1的问题。
array<char,30>actor;
array<short,100>betsie;
arry<float,13>chuck;
array<long double,64>dipsea;
3.声明一个包含5个元素的int数组,并将他们初始化为前5个正奇数。
int a[5]={1,3,5,7,9};
4.编写一条语句,将问题3中数组第一个元素和最后一个元素的和赋值给变量even。
int a[5]={1,3,5,7,9};
int even=a[0]+a[4];
5.编写一条语句,显示float数组ideas中的第二个元素的值。
cout<<ideas[1]<<endl;
6.声明一个char的数组,并将其初始化为字符串“cheeseburger”。
char a[]="cheeseburger";
7.声明一个string对象,并将其初始化为字符串“Waldorf Salad”。
string a="Waldorf Salad";
8.设计一个描述鱼的结构声明,结构中应当包括品种、重量(整数,单位为盎司)和长度(英寸,包括小数)。
struct fish{
char kind[20];
int weight;
float length;
}
9.声明8中定义的结构变量,并对她进行初始化。
fish Xfish=
{
"xiaoyu";
10;
20.5;
}
10.用enum定义一个名为Response的类型,它包含Yes、No和Maybe等枚举量,其中Yes的值为1,No为0,Maybe为2.
enum Response{No,Yes,Maybe};
11.假设ted是一个double变量,请声明一个指向ted的指针,并使用该指针来显示ted的值。
double *p=&ted;
cout<<*p<<endl;
12.假设treacle是一个包含10个元素的float数组,请声明一个指向treacle的第一个元素的指针,并使用该指针来显示数组的第一元素和最后一个元素。
float *p=treacle;
cout<<p[0]<<" "<<p[9]<<endl;
//or cout<<*p<<" "<<*(p+10) ;
13.编写一段代码,要求用户输入一个正整数,然后创建一个动态int数组,其中包含的元素数目等于用户的输入值,首先使用new来完成这项任务,再使用vector对象完成这项任务。
//use new
int num;
cout<<"Please input a positive integer: ";
cin>>num;
int *shu=new int[num];
//use vector
int num;
cout<<"Please input a number: ";
cin>>num;
vector<int>shu(num);
14.下面的代码是否有效,如果有效,他将输出什么结果。
cout<<(int*)"Home of the jolly bytes";
有效,输出该字符串的地址。
15.编写一段代码,给问题8中的结构动态分配内存,再读取该结构的成员的值。
fish yu=new fish{xiaoyu,10,20.5};
cout<<yu.name<<endl;
cout<<yu.weight<<endl;
cout<<yu.length<<endl;
16.程序清单4.6指出了混合输入数字和一行字符串存储的问题,如果将下面的代码:
cin.getline(adress,80);
替换为:cin>>address;
将对程序带来什么影响?
使用cin>>address 将使得程序跳过空白,直到找到给空白字符为止。然后它将读取字符,直到再次遇到空白为止。因此,它将跳过数字输入的换行符,从未避免这种问题。另一方面,它值读取一个单词,而不是整行。
17.声明一个vector对象和一个array对象,他们都包含10个string对象。指出所需的头文件,但不要使用using,使用const来指定要包含的string对象数。
#include<vector>
#include<array>
#include<string>
const int str_num=10;
std::vector<std::string>vstr(str_num);
std::array<<std::string,str_num>astr;
编程练习
1.编写一个c++程序,如下述输出示例的那样请求并显示信息:
What is your first name? Betty Sue
What is your last name? Yewe
What letter grade do you deserve? B
What is your age? 22
Name:Yewe,Betty Sue
Grade:C
Age:22
(注意,该程序应该接受的名字包含多个单词。另外,程序将向下调整成绩,即向上调一个字母。假设用户请求A、B或C,所以不必担心D和F之间的空档。)
#include<iostream>
#include<string>
int main()
{
using namespace std;
cout << "What your first name? ";
string first_name;
getline(cin,first_name) ;
cout << "What your last name? ";
string last_name;
getline(cin,last_name);
cout << "What letter grade do you deserve? ";
char my_grade;
cin >> my_grade ;
cout << "What is you age? ";
int age;
cin >> age ;
cout << "Name: " << last_name << "," << first_name << endl;
cout << "Grade: " << ++my_grade<< endl;
cout << "Age: " << age << endl;
system("pause");
return 0;
}
2.修改程序清单4.4,使用c++string类而不是char数组。
#include <iostream>
#include<string>
int main()
{
using namespace std;
string name;
string dessert;
cout << "Enter your name:\n";
getline(cin, name); // reads through newline
cout << "Enter your favorite dessert:\n";
getline(cin,dessert);
cout << "I have some delicious " << dessert;
cout << " for you, " << name << ".\n";
system("pause");
return 0;
}
3.编写一个程序,他要求用户首先输入其名,然后输入其姓;然后程序使用一个逗号和一个空格将姓和名组合起来,并存储和显示结合效果,请使用char数组和头文件cstring中的函数。下面是该程序的运行时的情形:
Enter your first name: Flip
Enter your last name: Fleaming
Here's the information in a single string: Fleming, Flip
#include<iostream>
#include<cstring>
//#pragma warning(disable:4996) //vs2017需要加上这句话,忽略4996警告
const int Strlen = 20;
int main()
{
using namespace std;
char first_name[Strlen];
char last_name[Strlen];
char full_name[2 * Strlen];
cout << "Enter your first name: ";
cin.get(first_name,Strlen).get();
cout << "Enter your last name:";
cin.get(last_name,Strlen).get();
strcpy(full_name,last_name);
strcat(full_name,", ");
strcat(full_name, first_name);
cout << "Here's the information in a single string: " << full_name << endl;
system("pause");
return 0;
}
4.编写一个程序,他要求用户首先输入其名,然后输入其姓;然后程序使用一个逗号和一个空格将姓和名组合起来,并存储和显示结合效果,请使用string对象和文件string中的函数。下面是该程序的运行时的情形:
Enter your first name: Flip
Enter your last name: Fleaming
Here's the information in a single string: Fleming, Flip
#include<iostream>
#include<string>
int main()
{
using namespace std;
string first_name;
string last_name;
string full_name;
cout << "Enter your first name: ";
getline(cin,first_name);
cout << "Enter your last name:";
getline(cin, last_name);
full_name = last_name + ", " + first_name;
cout << "Here's the information in a single string: " << full_name << endl;
system("pause");
return 0;
}
5.结构CandyBar包含3个成员。第一个成员存储了糖块的品牌;第二个成员存储糖块的重量(可以有小数);第三个成员存储了糖的卡路里含量(整数)。请编写一个程序,声明这个结构,创建一个名为snack的CandBar变量,并将其成员分别初始化为“Mocha Munch”、2.3和350。初始化在声明snack时进行。最后,程序显示snack变量的内容。
#include<iostream>
#include<string>
struct CandyBar {
std::string brand;
float weight;
int calorie;
};
int main()
{
using namespace std;
CandyBar snack = {"Mocha Munch",2.3,350};
cout << "brand: " << snack.brand << endl;
cout << "weight: " << snack.weight << endl;
cout << "calorie: " << snack.calorie << endl;
system("pause");
return 0;
}
6.结构CandyBar包含3个成员,如编程练习5所示。请编写一个程序,创建一个包含3个元素的CandyBar数组,并将他们初始化为所选择的值,然后显示每个结构的内容。
#include<iostream>
#include<string>
struct CandyBar {
std::string brand;
float weight;
int calorie;
};
int main()
{
using namespace std;
CandyBar snack[3] = {
{ "Mocha Munch",2.3,350 },
{ "Mocha Munch",2.3,350 },
{ "Mocha Munch",2.3,350 }
};
for (int i = 0; i < 3; i++)
{
cout << "brand: " << snack[i].brand << endl;
cout << "weight: " << snack[i].weight << endl;
cout << "calorie: " << snack[i].calorie << endl;
}
system("pause");
return 0;
}
7.William Wingate从事披萨分析服务。对于每个披萨饼,他都需要记录下列信息:
-
披萨饼公司的名称,可以有多个单词组成。
-
披萨饼的直径
-
披萨饼的重量
请设计一个能够存储这些信息的结构,并编写一个使用这种结构变量的程序。程序将请求用户输入上述信息,然后显示这些信息。请使用cin(或它的方法)和cout。
#include<iostream>
#include<string>
struct Pizza {
std::string company;
double diameter;
double weight;
};
int main()
{
using namespace std;
Pizza pizza;
cout << "Please input pizza's company: ";
getline(cin, pizza.company);
cout << "Please input pizza's diameter: ";
cin>>pizza.diameter;
cout << "Please input pizza's weight: ";
cin>> pizza.weight;
cout << "Company: " << pizza.company << endl;
cout << "Diameter: " <<pizza.diameter << endl;
cout << "Weight: " << pizza.weight<< endl;
system("pause");
return 0;
}
8.完成编程练习7,但使用new来为结构动态分配内存,而不是声明一个结构变量。另外,让程序在请求输入披萨名称之前输入披萨直径。
#include<iostream>
#include<string>
struct Pizza {
std::string company;
double diameter;
double weight;
};
int main()
{
using namespace std;
Pizza *p=new Pizza;
cout << "Please input p's diameter: ";
cin >> p->diameter;
cin.get();
cout << "Please input p's company: ";
getline(cin, p->company);
cout << "Please input p's weight: ";
cin>>p->weight;
cout << "Company: " << p->company << endl;
cout << "Diameter: " <<p->diameter << endl;
cout << "Weight: " << p->weight<< endl;
system("pause");
return 0;
}
9.完成编程练习6,但使用new来动态分配数组,而不是声明一个包含3个元素的CandyBar的数组。
#include<iostream>
#include<string>
struct CandyBar {
std::string brand;
double weight;
int calorie;
};
int main()
{
using namespace std;
CandyBar *snack = new CandyBar[3];
for (int i = 0; i < 3; i++)
snack[i]={"Mocha Munch", 2.3, 350};
for (int i = 0; i < 3; i++)
{
cout << "brand: " << snack[i].brand << endl;
cout << "weight: " << snack[i].weight << endl;
cout << "calorie: " << snack[i].calorie << endl;
}
delete[] snack;
system("pause");
return 0;
}
10.编写一个程序,让用户输入三次40码跑的成绩(如果你愿意,也可以让用户输入40米跑的成绩),并显示次数和平均成绩。请使用一个array对象来存储数据(如果编译器不支持array类,请使用数组)。
#include<iostream>
#include<array>
int main()
{
using namespace std;
array<double, 3>grade;
cout << "Please input your first grade:";
cin >> grade[0];
cout << "Please input your second grade:";
cin >> grade[1];
cout << "Please input your third grade:";
cin >> grade[2];
cout << "Average three times:" << (grade[0] + grade[1] + grade[2]) / 3.0 << endl;
system("pause");
return 0;
}
第五章课后习题答案
复习题
1.入口条件循环和出口条件循环之间的区别是什么?各种c++循环分别属于其中的哪一种?
入口循环就是程序在执行循环体中的语句之前先检查循环条件;出口循环是在执行循环体中的语句之后检查循环条件。for循环和while循环都是入口条件循环;do while循环为出口条件循环。
2.如果下面的代码片段是有效程序的组成部分,它将打印什么内容?
int i;
for(i=0;i<5;i++)
cout<<i;
cout<<endl;
打印内容:01234
3.如果下面的代码片段是有效程序的组成部分,它将打印什么内容?
int j;
for(j=0;j<11;j+=3)
cout<<j;
cout<<endl<<j<<endl;
打印内容:0369
12
4.如果下面代码是有效程序的组成部分,它将打印什么内容?
int j=5;
while(++j<9)
cout<<j++<<endl;
打印内容:6
8
5.如果下面代码是有效程序的组成部分,它将打印什么内容?
int k=8;
do
cout<<"k="<<k<<endl;
while(k++<5);
打印内容:k=8
6.编写一个打印1、2、4、8、16、32、64的for循环,每轮循环都将计数变量的值乘以2。
int i;
for(i=1;i<=64;i*=2)
cout<<i<<" ";
7.如何在循环体中包括多条语句?
将语句放在一对大括号中形成一个复合语句或代码块。
8.下面的语句是否有效?如果无效,原因是什么?如果有效,它将完成什么工作?
a.int x={1,024}
b.int y=1,024;
语句a是有效的,表达式1,024为逗号表达式,该表达时的右侧表达式的值,由于024为8进制数,对应的十进制数为20,因此x的值应为20,即x=20。
语句b也是有效的,但是逗号运算符的优先级低于赋值运算符,因此b中表达式等效为(int y=1),024;
。
9.在查看输入方面,cin>>ch同cin.get(ch)和ch=cin.get()有什么不同?
cin>>ch
将跳过空格、换行符和制表符,其他两种格式将读取这些字符。
编程练习
1.编写一个要求用户输入两个整数的程序。该程序将计算并输出这两个整数之间(包括这两个整数)所有整数的和。这里假设先输入较小的整数。例如,如果用户输入的是2和9,则程序将指出2~9之间所有整数的和为44。
#include<iostream>
using namespace std;
int main()
{
int a, b, sum = 0;
cout << "Please enter two integers(enter the smaller integer first)." << endl;
cout << "The first integer : _\b";
cin >> a;
cout << "The second integer: _\b";
cin >> b;
for (int i = a; i <= b; i++)
sum += i;
cout << "The sum of integers between "<<a<<" and "<<b<<" is : " << sum << endl;
system("pause");
return 0;
}
2.使用array对象(而不是数组)和long double(而不是long long)重新编写程序清单5.4,并计算100!的值。
Listing 5.4 formore.cpp
// formore.cpp -- more looping with for
#include <iostream>
const int ArSize = 16; // example of external declaration
int main()
{
long long factorials[ArSize];
factorials[1] = factorials[0] = 1LL;
for (int i = 2; i < ArSize; i++)
factorials[i] = i * factorials[i-1];
for (int i = 0; i < ArSize; i++)
std::cout << i << "! = " << factorials[i] << std::endl;
return 0;
}
编写后程序清单:
#include<iostream>
#include<array>
const int ArSize = 16;
int main()
{
using namespace std;
array<long double,ArSize>factorials;
factorials[1] = factorials[0] = 1.0;
for (int i = 2; i < ArSize; i++)
factorials[i] = i * factorials[i - 1];
for (int i = 0; i <ArSize; i++)
cout << i << "! = " << factorials[i] << endl;
system("pause");
return 0;
}
3.编写一个要求用户输入数字的程序。每次输入后,程序都将报告到目前为止,所有输入的累计和,当用户输入0时,程序结束。
#include<iostream>
#include<array>
int main()
{
using namespace std;
double num,sum=0;
for (int i = 1; i != 0; i=num)
{
cout << "Please enter a number(if 0,the end the program.)_\b";
cin >> num;
sum += num;
cout << "At this point, the cumulative sum of the Numbers is : " << sum << endl;
}
cout << "Bye" << endl;
system("pause");
return 0;
}
4.Daphne以10%的单利投资了100美元。也就是说,每一年的利润都是投资额的10%,即每年10美元:利息=0.10*原始存款。而Cleo在第一年投资100美元的盈利是5%--一共得到105美元。下一年的盈利是105美元的5%--即5.25美元,以此类推。请编写一个程序,计算多少年后,Cleo的投资价值超过Daphne的投资价值。并显示此时两个人的投资价值。
#include<iostream>
int main()
{
using namespace std;
double daphne = 100.0;
double cleo = 100.0;
int year;
for (year = 1; cleo <= daphne; year++)
{
daphne += 10.0;
cleo *= 1.05;
}
cout << year << " years later,Cleo's investment is worth more than Daphne's." << endl;
cout << "Daphne has $" << daphne << endl;
cout << "Cleo has $" << cleo << endl;
system("pause");
return 0;
}
5.假设要销售《C++ For Fools》一书。请编写一个程序,输入全年中每个月的销售量(图书数量,而不是销售额)。程序通过循环,使用初始化为月份字符串的char*数组(或string对象数组)逐月进行提示,并将输入数据存储的int数组中。然后,程序计算数组中各元素的总数,并报告这一年的销售情况。
#include<iostream>
#include<string>
int main()
{
using namespace std;
string months[12] = {
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November",
"December"
};
int sales[12];
int sum = 0;
for (int i = 0; i < 12; i++)
{
cout << "Please enter the sales volume for " << months[i] << " : _\b";
cin >> sales[i];
}
for (int i = 0; i < 12; i++)
{
cout << months[i] << " sales : " << sales[i]<<endl;
sum += sales[i];
}
cout << "Annual sales :" << sum << endl;
system("pause");
return 0;
}
6.完成编程练习5,但这一次使用大的一个二位数组来存储输入---3年中每个月的销售量。程序将报告每年销量以及三年的总销量。
#include<iostream>
#include<string>
int main()
{
using namespace std;
string months[12] = {
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November",
"December"
};
int sales[3][12];
int sum = 0;
for (int i = 0; i < 3; i++)
{
cout << "Year " << i+1 << ": " << endl;
for (int f = 0; f < 12; f++)
{
cout << "Please enter the sales volume for " << months[f] << " : _\b";
cin >> sales[i][f];
}
}
for (int j=0; j < 3; j++)
{
cout << "*********Year " << j+1 << "*********" << endl;
for (int i = 0; i < 12; i++)
{
cout << months[i] << " sales : " << sales[j][i] << endl;
sum += sales[j][i];
}
}
cout << "Annual sales :" << sum << endl;
system("pause");
return 0;
}
7.设计一个名为car的结构,用它存储下述有关汽车的信息:生产商(存在字符数组或string对象中的字符串)、生产年份(整数)。编写一个程序向用户询问有多少辆汽车。随后,程序使用new来创建一个有相应数量的car结构组成的动态数组。接下来,程序提示用户输入每辆车的生产商(可能有多个单词组成)和年份信息。请注意,这需要特别小心,因为它将交替读取数值和字符串。最后,程序将显示每个结构的内容。该程序的运行情况如下:
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
实现代码:
#include<iostream>
#include<string>
using namespace std;
struct Car {
string maker;
int year;
};
int main()
{
int num;
cout << "How many cars do you wish to catalog? ";
(cin >> num).get();
Car *cars=new Car[num];
for (int i=0; i < num; i++)
{
cout << "Car #" << i + 1 << " : " << endl;
cout << "Please enter the make : ";
getline(cin ,cars[i].maker);
cout << "Please enter the year made : ";
(cin >> cars[i].year).get();
}
cout << "Here is your collection:" << endl;
for (int i = 0; i < num; i++)
cout << cars[i].year << " " << cars[i].maker << endl;
delete []cars;
system("pause");
return 0;
}
8.编写一个程序,它使用一个char数组和循环来每次读取一个单词,直到用户输入done为止。随后,该程序指出用户输入多少个单词(不包含done)。下面是程序的运行情况:
Enter words(to stop,type the word done):
anteater birthday category dumpster
envy finagle geometry done for sure
You entered a total of 7words.
您应在程序中包含头文件cstring,并使用strcmp()来进行比较测试。
实现代码:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char word[20];
cout << "Enter words(to stop,type the word done):" << endl;
cin >> word;
int num = 0;
while (strcmp("done", word))
{
num++;
cin >> word;
}
cout << "You entered a total of " << num << " words." << endl;
system("pause");
return 0;
}
9.编写一个满足前一个练习的中描述的程序,但使用string对象而不是字符数组。请在程序中包含头文件string,并使用关系运算符来进行比较测试。
#include<iostream>
#include<string>
using namespace std;
int main()
{
string word;
cout << "Enter words(to stop,type the word done):" << endl;
cin >> word;
int num = 0;
while ( word.compare("done"))
{
num++;
cin >> word;
}
cout << "You entered a total of " << num << " words." << endl;
system("pause");
return 0;
}
10.编写一个使用嵌套循环的程序,要求用户输入一个值,指出要显示多少行。然后,程序将显示相应行数的型号,其中第一行包括一个星号,第二行包括两个星号,以此类推。每一行包含的字符数等于用户指定的行数,在星号不够的情况下,在星号前面加句点。程序的运行情况如下:
Enter number of row : 5
....*
...**
..***
.****
*****
代码实现:
#include<iostream>
using namespace std;
int main()
{
int row;
cout << "Enter number of rows : ";
cin >> row;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < row; j++)
{
if (i < row -j-1)
cout << '.';
else
cout << '*';
}
cout << endl;
}
system("pause");
return 0;
}
第六章课后习题答案
复习题
1.请看下面两个计算空格和换行符数目的代码片段:
//version 1
while(cin.get(ch)) //quit on eof
{
if(ch==' ')
spaces++;
if(ch=='\n')
newlines++;
}
//version 2
while(cin.get(ch)) //quit eof
{
if(ch==' ')
spacees++;
else if(ch=='\n')
newlines++;
}
第二个格式比第一个格式好在哪里?
第二个版本比第一个版本效率更高,因为在第一个中对于每个字符都需要判断两次,而在第二个版本中,如果字符为空格,在经过if判断确定为空格后,该字符肯定不是换行符,第二个else if的判断直接跳过,节省判断时间。
2.在程序清单6.2中,用ch+1替换++ch将发生什么情况?
程序清单6.2 ifelse.cpp
// ifelse.cpp -- using the if else statement #include <iostream> int main() { char ch; std::cout << "Type, and I shall repeat.\n"; std::cin.get(ch); while (ch != '.') { if (ch == '\n') std::cout << ch; // done if newline else std::cout << ++ch; // done otherwise std::cin.get(ch); } // try ch + 1 instead of ++ch for interesting effect std::cout << "\nPlease excuse the slight confusion.\n"; // std::cin.get(); // std::cin.get(); return 0; }
++ch的数据类型依旧是char型,但对于char+1最终类型为int型,因此当++ch换成ch+1后,输出的是数字。
3.请认真考虑下面的程序:
#include<iostream>
using namespace std;
int main()
{
char ch;
int ct1,ct2;
ct1=ct2=0;
while((ch=cin.get())!='$')
{
cout<<ch;
ct1++;
if(ch='$')
ct2++;
cout<<ch;
}
cout<<"ct1="<<ct1<<",ct2="<<ct2<<"\n";
return 0;
}
假设输入如下(请在每行末尾按回车键):
Hi!
Send $10 or $20 now!
则输出将是什么(还记得吗,输入被缓冲)?
输入输出结果为
Hi!
H$i$!$
$Send $10 or $20 now!
S$e$n$d$ $ct1=9,ct2=9
由于程序中使用的是ch='$'
,所以每次循环该if条件内代码都执行一次,因此ct1与ct2相等。同时在输入Hi!
之后键入回车,因此在读取回车之后,打印出来,光标换行,紧接着打印$。
4.创建表示下述条件的逻辑表达式:
a.weight大于或等于115,但小于125。
b.ch为q或Q。
c.x为偶数,但不是26.
d.x为偶数,但不是26。
e.donation为1000-2000或guest为1。
f.ch是小写字母或大写字母(假设小写字母是依次编码的,大写字母也是依次编码的,但在大小写字母间编码是不连续的)。
//a
weight>=115 && weight<125
//b
ch=='q' || ch=='Q'
//c
x%2==0 && x!=26
//d
x%2==0 && x%26!=0
//e
donation>=1000 && donation<=20000 || guest==1
//f
(ch>='a' && ch<='z') || (ch<='Z' && ch>='A')
5.在英语中,"I will not not speak(我不会不说) "的意思与"I will speak(我要说)"相同。在c++中,!!x是否与x相同呢?
对于bool变量而言,!!x与x是相同的,但对于其他类型变量不一定相同,例如!!5=1,!!5≠5。
6.创建一个条件表达式,其值为变量的绝对值。也就是说,如果变量x为正,则表达式的值为x;但如果x为负,则表达式的值为-x--这是一个正值。
x>=0 ? x : -x;
7.用switch改写下面的代码片段:
if(ch=='A')
a_grade++;
else if(ch=='B')
b_grade++;
else if(ch=='C')
c_grade++;
else if(ch=='D')
d_grade++;
else
f_grade++;
改写后代码:
switch(ch)
{
case 'A' : a_grade++;
break;
case 'B' : b_grade++;
break;
case 'C' : c_grade++;
break;
case 'D' : d_grade++;
break;
default : f_grade++;
break;
}
8.对于程序清单6.10,与使用字符(如a和c)表示菜单选项和case标签有何优点呢?(提示:想一想用户输入q和输入5的情况。)
程序清单6.10 switch.cpp
// switch.cpp -- using the switch statement #include <iostream> using namespace std; void showmenu(); // function prototypes void report(); void comfort(); int main() { showmenu(); int choice; cin >> choice; while (choice != 5) { switch (choice) { case 1: cout << "\a\n"; break; case 2: report(); break; case 3: cout << "The boss was in all day.\n"; break; case 4: comfort(); break; default: cout << "That's not a choice.\n"; } showmenu(); cin >> choice; } cout << "Bye!\n"; return 0; } void showmenu() { cout << "Please enter 1, 2, 3, 4, or 5:\n" "1) alarm 2) report\n" "3) alibi 4) comfort\n" "5) quit\n"; } void report() { cout << "It's been an excellent week for business.\n" "Sales are up 120%. Expenses are down 35%.\n"; } void comfort() { cout << "Your employees think you are the finest CEO\n" "in the industry. The board of directors think\n" "you are the finest CEO in the industry.\n"; }
使用数字作为菜单选项和case标签,限定了用户只有输入数字的时候才能有效,若用户错误的输入非整数类型,导致程序被挂起。而使用字符作为菜单选项和case标签,当用户输入错误类型,程序能正确通过default部分提示用户输入错误,用户体验更加友好,提高了程序的容错性和健壮性。
9.请看下面的代码片段
int line = 0;
char ch;
while(cin.get(ch))
{
if(ch=='Q')
break;
if(ch!='\n')
continue;
line++;
}
重写后代码:
int line = 0;
char ch;
while(cin.get(ch) && ch!='Q')
{
if(ch=='\n')
line++;
}
编程练习
1.编写一个程序,读取键盘输入,直到遇到@符号为止,并回显输入(数字除外),同时将大写字符转换为小写字符,将小写字符转换为大写(别忘了cctype函数系列)
#include<iostream>
#include<cctype>
using namespace std;
int main()
{
cout << "Please enter characters (type @ to stop):";
char ch;
cin.get(ch);
while (ch != '@')
{
if (islower(ch))
ch = toupper(ch);
else if (isupper(ch))
ch = tolower(ch);
if (!isdigit(ch))
cout << ch;
cin.get(ch);
}
system("pause");
return 0;
}
2.编写一个程序,最多将10个donation值读入一个double数组中(如果你愿意,也可以使用模板类array)。程序遇到非数字输入时将结束输入,并报告这些数字的平均值以及数组中有多少个数字大于平均值。
#include<iostream>
#include<array>
using namespace std;
int main()
{
array<double,10>donations;
double sum=0;
cout<<"Please enter donation(non-number to stop):";
int i;
double donation;
for(i=0;(i<10)&&(cin>>donation);++i)
{
donations[i]=donation;
sum=+donations[i];
}
double avg=sum/(i+1);
cout<<"Average:"<<avg<<endl;
cout<<"Number larger than average:";
for(int j=0;j<i;j++)
{
if(donations[j]>avg)
cout<<donations[j]<<" ";
}
cout<<endl;
return 0;
}
3.编写一个菜单驱动程序的雏形。该程序显示一个提供四个选项的菜单--每个选项用一个字母表标记。如果用户使用有效选项之外的字母进行响应,程序将提示用户输入有效的字母,直到用户这样选择为止。然后,该程序使用一条switch语句,根据用户的选择执行一个简单操作。该程序的运行情况如下:
Please enter one of the following choices:
c) carnivore p) pianist
t) tree g)game
f
Please enter a c,p,t or g:q
Please enter a c,p,t or g:t
A maple is a tree.
代码实现:
#include <iostream>
using namespace std;
int main()
{
cout<<"Please enter one of the following choices:"<<endl;
cout<<"c) carnivore p) pianist"<<endl;
cout<<"t) tree g) game"<<endl;
char ch;
cin>>ch;
while(ch!='c' && ch!='p' && ch!='t' && ch!='g')
{
cout<<"Please enter a c,p,t or g:";
cin>>ch;
}
switch (ch)
{
case 'c':
cout<<"A maple is a carnivore."<<endl;
break;
case 'p':
cout<<"A maple is a pianist."<<endl;
break;
case 't':
cout<<"A maple is a tree."<<endl;
break;
case 'g':
cout<<"A maple is a game."<<endl;
break;
default:
break;
}
return 0;
}
4.加入Benevolent Order of Programmer后,在BOP大会上,人们便可以通过加入者的真实姓名、头衔或秘密BOP姓名来了解他(她)。请编写一个程序,可以使用真实姓名、头衔、秘密姓名或成员偏好来列出成员。编写该程序时,请使用下面的结构:
//Benevolent Order of Programmers name structure
struct bop{
char fullname[strsize]; //real name
char title[strzie]; //job title
char bopname[strsize]; //secret BOP name
int preference; //0=fullname,1=title,2=bopname
};
该程序创建一个由上述结构组成的小型数组,并将其初始化为适当的值。另外,该程序使用一个循环,让用户在下面的选项中进行选择:
a.display by name b.diaplay by title
c.display by bopname d.display by preference
q.quit
注意,“display by preference”并不意味显示成员的偏好,而是意味着根据成员的偏好来列出成员。例如,如果偏好号为1,则选择d将显示程序员的头衔。该程序的运行情况如下:
Benevolent Order of Programmers Report
a. display by name b. display by title
c. display by bopname d. display by preference
q. quit
Enter your choice: a
Wimp Macho
Raki Rhodes
Celia Laiter
Hoppy Hipman
Pat Hand
Next choice: d
Wimp Macho
Junior Programmer
MIPS
Analyst Trainee
LOOPY
Next choice: q
Bye!
代码实现 :
#include <iostream>
using namespace std;
const int strsize = 20;
struct bop
{
char fullname[strsize];
char title[strsize];
char bopname[strsize];
int preference; //0 = fullname, 1 = title, 2 = bopname
};
int main()
{
int programmerNum = 5;
bop programmers[programmerNum]={{"Wimp Macho", "Junior Programmer", "WM",0},
{"Raki Rhodes", "Junior Programmer", "RR", 1},
{"Celia Laiter", "Junior Programmer", "MIPS", 2},
{"Hoppy Hipman", "Analyst Trainee", "HH", 1},
{"Pat Hand", "Junior Programmer", "LOOPY", 2}};
cout << "Benevolent Order of Programmers Report" << endl;
cout << "a. display by name b. display by title" << endl;
cout << "c. display by bopname d. display by preference" << endl;
cout << "q. quit" << endl;
cout << "Enter your choice: ";
char choice;
while(cin.get(choice))
{
if(choice == 'a')
{
for(int i = 0; i < programmerNum; i++)
{
cout << programmers[i].fullname << endl;
}
}
else if(choice == 'b')
{
for(int i = 0; i < programmerNum; i++)
{
cout << programmers[i].title << endl;
}
}
else if(choice == 'c')
{
for(int i = 0; i < programmerNum; i++)
{
cout << programmers[i].bopname << endl;
}
}
else if(choice == 'd')
{
for(int i = 0; i < programmerNum; i++)
{
if(programmers[i].preference == 0)
{
cout << programmers[i].fullname << endl;
}
else if(programmers[i].preference == 1)
{
cout << programmers[i].title << endl;
}
else
{
cout << programmers[i].bopname << endl;
}
}
}
else if(choice == 'q')
{
cout << "Bye!" << endl;
break;
}
else
{
if(choice == '\n')
{
continue;
}
cout << "input error, please re-enter!" << endl;
}
cout << "Next choice: ";
}
return 0;
}
5.在Neutronia王国,货币单位是tvarp,收入所得税的计算方式如下:
5000 tvarps: 不收税
5001-15000 tvarps: 10%
15001-35000 tvarps: 15%
35000 tvarps以上: 20%
例如,收入为38000 tvarps时,所得税为5000×0.00+10000×0.10+2000×0.15+3000×0.20,即 4600tvarps。请编写一个程序,使用循环来要求用户输入收入,并报告所得税,当用户输入负数或非数字时,循环将结束。
代码实现:
#include<iostream>
using namespace std;
int main()
{
cout << "Please enter your income(if you enter negative number or non-numberic, it will exit.) : ";
double income, tax;
while(cin >> income)
{
cout<< income <<endl;
if(income > 35000)
{
tax = 10000 * 0.10 + 20000 * 0.15 + (income - 35000) * 0.20;
}
else if(income >= 15001)
{
tax = (income - 3500) * 0.15 +10000 * 0.10;
}
else if(income >= 5001)
{
tax = (income - 5000) * 0.10;
}
else if(income >= 0)
{
tax = 0;
}
else
{
cout << "Enter negative number, exiting soon..." << endl;
break;
}
cout << "your should pay tax : " << tax << " tvarps." << endl;
cout << "Please enter another income(if you enter negative number or non-numberic, it will exit.) : ";
}
cout << "Exited, Bye !" << endl;
return 0;
}
6.编写一个程序,记录捐助给"维护合法权利团体"的资金。该程序要求用户输入捐赠者数目,然后要求用户输入每一个捐献者的姓名和款项。这些信息被存储在一个动态分配的结构数组中.每个数据结构有两个成员:用来存储姓名的字符串数组(或string对象)和用来存储款项的double成员。读取所有的数据后,程序将显示所有捐款超过10000的捐款着姓名及其捐款数额。该列表前应包含一个标题,指出下面的捐款者是重要捐款人(Grand Patrons)。然后,程序将列出其他的捐款者,该列表要以Partons开头。如果某种类别没有捐款者,则程序将打印单词"none"。该程序只显示这两种类别,而不进行排序。
代码实现:
#include<iostream>
#include<string>
using namespace std;
struct DonationInfo{
string name;
double amount;
};
void donationInfoDisplay(DonationInfo donationInfo[], int num, bool isGrandPatrons)
{
int countNum = 0;
for(int i = 0 ; i < num ; i++)
{
if(isGrandPatrons)
{
if(donationInfo[i].amount > 10000)
{
countNum++;
cout << donationInfo[i].name << endl;
}
}
else
{
if(donationInfo[i].amount <= 10000)
{
countNum++;
cout << donationInfo[i].name << endl;
}
}
}
if(countNum == 0)
cout << "none" << endl;
}
int main()
{
cout << "Please enter the number of donors :";
int num;
while(!(cin >> num))
{
cin.clear();
cin.sync();
cin.ignore();
cout << "***[WARNING]:Please enter positive integer.***" << endl;
cout << "Please enter the number of donors :";
}
DonationInfo* donationInfo = new DonationInfo[num];
for(int i = 0; i < num; i++)
{
cout << "enter the donor name :";
cin >> donationInfo[i].name;
cout << "enter the donation amount :";
cin >> donationInfo[i].amount;
}
cout << "******Grand Partons******" << endl;
donationInfoDisplay(donationInfo, num, true);
cout << "******Partons******" << endl;
donationInfoDisplay(donationInfo, num, false);
return 0;
}
7.编写一个程序,它每次读取一个单词,直到用户只输入q。然后,该程序指出有多少个单词以元音打头,有多少个单词以辅音打头,还有多少个单词不属于这两类。为此,方法之一是,使用isalpha()来区分以字母和其他字母打头的单词,然后对于通过isalpha()测试的单词,使用if或switch语句来确定哪些以元音打头。该程序的运行情况如下:
Enter words (q to quit):
The 12 awesome oxem ambled
quiety across 15 meters of lawn. q
5 words beginning with vowels
4 words beginning with consonants
2 others
代码实现:
#include<iostream>
#include<string>
using namespace std;
int main()
{
cout << "Enter words (q to quit) :" << endl;
string word;
int vowelNum = 0;
int consonantNum = 0;
int othersNum = 0;
while(cin >> word)
{
if(word == "q")
{
break;
}
else
{
if(isalpha(word[0]))
{
switch(word[0])
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
case 'A':
case 'E':
case 'I':
case 'O':
case 'U':
vowelNum++;
break;
default:
consonantNum++;
}
}
else
{
othersNum++;
}
}
}
cout << vowelNum << " words beginning with vowels" << endl;
cout << consonantNum << " words beginning with consonants" << endl;
cout << othersNum << " others" <<endl;
return 0;
}
8.编写一个程序,他打开一个文件,逐个字地读取该文件,直到到达文件末尾,然后指出该文件中包含多少个字符。
代码实现:
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
ifstream txtSource;
txtSource.open("test.txt", ios::in);
if(!txtSource.is_open())
{
cout << "File failed to open !" << endl;
exit(EXIT_FAILURE);
}
char ch;
int characterNum = 0;
while(txtSource >> ch)
{
characterNum++;
}
cout << "The file contains " << characterNum << " characters" << endl;
return 0;
}
9.完成编程练习6,但从文件中读取所需的信息。该文件的第一项应为捐款人数,余下的内容应为对的行。在每一对中,第一行为捐款人姓名,第二行为捐款数额。即该文件类似于下面:
代码实现:
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
struct DonationInfo{
string name;
double amount;
};
void donationInfoDisplay(DonationInfo donationInfo[], int num, bool isGrandPatrons)
{
int countNum = 0;
for(int i = 0 ; i < num ; i++)
{
if(isGrandPatrons)
{
if(donationInfo[i].amount > 10000)
{
countNum++;
cout << donationInfo[i].name << endl;
}
}
else
{
if(donationInfo[i].amount <= 10000)
{
countNum++;
cout << donationInfo[i].name << endl;
}
}
}
if(countNum == 0)
cout << "none" << endl;
}
int main()
{
cout << "Read file content..." << endl;
ifstream txtDonationInfo;
txtDonationInfo.open("test.txt", ios::in);
if(!txtDonationInfo.is_open())
{
cout << "File failed to open !" << endl;
exit(EXIT_FAILURE);
}
int num = 0;
(txtDonationInfo >> num).get();
DonationInfo* donationInfo = new DonationInfo[num];
for(int i = 0; i < num; i++)
{
txtDonationInfo >> donationInfo[i].name;
txtDonationInfo >> donationInfo[i].amount;
}
cout << "******Grand Partons******" << endl;
donationInfoDisplay(donationInfo, num, true);
cout << "******Partons******" << endl;
donationInfoDisplay(donationInfo, num, false);
return 0;
}
第七章课后习题答案
复习题
1. 使用函数的3个步骤是什么?
定义函数、提供函数、调用函数。
2.请创建与下面的描述相匹配的函数原型。
a. igor()没有参数,且没有返回值
b. tofu()接受一个int参数,并返回一个float
c. mpg()接受两个double参数,并返回一个double
d. summation()将long数组名和数组长度作为参数,并返回一个long值
e. doctor()接受一个字符串参数(不能修改该字符串),并返回一个double值
f. ofcourse()将boss结构作为参数,并返回一个字符串
g. plot()将map结构的指针作为参数,并返回一个字符串
a. void igor(void);
b. float tofu(int n);
c. double mpg(double m, double n);
d. long summation(long arr[], int size);
e. double doctor(const char* str);
f. char* ofcourse(boss bs);
g. char* plot(map *mp);
3. 编写一个接受3个参数的函数:int 数组名、数组长度和一个int值,并将数组的所有元素设为该int值。
void setArrValue(int arr[], int size, int value)
{
for(int i = 0, i < size; i++)
{
arr[i] = value;
}
}
4. 编写一个接受3个参数的函数:指向数组区间中第一个元素的指针、指向数组最后一个了元素后面的指针以及一个int值,并将数组中的每个元素都设置为该int值。
void setArr(int* begin,int *end, int value)
{
for(int* pt = begin; pt != end; pt++)
{
*pt = value;
}
}
5. 编写将double数组名和数组长度作为参数,并返回该数组中最大值的函数。该函数不应该修改数组的内容。
double OutMaxValue(const double arr[], int size)
{
double max;
if(size < 1)
{
cout << "Array size is INVALID!" << endl;
cout << "will return 0."
return 0;
}
else
{
max = arr[0];
for(int i =0; i < size; i++)
{
if(max < arr[i])
max = arr[i];
}
return 0;
}
}
6. 为什么不对类型为基本类型的函数参数使用const限定符?
因为函数在调用参数时,使用的是参数的副本,不是原来的值,因此不会修改作为实参的基本类型的值,原数据就得到了保护。但是对于指针,需要使用const来防止指向的原始数据被修改。
7. C++程序可以使用哪三种C-风格的字符串格式?
字符串可以存储在char数组中,可以用带双引号的字符串来表示,也可以用指向字符串第一个字符的指针表示。
8. 编写一个函数,其原型如下:
int replace(char * str, char c1, char c2)
该函数将字符串中所c1都替换为c2,并返回替换次数。
int replance(char*str, char c1, char c2)
{
int count = 0;
while(*str)
{
if(*str == c1)
{
*str = c2;
count++;
}
str++;
}
return count;
}
9.表达式*"pizza"的含义是什么?"taco"[2]呢?
c++将*"pizza"
中"pizza"解释为其第一个元素的地址,在使用*运算符将得到第一个元素的值,即字符p。c++将"taco"解释为其第一个元素的地址,因此它将"taco[2]"解释为第2个元素的值,即字符c。(注:字符常量的行为与数组名相同)
10. C++允许按值传递结构,也允许传递结构的地址,如果glitz是一个结构变量,如何按值传递它?如何传递他的地址?这两种方法有什么利弊?
如果要按值传递,只需要传递结构名glitz即可。若传递地址,需要使用地址运算符&glitz。按值传递可以保护原始数据,但是牺牲内存和时间为代价。按地址传递可以节省时间和内存,但是不能保护原始数据,除非使用const限定符。(按值传递意味着可以使用常规的结构成员表示法,但传递指针必须使用间接成员运算符。)
11.函数judge()的返回类型为int,它将这样一个函数的地址作为参数 :将const char指针作为参数,并返回一个int值。请编写judge()函数原型。
int judge(int (*pf)(const char*))
12.假设有如下结构声明:
struct applicant
{
char name[30];
int credit_ratings[3];
}
a.编写一个函数,将它的applicant结构作为参数,并显示该结构的的内容。
b.编写一个函数,将applicant结构作的地址作为参数,并显示该结构的内容。
//a.applicant结构作为参数
void display(applicant ap)
{
cout << ap.name << endl;
for(int i = 0; i < 3; i++)
{
cout << ap.credit_ratings[i] << endl;
}
}
//b.applicant结构的地址作为参数
void display(applicant *ap)
{
cout << ap->name << endl;
for(int i = 0; i < 3; i++)
{
cout << ap->credit_ratings[i] << endl;
}
}
13.假设函数f1()和f2()的原型如下:
void f1(applicant *a)
const char * f2(const applicant *a1, const applicant *a2)
请将p1和p2分别声明指向f1和f2的指针;将ap声明为一个数组,它包含5个类型的与p1相同的指针;将pa声明为一个指针,它指向的数组包含10个类型与p2相同的指针。使用typedef来帮助完完成这项工作。
typedef void (* pf1) (applicant *a);
typedef void (* pf2) (const applicant *a1, const applicant *a2);
pf1 p1 = f1;
pf2 p2 = f2;
pf1 ap[5];
pf2 (*pa)[10];
编程练习
1.编写一个程序,不断要求用户输入两个数,直到其中一个为0。对于每两个数,程序将使用一个函数来计算它的调和平均数,并将结果返回给main(),而后者将报告结果。调和平均数指的是倒数平均值的倒数,计算公式如下:
调和平均数=2.0*x*y/(x+y)
代码实现:
#include<iostream>
using namespace std;
double calculateHarmonicMean(double x, double y);
int main()
{
double a, b;
cout << "Please enter two numbers (if one is zero, stop):";
cin >> a;
cin >> b;
while (a && b)
{
cout << "Harmonic mean of " << a << " and " << b << " = " << calculateHarmonicMean(a, b) << endl;
cout << "Enter agen(if one is zero, stop):";
(cin >> a) >> b;
}
system("pause");
return 0;
}
double calculateHarmonicMean(double x, double y)
{
return 2.0 * x * y / (x + y);
}
2.编写一个程序,要求用户输入最多10个高尔夫成绩,并将其存入到一个数组中。程序允许用户提早结束输入,并在一行上显示所有成绩,然后报告平均成绩。请使用3个数组处理函数来分别进行输入、显示和计算平均成绩。
代码实现:
#include<iostream>
using namespace std;
double SCORES[10];
int fillScore(double* score);
void display(double* score, int n);
double getAverage(double* score, int n);
int main()
{
double scores[10] = { 0 };
int n = fillScore(scores);
display(scores, n);
cout << "AVERAGESCORE: " << getAverage(scores, n) << endl;
system("pause");
return 0;
}
int fillScore(double* score)
{
cout << "Please enter the scores(maximum quantity=10),"<< endl;
cout << "If you want to end the input, enter a letter!" << endl;
double value;
int i;
for (i = 0; i < 10; i++)
{
cout << "enter the " << i + 1 << " Score:";
if (i > 9)
break;
else
{
if (cin >> value)
score[i] = value;
else
break;
}
}
cout << "QUANTITY: " << i << endl;
return i;
}
void display(double* score, int n)
{
cout << "SCORES: ";
for (int i = 0; i < n; i++)
cout << score[i] << " ";
cout << endl;
}
double getAverage(double* score, int n)
{
double sum=0;
for (int i = 0; i < n; i++)
sum += score[i];
return sum / n;
}
3.下面是一个结构声明:
struct box
{
char marker[40];
float height;
float width;
float length;
float volume;
};
a.编写一个函数,按值传递box结构,并显示每个成员的的值。
b.编写一个函数,传递box结构的地址,并将volume成员设置为其他三维长度的成绩。
c.编写一个使用这两个函数的简单程序。
代码实现:
#include<iostream>
using namespace std;
struct box
{
char marker[40];
float height;
float width;
float length;
float volume;
};
void calculationBoxVolume(box* pbox);
void display(box bx);
int main()
{
box bx = { "jianmo1993",1.0,1.0,1.0,0.0 };
calculationBoxVolume(&bx);
display(bx);
system("pause");
return 0;
}
void display(box bx)
{
cout << "BOX'S INFORMATION:" << endl;
cout << "maker : " << bx.marker << endl;
cout << "height : " << bx.height << endl;
cout << "width : " << bx.width << endl;
cout << "length : " << bx.length << endl;
cout << "volume : " << bx.volume << endl;
}
void calculationBoxVolume(box* pbox)
{
pbox->volume = pbox->height * pbox->length * pbox->width;
}
4.许多州的彩票发行机构都使用如程序清单7.4所示的简单彩票玩法的变体。在这些玩法中,玩家从一组被称为域号码(field number)的号码中选择几个。例如,可以从域号码1~47中选择5个号码;还可以从第二个区间(如1~27)选择一个号码(成为特选号码)。要赢得头奖,必须正确猜中所有的号码。中头奖的几率是选中所有域号码的几率与选中特选号几率的乘积。例如,在这个例子中,中头奖的几率从47个号码中正确选取5个号码的几率与从27个号码中正确选择1个号码的几率的乘积。请修改程序清单7.4,以计算中得这中彩票头奖的几率。
代码实现:
#include<iostream>
using namespace std;
long double probability(unsigned numbers, unsigned picks);
int main()
{
long double result1,result2, result;
result1 = probability(47, 5);
result2 = probability(27, 1);
result = result1 * result2;
cout << "Odds of lottery jackpot : " << result << endl;
system("pause");
return 0;
}
long double probability(unsigned numbers, unsigned picks)
{
long double result = 1.0;
unsigned n, p;
for (n = numbers, p = picks; p > 0; n--, p--)
{
result = result * p / n;
}
return result;
}
5.定义一个递归函数,接受一个整数参数,并返回该参数的阶乘。前面讲过,3的阶乘写作3!,等于3*2!,以此类推;而0!的阶乘被定义为1。被定义为1.通用的计算公式是,如果n大于零 , 则n! = n * (n - 1)!。在程序中对该函数进行测试,程序使用循环让用户 输入不同的值,程序将报告这些值的阶乘。
代码实现:
#include<iostream>
using namespace std;
long factorial(long n);
int main()
{
long n;
cout << "CALCULATION OF FACTORIAL" << endl;
cout << "Enter number : ";
while (cin >> n)
{
long result = factorial(n);
cout << n << "! = " << result << endl;
cout << "Next number(q to quit):";
}
cout << "Bye!" << endl;
system("pause");
return 0;
}
long factorial(long n)
{
if (n == 1 || n == 0)
return 1;
else
return n * factorial(n - 1);
}
6.编写一个程序,它使用下列函数:
` Fill_array()`将一个double数组的名称和长度作为参数。它提示用户输入double值,并将这些值存储到数组中。当数组被填满或 用户输入了非数字时,输入将停止,并返回实际输入了多少个数字。
`Show_array()`将一个double数组的名称和长度作为参数,并显示该数组的内容。
`Reverse-array()`将一个double数组的名称和长度作为参数,并将存储在数组中的值的顺序反转。
程序将使用这些函数来填充数组,然后显示数组;反转数组,然后显示数组;反转数组中除第一个和最后一个元素之外的所有元素, 然后显示数组。
代码实现:
#include<iostream>
using namespace std;
const int n = 5;
int Fill_array(double* arr, int n);
void Show_array(double* arr, int n);
void Reverse_array(double* arr, int n);
int main()
{
double arr[n] = { 0.0 };
Fill_array(arr, n);
Show_array(arr, n);
Reverse_array(arr, n);
Show_array(arr, n);
system("pause");
return 0;
}
int Fill_array(double* arr, int n)
{
cout << "Please enter double number : ";
int i;
for (i = 0; i < n; i++)
{
if (cin >> arr[i])
{
cout << "Enter next number : ";
}
else
{
cout << "Type enter error!" << endl;
}
}
return i;
}
void Show_array(double* arr, int n)
{
cout << "ARRAY MEMBER : ";
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
void Reverse_array(double* arr, int n)
{
int med = n / 2;
double temp;
for (int i = 0; i < med; i++)
{
temp = arr[i];
arr[i] = arr[n - 1 - i];
arr[n - 1 - i] = temp;
}
}
7.修改程序清单7.7中的3个数组处理函数,使之使用两个指针参数来表示区间。file_array()函数不返回实际读取了多少个数字,而是返回一个指针,该指针指向最后被填充的位置。其他的函数可以将该指针作为第二个参数,以标识数据结尾。
清单7.7:
/*******************************-清单7.7********************************/ // arrfun3.cpp -- array functions and const #include <iostream> const int Max = 5; // function prototypes int fill_array(double ar[], int limit); void show_array(const double ar[], int n); // don't change data void revalue(double r, double ar[], int n); int main() { using namespace std; double properties[Max]; int size = fill_array(properties, Max); show_array(properties, size); if (size > 0) { cout << "Enter revaluation factor: "; double factor; while (!(cin >> factor)) // bad input { cin.clear(); while (cin.get() != '\n') continue; cout << "Bad input; Please enter a number: "; } revalue(factor, properties, size); show_array(properties, size); } cout << "Done.\n"; // cin.get(); // cin.get(); return 0; } int fill_array(double ar[], int limit) { using namespace std; double temp; int i; for (i = 0; i < limit; i++) { cout << "Enter value #" << (i + 1) << ": "; cin >> temp; if (!cin) // bad input { cin.clear(); while (cin.get() != '\n') continue; cout << "Bad input; input process terminated.\n"; break; } else if (temp < 0) // signal to terminate break; ar[i] = temp; } return i; } // the following function can use, but not alter, // the array whose address is ar void show_array(const double ar[], int n) { using namespace std; for (int i = 0; i < n; i++) { cout << "Property #" << (i + 1) << ": $"; cout << ar[i] << endl; } } // multiplies each element of ar[] by r void revalue(double r, double ar[], int n) { for (int i = 0; i < n; i++) ar[i] *= r; } /**********************************************************************/
代码实现:
/*******************************-清单7.7********************************/
#include <iostream>
const int Max = 5;
// function prototypes
double* fill_array(double* begin, double* end);
void show_array(double* begin, double* end); // don't change data
void revalue(double r, double* start, double* end);
int main()
{
using namespace std;
double properties[Max];
double* end = fill_array(properties, properties + Max - 1);
show_array(properties, end);
if ((end - properties) > 0)
{
cout << "Enter revaluation factor: ";
double factor;
while (!(cin >> factor)) // bad input
{
cin.clear();
while (cin.get() != '\n')
continue;
cout << "Bad input; Please enter a number: ";
}
revalue(factor, properties, end);
show_array(properties, end);
}
cout << "Done.\n";
// cin.get();
// cin.get();
return 0;
}
double* fill_array(double* begin, double* end)
{
using namespace std;
double* temp;
int i = 0;
for (temp = begin; temp <= end; temp++)
{
cout << "Enter value #" << (i + 1) << ": ";
cin >> *temp;
if (!cin) // bad input
{
cin.clear();
while (cin.get() != '\n')
continue;
cout << "Bad input; input process terminated.\n";
break;
}
else if (*temp < 0) // signal to terminate
break;
}
return temp - 1;
}
void show_array(double* begin, double* end)
{
using namespace std;
double* p;
int i = 0;
for (p = begin; p <= end; p++)
{
cout << "Property #" << (i + 1) << ": $";
cout << *p << endl;
}
}1
void revalue(double r, double* start, double* end)
{
double* p;
for (p = start; p <= end; p++)
*p *= r;
}
8.在不使用array类的情况下完成程序清单7.15所做的工作。编写两个这样的版本:
a.使用const char *数组存储表示季度名称的字符串,并使用double数组存储开支。
b.使用const char *数组存储表示季度名称的字符串,并使用一个结构,该结构只有一个成员——一个用于存储开支的double数组。这种设计与使用array类基本设计类似。
清单7.15:
//arrobj.cpp -- functions with array objects #include <iostream> #include <array> #include <string> const int Seasons = 4; const std::array<std::string, Seasons> Snames = {"Spring", "Summer", "Fall", "Winter"}; void fill(std::array<double, Seasons> * pa); void show(std::array<double, Seasons> da); int main() { std::array<double, 4> expenses; fill(&expenses); show(expenses); // std::cin.get(); // std::cin.get(); return 0; } void fill(std::array<double, Seasons> * pa) { for (int i = 0; i < Seasons; i++) { std::cout << "Enter " << Snames[i] << " expenses: "; std::cin >> (*pa)[i]; } } void show(std::array<double, Seasons> da) { double total = 0.0; std::cout << "\nEXPENSES\n"; for (int i = 0; i < Seasons; i++) { std::cout << Snames[i] << ": $" << da[i] << '\n'; total += da[i]; } std::cout << "Total: $" << total << '\n'; } /********************************************************************/
代码实现:
a.
#include <iostream>
#include <array>
#include <string>
const int Seasons = 4;
const char* Snames[Seasons] =
{ "Spring", "Summer", "Fall", "Winter" };
void fill(double* pa, int n);
void show(double* da, int n);
int main()
{
double expenses[Seasons];
fill(expenses, Seasons);
show(expenses, Seasons);
return 0;
}
void fill(double* pa, int n)
{
for (int i = 0; i < n; i++)
{
std::cout << "Enter " << Snames[i] << " expenses: ";
std::cin >> pa[i];
}
}
void show(double* da, int n)
{
double total = 0.0;
std::cout << "\nEXPENSES\n";
for (int i = 0; i < n; i++)
{
std::cout << Snames[i] << ": $" << da[i] << '\n';
total += da[i];
}
std::cout << "Total: $" << total << '\n';
}
b.
#include <iostream>
#include <array>
#include <string>
const int Seasons = 4;
const char* Snames[Seasons] =
{ "Spring", "Summer", "Fall", "Winter" };
struct Expenses
{
double expenses[Seasons];
};
void fill(Expenses* exp, int n);
void show(Expenses* exp, int n);
int main()
{
Expenses expenses;
fill(&expenses, Seasons);
show(&expenses, Seasons);
return 0;
}
void fill(Expenses* exp, int n)
{
double* pa = exp->expenses;
for (int i = 0; i < n; i++)
{
std::cout << "Enter " << Snames[i] << " expenses: ";
std::cin >> pa[i];
}
}
void show(Expenses* exp, int n)
{
double* da = exp->expenses;
double total = 0.0;
std::cout << "\nEXPENSES\n";
for (int i = 0; i < n; i++)
{
std::cout << Snames[i] << ": $" << da[i] << '\n';
total += da[i];
}
std::cout << "Total: $" << total << '\n';
}
9.这个练习让您编写处理数组和结构的函数。下面是程序的框架,请提供其中描述的函数,以完成该程序。
#include <iostream> using namespace std; const int SLEN = 30; struct student { char fullname[SLEN]; char hobby[SLEN]; int ooplevel; }; // getinfo() has two arguments: a pointer to the first element of // an array of student structures and an int representing the // number of elements of the array. The function solicits and // stores data about students. It terminates input upon filling // the array or upon encountering a blank line for the student // name. The function returns the actual number of array elements // filled. int getinfo(student pa[], int n); // display1() takes a student structure as an argument // and displays its contents void display1(student st); // display2() takes the address of student structure as an // argument and displays the structure’s contents void display2(const student* ps); // display3() takes the address of the first element of an array // of student structures and the number of array elements as // arguments and displays the contents of the structures void display3(const student pa[], int n); int main() { cout << "Enter class size : "; int class_size; cin >> class_size; while (cin.get() != '\n') continue; student* ptr_stu = new student[class_size]; int entered = getinfo(ptr_stu, class_size); for (int i = 0; i < entered; i++) { display1(ptr_stu[i]); display2(&ptr_stu[i]); } display3(ptr_stu, entered); delete[] ptr_stu; cout << "Done\n"; return 0; }
代码实现:
#include <iostream>
using namespace std;
const int SLEN = 30;
struct student {
char fullname[SLEN];
char hobby[SLEN];
int ooplevel;
};
int getinfo(student pa[], int n);
void display1(student st);
void display2(const student* ps);
void display3(const student pa[], int n);
int main()
{
cout << "Enter class size : ";
int class_size;
cin >> class_size;
while (cin.get() != '\n')
continue;
student* ptr_stu = new student[class_size];
int entered = getinfo(ptr_stu, class_size);
for (int i = 0; i < entered; i++)
{
display1(ptr_stu[i]);
display2(&ptr_stu[i]);
}
display3(ptr_stu, entered);
delete[] ptr_stu;
cout << "Done\n";
return 0;
}
int getinfo(student pa[], int n)
{
int num = 0;
for (int i = 0; i < n; i++)
{
cout << "Enter #" << i + 1 << " student' info:" << endl;
cout << "fullname : ";
cin.getline(pa[i].fullname, SLEN);
if (pa[i].fullname[0] == '\0')
break;
cout << "hobby : ";
cin.getline(pa[i].hobby, SLEN);
cout << "ooplevel : ";
(cin >> pa[i].ooplevel).get();
num++;
}
return num;
}
void display1(student st)
{
cout << "name: " << st.fullname << endl;
cout << "hobby: " << st.hobby << endl;
cout << "ooplevel: " << st.ooplevel << endl;
}
void display2(const student* ps)
{
cout << "name: " << ps->fullname << endl;
cout << "hobby: " << ps->hobby << endl;
cout << "ooplevel: " << ps->ooplevel << endl;
}
void display3(const student pa[], int n)
{
for(int i = 0; i < n; i++)
{
display2(&pa[i]);
}
}
10.设计一个名为calculate()的函数,它接受两个double值和一个指向函数的指针,而被指向的函数接受两个double参数,并返回一个double值。calculate()函数的类型也是double,并返回被指向的函数使用calculate()的两个double参数计算得到的值。例如,假设add()函数的定义如下:
double add (double x, double y)
{
return x + y;
}
则下述代码中的函数调用将导致calculate()把2.5和10.4传递给add()函数,并返回add()的返回值(12.9):
double q = calculate (2.5, 10.4, add);
请编写一个程序,它调用上述两个函数和至少另一个与add()类似的函数。该程序使用循环来让用户成对地输入数字。对于每对数字,程序都使用calculate()来调用add()和至少一个其他的函数。如果读者爱冒险,可以尝试创建一个指针数组,其中的指针指向add()样式的函数,并编写一个循环,使用这些指针连续让calculate()调用这些函数。提示:下面是声明这种指针数组的方式,其中包含三个指针:
double (*pf[3]) (double, double);
可以采用数组初始化语法,并将函数名作为地址来初始化这样的数组。
代码实现:
#include <iostream>
using namespace std;
typedef double (*pfunc)(double x, double y);
double add(double x, double y);
double multiply(double x, double y);
double calculate(double x, double y, pfunc pf);
int main()
{
pfunc pf[2] = {add, multiply};
cout << "Please enter two numbers : ";
double a, b;
while ((cin >> a) >> b)
{
for (int i = 0; i < 2; i++)
{
cout << a;
if(i == 0)
cout << " + ";
else
cout << " * ";
cout << b << " = " << calculate(a, b, pf[i]) << endl;
}
cout << "Next two numbers(q to quit) : ";
}
return 0;
}
double add(double x , double y)
{
return x + y;
}
double multiply(double x, double y)
{
return x * y;
}
double calculate(double x, double y, pfunc pf)
{
return pf(x, y);
}
第八章课后习题答案
复习题
1.哪种函数适合定义为内联函数?
只有一行代码的小型、非递归的函数适合作为内联函数。
2假设song()函数的原形如下:
void song(const char * name, int times);
a.如何修改原形,使times的默认值为1?
b.函数定义需要做哪些修改?
c.能否为name提供默认值"O,My Papa"?
a.void song(const char * name, int times = 1);
b.函数定义不需要修改,只有函数原型包含默认信息。
c.可以,void song(char * name ="O,My Papa", int times = 1);
3.编写iquote()的重载版本--显示其用双引号括起的参数,编写3个版本:一个用于int参数,一个用于double参数,另一个用于string参数。
//用于 int 参数
void iquote(int n)
{
cout << "\"" << n << "\"" << endl;
}
//用于 double 参数
void iquote(couble n)
{
cout << "\"" << n << "\"" << endl;
}
//用于 string 参数
void iquote(char * str)
{
cout << "\"" << str << "\"" << endl;
}
4.下面是一个结构模板:
struct box
{
char maker[40];
float height;
float width;
float length;
float volume;
}
a.请编写一个函数,他将box结构体的引用作为形参,并显示每个成员的值。
b.请编写一个函数,他将box结构的引用作为行参,并将volume成员设置为其他3边的乘积。
a.
void showBox(const box & b)
{
cout << "maker : " << b.maker << endl;
cout << "height : " << b.height <<endl;
cout << "width : " << b.width << endl;
cout << "length : " << b.length <<endl;
cout << "volume : " << b.volume << endl;
}
b.
void setVolume(box & b)
{
b.volume = b.height * b.width * b.length;
}
5.为让函数fill()和show()使用引用参数,需要对程序清单7.15做哪些修改?
修改后的代码:
#include <iostream>
#include <array>
#include <string>
const int Seasons = 4;
const std::array<std::string, Seasons> Snames =
{"Spring", "Summer", "Fall", "Winter"};
void fill(std::array<double, Seasons> &pa);
void show(const std::array<double, Seasons> &da);
int main()
{
std::array<double, 4> expenses;
fill(expenses);
show(expenses);
return 0;
}
void fill(std::array<double, Seasons> &pa)
{
for (int i = 0; i < Seasons; i++)
{
std::cout << "Enter " << Snames[i] << " expenses: ";
std::cin >> pa[i];
}
}
void show(const std::array<double, Seasons> &da)
{
double total = 0.0;
std::cout << "\nEXPENSES\n";
for (int i = 0; i < Seasons; i++)
{
std::cout << Snames[i] << ": $" << da[i] << '\n';
total += da[i];
}
std::cout << "Total: $" << total << '\n';
}
6.指出下面每个目标是否可以使用默认参数或函数重载完成,或者这两种方法都无法完成,并提供合适的原型。
a. mass(density,volume)返回密度为density、体积为volume的物体的质量,而mass(density)返回密度为density、体积为1.0立法米的物体的质量。这些值的类型都为double。
b. repeat(10,"I'm OK")将指定的字符串显示10次,而repeat("But you're kind of stupid")将指定的字符串显示5次。
c. average(3,6)返回两个int参数的平均值(int类型),而average(3.0,6.0)返回两个double值的平均值(double类型)。
d. mangle("I'm glad to meet you")根据是将值赋给char变量还是char*变量,分别返回字符1和指向字符串“I'm glad to meet you”的指针。
a.
//既可以使用默认参数,又可以使用函数重载
//1.默认参数
double mass(double density, double volume = 1.0);
//2.函数重载
double mass(double density, double volume);
double mass(double density);
b.
//不能使用默认参数,因为使用默认值必须从右到左提供默认值
//函数重载
void repeat(int times, const char* str);
void repeat(const char* str);
c.
//函数重载
int average(int a, int b);
double average(double a, double b);
d.两种方法都不能完成,需分成两个不同的函数实现。
7.编写返回两个参数中较大值的函数模板。
代码实现:
template<class T>
T max(T t1, T t2)
{
return t1 > t2 ? t1 : t2;
}
8.给定复习题6的模板和复习题4的box结构,提供一个模板具体化,它接受两个box参数,并返回体积较大的一个。
代码实现:
template<>
box max(box b1, box b2)
{
return b1.volume > b2.volume ? b1 : b2;
}
9.在下述代码(假定这些代码是一个完整程序的一部分)中,v1、v2、v3、v4和v5分别是哪种类型?
int g(int x);
....
float m = 5.5f;
float &rm = m;
decltype(m)v1 = m;
decltype(rm)v2 = m;
decltype((m)) v3 = m;
decltype(g(100))v4;
decltype(2.0*m)v5;
decltype(m)v1 = m; //类型为float
decltype(rm)v2 = m; //类型为float &
decltype((m)) v3 = m; //类型为float &
decltype(g(100))v4; //类型为int
decltype(2.0*m)v5; //类型为double
编程练习
1. 编写通常接受一个参数(字符串的地址),并打印该字符串的函数。然而,如果提供了第二个参数(int类型),且该参数不为0,则该函数打印字符串的次数将为该函数被调用的次数(注意,字符串的打印次数不等于第二个参数的值,而等于函数被调用的次数)。是的,这是一个非常可笑的函数,但它让您能够使用本章介绍的一些技术。在一个简单的程序中使用该函数,以演示该函数是如何工作的。
代码实现:
#include<iostream>
using namespace std;
int myShowStr(char* str, int printTimes);
int main()
{
char mystr[50] = "Hello,world!";
myShowStr(mystr, 5);
return 0;
}
int myShowStr(char* str, int printTimes)
{
if(printTimes > 1)
{
cout << str << endl;
printTimes--;
myShowStr(str, printTimes);
}
else
{
cout << str << endl;
}
return printTimes;
}
2. CandyBar结构包含3个成员,第一个成员存储candy bar的品牌名称;第二个成员存储candy bar的重量(可能有小数);第三个成员存储candy bar的热量(整数)。请编写一个程序,它使用一个这样的函数,即将CandyBar的引用、char指针、double和int作为参数,并用最后3个值设置相应的结构成员。最后3个参数的默认值分别为“Millennium Munch”、2.85和350。另外,该程序还包含一个以CandyBar的引用为参数,并显示结构内容的函数。请尽可能使用const。
代码实现:
#include<iostream>
using namespace std;
#define DEFAULT_BRAND (char*)"Millennium Munch"
struct CandyBar{
char* brand;
double weight;
int heat;
};
void setCandyBar(CandyBar& candyBar, char* brand = DEFAULT_BRAND, double weight = 2.85, int heat = 350);
void display(const CandyBar& candyBar);
int main()
{
CandyBar cb,cb1;
setCandyBar(cb1);
setCandyBar(cb, (char*)"MJJ", 3.55, 120);
display(cb);
display(cb1);
return 0;
}
void setCandyBar(CandyBar& candyBar, char *brand, double weight, int heat)
{
candyBar.brand = brand;
candyBar.weight = weight;
candyBar.heat = heat;
}
void display(const CandyBar& candyBar)
{
cout << "BRAND : " << candyBar.brand << endl;
cout << "WEIGHT : " << candyBar.weight << endl;
cout << "HEAT : " << candyBar.heat << endl;
}
3. 编写一个函数,它接受一个指向string对象的引用作为参数,并将该string对象的内容转化成大写,为此可以使用表6.4描述的函数toupper()。然后编写一个程序,它通过使用一个循环让您能够用不同的输入来测试这个函数,该程序的运行如下:
Enter a string (q to quit):go away
GO AWAY
Enter a string (q to quit):good grief!
GOOD GRIEF!
Enter a string (q to quit):q
Bye.
代码实现:
#include<iostream>
#include<string>
using namespace std;
void Conversion(string& str);
int main()
{
string str;
cout<<"Enter a string(q to quit): ";
while(getline(cin,str) && str != "q")
{
Conversion(str);
cout << str << endl;
cout << "Next string(q to quit): ";
}
cout << "Bye." << endl;
return 0;
}
void Conversion(string& str)
{
int size = str.size();
for(int i =0; i < size; i++)
{
str[i] = toupper(str[i]);
}
}
4.下面是一个程序框架:
#include<iostream>
#include<cstring>
using namespace std;
struct stringy{
char * str;
int ct;
};
int main()
{
stringy beany;
char testing[] = "Reality isn't what it used to be.";
set(beany, testing);
show(beany);
show(beany, 2);
testing[0] = 'D';
testing[1] = 'u';
show(testing);
show(testing, 3);
show("Done!");
return 0;
}
请提供其中描述的函数和原型,从而完成该程序。注意,应有两个show()函数,每个都使用默认参数。请尽可能使用const参数。set()使用new分配足够的空间来存储指定的字符串。这里使用的技术与设计和实现类时使用的相似。(可能还必须修改头文件的名称,删除using编译指令,这取决于所用的编译器)。
代码实现:
#include<iostream>
#include<cstring>
using namespace std;
struct stringy{
char * str;
int ct;
};
void set(stringy& stry, const char* test);
void show(const stringy& stry, int showTimes = 1);
void show(const char* ch, int showTimes = 1);
int main()
{
stringy beany;
char testing[] = "Reality isn't what it used to be.";
set(beany, testing);
show(beany);
show(beany, 2);
testing[0] = 'D';
testing[1] = 'u';
show(testing);
show(testing, 3);
show("Done!");
return 0;
}
void set(stringy& stry, const char* test)
{
stry.ct = strlen(test);
stry.str = new char[stry.ct];
strcpy(stry.str, test);
}
void show(const stringy& stry, int showTimes)
{
for(int i =0; i < showTimes; i++)
{
cout << stry.str <<endl;
}
}
void show(const char* ch, int showTimes)
{
for(int i =0; i < showTimes; i++)
{
cout << ch <<endl;
}
}
5.编写模板函数max5(),它将一个包含5个T类型元素的数组作为参数,并返回数组中最大的元素(由于长度固定,因此可以在循环中使用硬编码,而不必通过参数来传递)。在一个程序使用该函数,将T替换为一个包含5个int值的数组和一个包含5个double值的数组,以测试该函数。
代码实现:
#include<iostream>
using namespace std;
template<typename T>
T max5(T *t);
int main()
{
int arr1[5] = {5, 3, 5, 9, 6};
double arr2[5] = {5.2, 3.1, 6.8, 10.8, 7.1};
cout << "arr1 max num : " << max5(arr1) << endl;
cout << "arr2 max num : " << max5(arr2) << endl;
return 0;
}
template<typename T>
T max5(T* t)
{
T maxValue = t[0];
for(int i = 1; i < 5; i++)
{
if(maxValue < t[i])
{
maxValue = t[i];
}
}
return maxValue;
}
6.编写模板函数maxn(),他将由一个T类型元素组成的数组和一个表示数组元素数目的整数作为参数,并返回数组中最大的元素。在程序对它进行测试,该程序使用一个包含6个int元素的数组和一个包含4个都不了元素的数组来调用该函数。程序还包含一个具体化,他将char指针数组和数组中的指针数量作为参数,并返回最长的字符串的地址。如果有多个这样的字符串,则返回其中第一个字符串的地址。使用由5个字符串指针组成的数组来测试该具体化。
代码实现:
#include<iostream>
#include<cstring>
using namespace std;
template<typename T>
T maxn(T* t, int n);
template<>
char* maxn(char* pch[], int n);
int main()
{
int arr1[6] = {5, 3, 5, 9, 6, 11};
double arr2[4] = {5.2, 3.1, 2.8, 4.8};
char const * arr3[5] = {
"abcde",
"abcdef",
"abc",
"ab",
"abcdefg"
};
cout << "arr1 max num : " << maxn(arr1, 6) << endl;
cout << "arr2 max num : " << maxn(arr2, 4) << endl;
cout << "arr3 max len : " << maxn(arr3, 5) << endl;
return 0;
}
template<typename T>
T maxn(T* t, int n)
{
T maxValue = t[0];
for(int i = 1; i < n; i++)
{
if(maxValue < t[i])
{
maxValue = t[i];
}
}
return maxValue;
}
template<>
char* maxn(char* pch[], int n)
{
auto maxLen = strlen(pch[0]);
int index = 0;
for(int i = 1; i < n; i++)
{
if(maxLen < strlen(pch[i]))
{
maxLen = strlen(pch[i]);
index = i;
}
}
return pch[index];
}
7.修改程序清单8.14,使其使用两个名为SumArray()的模板函数来返回数组元素的总和,而不是显示数组的内容。程序应显示thing的总和以及所有debt的总和。
/******************程序清单8.14******************/ // tempover.cpp --- template overloading #include <iostream> template <typename T> // template A void ShowArray(T arr[], int n); template <typename T> // template B void ShowArray(T * arr[], int n); struct debts { char name[50]; double amount; }; int main() { using namespace std; int things[6] = {13, 31, 103, 301, 310, 130}; struct debts mr_E[3] = { {"Ima Wolfe", 2400.0}, {"Ura Foxe", 1300.0}, {"Iby Stout", 1800.0} }; double * pd[3]; // set pointers to the amount members of the structures in mr_E for (int i = 0; i < 3; i++) pd[i] = &mr_E[i].amount; cout << "Listing Mr. E's counts of things:\n"; // things is an array of int ShowArray(things, 6); // uses template A cout << "Listing Mr. E's debts:\n"; // pd is an array of pointers to double ShowArray(pd, 3); // uses template B (more specialized) // cin.get(); return 0; } template <typename T> void ShowArray(T arr[], int n) { using namespace std; cout << "template A\n"; for (int i = 0; i < n; i++) cout << arr[i] << ' '; cout << endl; } template <typename T> void ShowArray(T * arr[], int n) { using namespace std; cout << "template B\n"; for (int i = 0; i < n; i++) cout << *arr[i] << ' '; cout << endl; }
代码实现:
#include <iostream>
template <typename T>
T SumArray(T arr[], int n);
template <typename T>
T SumArray(T * arr[], int n);
struct debts
{
char name[50];
double amount;
};
int main()
{
using namespace std;
int things[6] = {13, 31, 103, 301, 310, 130};
struct debts mr_E[3] =
{
{"Ima Wolfe", 2400.0},
{"Ura Foxe", 1300.0},
{"Iby Stout", 1800.0}
};
double * pd[3];
for (int i = 0; i < 3; i++)
pd[i] = &mr_E[i].amount;
cout << "sum of things : " << SumArray(things, 6) << endl;
cout << "sum of debts :" << SumArray(pd, 3) << endl;;
return 0;
}
template <typename T>
T SumArray(T arr[], int n)
{
T sum = 0;
for(int i =0; i < n; i++)
{
sum = sum + arr[i];
}
return sum;
}
template <typename T>
T SumArray(T * arr[], int n)
{
T sum = 0;
for(int i =0; i < n; i++)
{
sum = sum + *arr[i];
}
return sum;
}
第九章课后习题答案
复习题
1. 对于下面的情况,应使用哪种存储方案?
-
a. homer是函数的形参。
-
b. secret变量由两个文件共享。
-
c. topsecret变量由一个文件中的所有函数共享,但对于其他文件来说是隐蔽的。
-
d. beencalled记录包含它的函数被调用的次数
a. home将自动成为自动变量。
b. secret在一个文件应该定义为一个外部变量,在第二个文件用extern声明。
c. 在topsecret前面添加关键字static,将topsecret定义为一个有内部链接的静态变量。或者将其在一个未命名的的名称空间中进行定义。
d. 在beencalled前面添加关键字static,将其定义为一个本地静态变量。
2.using声明和using编译指令有何区别?
using声明使得名称空间中的单个名称可用,其作用域与using所在的声明区域相同。using编译指令使名称空间中的所有名称可用。使用using编译指令时,就像在一个包含using声明和名称空间本身的最小声明区域中声明了这些名称一样。
3.重新编写下面的代码,使其不使用using声明和using编译指令。
#include <iostream> using namespace std; int main() { double x; cout << "Enter value: "; while (!(cin >> x)) { cout << "Bad input. Please enter a number: "; cin.clear(); while (cin.get() != '\n') continue; } cout << "Value = " << x << endl; return 0; }
不使用using声明和using编译指令:
#include <iostream>
int main()
{
double x;
std::cout << "Enter value: ";
while (!(std::cin >> x))
{
std::cout << "Bad input. Please enter a number: ";
std::cin.clear();
while (std::cin.get() != '\n')
continue;
}
std::cout << "Value = " << x << std::endl;
return 0;
}
4.重新编写下面的代码,使之使用using声明,而不是using编译指令。
#include <iostream> using namespace std; int main() { double x; cout << "Enter value: "; while (!(cin >> x)) { cout << "Bad input. Please enter a number: "; cin.clear(); while (cin.get() != '\n') continue; } cout << "Value = " << x << endl; return 0; }
使用using声明:
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
int main()
{
double x;
cout << "Enter value: ";
while (!(cin >> x))
{
cout << "Bad input. Please enter a number: ";
cin.clear();
while (cin.get() != '\n')
continue;
}
cout << "Value = " << x << endl;
return 0;
}
5.在一个文件中调用average(3,6)函数时,它返回两个int参数平均值,在同一个程序的另一个文件中调用时,它返回两个int参数的double平均值。应如何实现?
在每个文件中使用静态函数定义。或者每个文件都在未命名空间中定义一个合适的average函数。
6.下面的程序由两个文件组成,该程序显示什么内容?
//file1.cpp #include <iostream> using namespace std; void other(); void another(); int x = 10; int y; int main() { cout << x << endl; { int x = 4; cout << x << endl; cout << y << endl; } other(); another(); return 0; } void other() { int y = 1; cout << "Other: " << x << ", " << y << endl; }
//file2.cpp #include <iostream> using namespace std; extern int x; namespace { int y = -4; } void another() { cout << "another() " << x << ", " << y << endl; }
10
4
0
Other:: 10, 1
another() 10, -4
7.下面的代码将显示什么内容?
#include <iostream> using namespace std; void other(); namespace n1 { int x = 1; } namespace n2 { int x = 2; } int main() { using namespace n1; cout << x << endl; { int x = 4; cout << x << ", " << n1::x << ", " << n2::x << endl; } using n2::x; cout << x << endl; other(); return 0; } void other() { using namespace n2; cout << x << endl; { int x = 4; cout << x << ", " << n1::x << ", " << n2::x << endl; } using n2::x; cout << x << endl; }
1
4, 1, 2
2
2
4, 1, 2
2
编程题
1.根据这个头文件:
// golf.h -- for pe9-1.cpp const int Len = 40; struct golf { char fullname(Len); int handicap; }; // non-interactive version: // function sets golf structure to provided name, handicap // using values passed as arguments to the function void setgolf(golf & g, const char * name, int hc); // interactive version: // function solicits name and handicap from uaer // and sets the members of g to the valus entered // returns 1 if name is entered, 0 if name is empty string int setgolf(golf & g); // function resets handicap to new value void handicap(golf & g, int hc); // function displays contents of golf structure void showgolf(const golf &g);
注意到setgolf()被重载,可以这样使用其第一个版本:
golf ann; setgolf(ann, "Ann Birdfree", 24);
上述函数调用提供了存储在ann结构中的信息。可以这样使用其第二个版本:
golf andy; setgolf(andy);
上述函数将提示用户输入姓名和等级,并将它们存储在andy结构中。这个函数可以(但是不一定必须)在内部使用第一个版本。
根据这个头文件,创建一个多文件程序。其中的一个文件名为golf.cpp,它提供了与头文件中的原型匹配的函数定义;另一个文件应包含main(),并演示原型化函数的所有特性。例如,包含一个让用户输入的循环,并使用输入的数据来填充一个由golf结构组成的数组,数组被填满或用户将高尔夫选手的姓名设置为空字符串时,循环将结束。main()函数只使用头文件中原型化的函数来访问golf结构。
golf.cpp:
#include "golf.h"
#include <iostream>
using namespace std;
void setgolf(golf &g, const char *name, int hc)
{
strcpy(g.fullname, name);
g.handicap = hc;
}
int setgolf(golf &g)
{
cout << "please enter fullname : ";
cin.getline(g.fullname, Len);
if (strlen(g.fullname) == 0)
return 0;
else
{
cout << "please enter handicap : ";
cin >> g.handicap;
cin.get();
return 1;
}
}
void handicap(golf &g, int hc)
{
g.handicap = hc;
}
void showgolf(golf &g)
{
cout << "fullname : " << g.fullname << ", handicap : " << g.handicap << endl;
}
main.cpp:
#include "golf.h"
#include <iostream>
using namespace std;
int main()
{
golf ann, andy, arrGolf[3];
setgolf(ann, "Ann Birdfree", 24);
showgolf(ann);
if (setgolf(andy) == 1)
showgolf(andy);
handicap(andy, 20);
showgolf(andy);
int i = 0;
while (i < 3 && setgolf(arrGolf[i]))
{
showgolf(arrGolf[i]);
i++;
if(i<3)
cout << "next one: " << endl;
}
return 0;
}
2.修改程序清单9.9:
//Listing 9.9 static.cpp // static.cpp -- using a static local variable #include <iostream> // constants const int ArSize = 10; // function prototype˜ void strcount(const char *str); int main() { using namespace std; char input[ArSize]; char next; cout << "Enter a line:\n"; cin.get(input, ArSize); while (cin) { cin.get(next); while (next != '\n') // string didn't fit! cin.get(next); // dispose of remainder strcount(input); cout << "Enter next line (empty line to quit):\n"; cin.get(input, ArSize); } cout << "Bye\n"; return 0; } void strcount(const char *str) { using namespace std; static int total = 0; int count = 0; // static local variable // automatic local variable cout << "\"" << str << "\" contains "; while (*str++) // go to end of string count++; total += count; cout << count << " characters\n"; cout << total << " characters total\n"; }
用string对象代替字符数组。这样,该程序将不再需要检查输入的字符串是否过长,同时可以将输入字符串同字符串“”进行比较,以判断是否为空行。
#include <iostream>
#include <string>
void strcount(const std::string &str);
int main()
{
using namespace std;
string input;
cout << "Enter a line:\n";
getline(cin, input);
while (input.size())
{
strcount(input);
cout << "Enter next line (empty line to quit):\n";
getline(cin, input);
}
cout << "Bye\n";
return 0;
}
void strcount(const std::string &str)
{
using namespace std;
static int total = 0;
int count = str.size();
cout << "\"" << str << "\" contains ";
total += count;
cout << count << " characters\n";
cout << total << " characters total\n";
}
3.下面是一个结构声明:
struct chaff { char dross[20]; int slag; };
编写一个程序,使用定位new运算符将一个包含两个这种结构的数组放在一个缓冲区中。然后,给结构的成员赋值(对于char数组,使用函数strcpy()),并使用一个循环来显示内容。一种方法是像程序清单9.10那样将一个静态数组用作缓冲区;另一种方法是使用常规new运算符来分配缓冲。
#include <iostream>
using namespace std;
const int LEN = 512;
const int N = 3;
char buff[LEN];
struct chaff
{
char dross[20];
int slag;
};
int main()
{
chaff *cf1 = new chaff[N];
chaff *cf2 = new (buff) chaff[N];
string temp;
for (int i = 0; i < N; i++)
{
cout << "Please enter dross of #" << i + 1 << " chaff :";
cin.getline(cf1[i].dross, 20);
strcpy(cf2[i].dross, cf1[i].dross);
cout << "enter slag :";
cin >> cf1[i].slag;
cf2[i].slag = cf1[i].slag;
cin.ignore();
}
for (int i = 0; i < N; i++)
{
cout << "#" << i + 1 << " chaff:" << endl;
cout << "cf1[" << i << "].dross : " << cf1[i].dross << ", slag :"
<< "cf1[" << i << "].slag : " << cf1[i].slag << endl;
cout << "cf2[" << i << "].dross : " << cf2[i].dross << ", slag :"
<< "cf2[" << i << "].slag : " << cf2[i].slag << endl;
}
return 0;
}
4。请基于下面这个名称空间编写一个由3个文件组成的程序:
namespace SALES
{
const int QUARTERS = 4;
struct Sales
{
double sales [QUARTERS];
double average;
double max;
double min;
};
// copies the lesser of 4 or n items from the array ar
// to the sales member of s and computes and stores the
// average, maximum, and minimum values of the entered items;
// remaining elements of sales ,if any, set to 0
void setSales(Sales & s,const double ar[],int n);
// gathers sales for 4 quarters interactively,stores them
// in the sales member of s and computes and stores the
// average,maximum,and minimum values
void setSales (Sales & s);
// display all information in structure s
void showSales(const Sales & s);
}
第一个文件是一个头文件,其中包含名称空间:第二个文件是一个源代码文件,它对这个名称空间进行扩展,以提供这三个函数的定义;第三个文件声明两个Sales对象,并使用setSales()的交互式版本为一个结构提供值,然后使用setSales()的非交互式版本为另一个结构提供值。另外它还使用showSales()来显示这两个结构的内容。
1.sales.h
//sales.h-----头文件
namespace SALES
{
const int QUARTERS = 4;
struct Sales
{
double sales [QUARTERS];
double average;
double max;
double min;
};
void setSales(Sales & s,const double ar[],int n);
void setSales (Sales & s);
void showSales(const Sales & s);
}
2.sales.cpp
//sales.cpp-----源代码文件
#include "sales.h"
using namespace std;
namespace SALES
{
void setSales(Sales &s, const double ar[], int n)
{
double min = 0, max = 0, sum = 0;
s.min = s.max = ar[0];
for (int i = 0; i < n; i++)
{
s.sales[i] = ar[i];
sum += ar[i];
if (ar[i] > max)
{
max = ar[i];
}
if (ar[i] < min)
{
min = ar[i];
}
}
s.average = sum / n;
}
void setSales(Sales &s)
{
cout << "Please enter 4 quarters for sales:" << endl;
cout << "the 1 quarter :";
cin >> s.sales[0];
s.min = s.max = s.sales[0];
for (int i = 1; i < 4; i++)
{
cout << "the " << i << " quarter :";
cin >> s.sales[i];
if (s.max < s.sales[i])
{
s.max = s.sales[i];
}
if (s.min > s.sales[i])
{
s.min = s.sales[i];
}
}
s.average = (s.sales[0] + s.sales[1] + s.sales[2] + s.sales[3]) / 4;
}
void showSales(const Sales &s)
{
cout << "Display all information in sales : " << endl;
cout << "The 4 quarters are $" << s.sales[0] << ", $" << s.sales[1] << ", $" << s.sales[2] << ", $" << s.sales[3] << endl;
cout << "The average income is $" << s.average << endl;
cout << "The maximum income is $" << s.max << endl;
cout << "The minimum income is $" << s.min << endl;
}
}
3.main.cpp
#include "sales.h"
#include <iostream>
using namespace SALES;
int main()
{
double arr[4] = {3.4, 5.6, 2.5, 6.1};
Sales s1, s2;
setSales(s1, arr, 4);
showSales(s1);
setSales(s2);
showSales(s2);
return 0;
}
1. iostream文件在C++ I/O中扮演何种角色?
iostream文件定义了用于管理输入和输出的类、常量和操作符,这些对象用于I/O的流和缓冲区。该文件还创建了一些用于处理标准输入输出流的标准对象(如cin、cout、cerr和clog以及对应的宽字符对象)。
2. 为什么键入数字(如121)作为输入要求程序进行转换?
键盘输入会生成一系列字符,输入121将会生成3个字符,每个字符都由一个字节的二进制码表示。要将这个值存储为int
类型,则必须将这3个字符转换为121值的二进制表示。
3. 标准输出与标准错误之间有什么区别?
默认情况下两者都将输出发给标准输出设备(通常为显示器)。然而,如果要求操作系统操作系统将输出重定向到文件,则标准输出将与文件相连,但标准错误仍与显示器相连。
4. 为什么在不为每个类型提供明确指示的情况下,cout仍能够显示不同的C++类型?
ostream
类为每种C++基本类型定义了一个operator <<()
函数的版本。编译器将类似cout << spot
的表达式解释为cout.operator<<(spot)
,这样,它便能够将该方法调用与具有相同参数类型的函数原型匹配。
5. 输出方法的定义的哪一特征让您能够拼接输出?
返回ostream &
类型的输出方法能够拼接输出。通过一个对象调用方法时,将返回该对象。然后,返回对象将可以调用序列中的下一个方法
6. 编写一个程序,要求用户输入一个整数,然后以十进制、八进制和十六进制显示该整数。在宽度为15个字符的字段中显示每种形式,并将它们显示在同一行上,同时使用C++数基前缀。
#include <iomanip>
#include <iostream>
int main() {
using namespace std;
cout << "Enter an interger: ";
int n;
cin >> n;
cout << setw(15) << "base ten" << setw(15) << "base sixteen" << setw(15)
<< "base eight"
<< "\n";
cout.setf(ios::showbase);
cout << setw(15) << n << hex << setw(15) << n << oct << setw(15) << n << "\n";
return 0;
}
7. 编写一个程序,请求用户输入下面的信息,并按下面的格式显示它们:
Enter your name: Billy Gruff Enter your hourly wages: 12 Enter number of hours worked: 7.5 First format: Billy Gruff: $ 12.00: 7.5 Second format: Billy Gruff : $12.00 :7.5
main.cpp:
#include <iomanip>
#include <iostream>
int main() {
using namespace std;
char name[20];
float hourly;
float hours;
cout << "Enter your name: ";
cin.get(name, 20).get();
cout << "Enter your hourly wages: ";
cin >> hourly;
cout << "Enter number of hours worked: ";
cin >> hours;
cout.setf(ios::showpoint);
cout.setf(ios::fixed, ios::floatfield);
cout.setf(ios::right, ios::adjustfield);
// or cout << showpoint << fixed << right;
cout << "First format:\n";
cout << setw(30) << name << ": $" << setprecision(2) << setw(10) << hourly
<< ":" << setprecision(1) << setw(5) << hours << "\n";
cout << "Second format:\n";
cout.setf(ios::left, ios::adjustfield);
cout << setw(30) << name << ": $" << setprecision(2) << setw(10) << hourly
<< ":" << setprecision(1) << setw(5) << hours << "\n";
return 0;
}
8. 对于下面的程序:
//rq17-8.cpp #include <iostream> int main() { using namespace std; char ch; int ct1 = 0; cin >> ch; while (ch != 'q') { ct1++; cin >> ch; } int ct2 = 0; cin.get(ch); while (ch != 'q') { ct2++; cin.get(ch); } cout << "ct1 = " << ct1 << "; ct2 = " << ct2 << "\n"; return 0; }
如果输入如下,该程序将打印什么内容?
I see a q<Enter> I see a q<Enter>
其中,表示按回车键。
使用cin >> ch;
会自动忽略空格和换行符,因此ct1
的值应为5。而cin.get(ch);
不忽略空格和换行符,且第一次输入的回车键,也会被cin.get(ch);
捕捉到,因此ct2
的值应为9。打印内容如下:
ct1 = 5; ct2 = 9
9. 下面的两条语句都读取并丢弃行尾之前的所有字符(包括行尾)。这两条语句的行为在哪方面不同?
while (cin.get() != '\n') continue; cin.ignore(80, '\n');
如果输入超过80个字符,且这80个字符中没有出现'\n'
,则ignore()
会将前80个字符都会抛弃掉,然后再开始执行后面的语句。也就是说当输入超过80个字符,且这80个字符中没有出现'\n'
,cin.ignore(80, '\n');
读取并丢弃行尾之前的所有字符(包括行尾)的作用可能会不符合预期。而第一条语句没有该限制。【注:可以将第二个语句中80改为numeric_limits<streamsize>::max()
来解除该限制】