面向对象程序设计—Visual C++ 课后习题
第一章 C++的基本知识:
思考题:
习题
1、下列常数中哪些是合法的?若合法,指出常数的类型,若不合法,说明原因。
+3 -0 0379 00014 0x123e e5 3e 1e-3 1.45e4.0 1.23 .3 12. ‘\t’ ‘a’‘ab’ ‘\85’ ‘\x60’ “Hello,China!” “I’m a student” 23u 5L 12.3u 12.3l 87Ul
合法常数:
+3(int)、-0(int)、0379(八进制,int)、00014(八进制,int)、0x123e(十六进制,int)、e5(科学计数法,double)、3e(错误的科学计数法,不合法)、1e-3(科学计数法,double)、1.45e4(科学计数法,double)、1.23(double)、.3(double)、12.(double)、‘\t’(char)、‘a’(char)、‘\85’(八进制转义,char)、‘\x60’(十六进制转义,char)、“Hello,China!”(字符串)、“I’m a student”(字符串)、23u(unsigned int)、5L(long)、12.3u(无效后缀,不合法)、12.3l(long double)、87Ul(unsigned long)。
不合法的常数:
- 3e: 科学计数法必须要有指数部分。
- 12.3u: 后缀u不适合用于表示浮点数。
- 87Ul": 后缀Ul不是任何已知数据类型的有效后缀。
2、在C++中,下列符号中哪些是合法的标识符?
abs3 3block a+b else Class sum abc for my_class fun(4) a-bc
合法的标识符:abs3、_else、Class、sum、a_bc、for、my_class。
不合法的标识符:3block(不能以数字作为开头)、a+b(不能使用加号作为标识符的一部分)、fun(4)(不能使用括号作为标识符的一部分)、a-bc(不能使用减号作为标识符的一部分)。
3、在C++中,下列定义变量和常量的方法中哪些是错误的,如何修改?
(1)int i,j=10,k;
(2)float i,j,int k;
(3)const int i;
(4)const k=10;
(5)#define PI=3.14159
(6)int i,j; int i;
(1) 正确。定义了三个int类型的变量i、j、k,并初始化j为10。
(2) 错误。不能同时定义不同类型的变量,应该写成float i,j; int k;。
(3) 错误。const修饰的变量必须进行初始化,应该写成const int i=0;。
(4) 错误。const修饰的变量必须进行初始化,应该写成const int k=10;。
(5) 错误。宏定义中不应该有“=”号,应该写成#define PI 3.14159。
(6) 错误。同一个作用域中不能定义同名的变量,应该修改为int i, j; 或者删除一行int i;。
4、在C++中,下列符号中,哪些表示字符,哪些表示字符串,哪些两者都不是?
‘a’ ‘ab’ ‘0x70’ abc “计算机” 45.6 “\0x54” “a” “\a” ‘\n’ “\n\\\67” ‘56.3’
‘a’ 表示字符。
‘ab’ 和 ‘0x70’ 都不是字符,也不是字符串,因为它们包含多个字符和数字。
abc 是字符串。
“计算机” 是字符串。
45.6 不是字符或字符串,它表示一个浮点数。
“\0x54” 表示一个字符串,其中包含转义字符“\0”和“\x54”,后者表示字母“T”。
“a” 表示一个字符。
“\a” 表示转义字符“\a”,在输出时会发出警报声。
‘\n’ 表示换行符。
“\n\\\67” 表示两个转义字符“\n”和“\\\67”,后者表示ASCII码为67的字符“C”。
‘56.3’ 不是字符或字符串,它表示一个浮点数,且单引号只能用来表示单个字符。最后的引号少了一个,应该是“'56.3'”。
5、在C++中,下列式子中,哪些是合法的表达式,哪些不是,为什么?
(1)4*2.5%3 (2)7%2.5*4 (3)8.2/3%2
(4)x+=y*=z+3 (5)x=y+z=4 (6)5=2+3
(7)123.4>>2 (8)123<<2 (9)123<<2.5
(10)a+++b (11)a+++++b (12)++5
(1) 合法。先计算4*2.5=10,再取余3,结果为1。
(2) 不合法。取模运算和乘法运算的优先级相同,但是%和*都是左结合的,即从左往右计算,所以应该先计算7%2=1,再计算1*4=4。但是2.5不是整数,所以这个表达式是不合法的。
(3) 合法。先计算8.2/3=2,再取余2,结果为0。
(4) 合法。先计算z+3,再把y乘以(z+3),最后把结果加到x上。
(5) 不合法。一个赋值语句不能同时给多个变量赋值。应该拆成两句赋值语句,分别给x和y+z赋值为4。
(6) 不合法。一个数字不能作为左值,即不能赋值给数字。正确的表达应该是5=2+3。
(7) 不合法。位移运算只能用于整数,而且右移运算符>>要求右操作数必须是整数,所以这个表达式不合法。
(8) 合法。左移运算可以用于整数和浮点数,这个表达式等价于123*2^2=492。
(9) 不合法。左移运算的右操作数必须是整数,所以这个表达式不合法。
(10) 合法。这个表达式相当于在求a+b之后再把a加1。
(11) 不合法。C++中不允许对数字常量进行自增运算,所以这个表达式不合法。
(12) 不合法。字符串不能被自增,所以这个表达式不合法。
在C++中,设有如下的变量说明:
int a=2,b=5,c=9;
float x=2.3,y=4.5,z=6.0;
char ch1=’a’,ch2=’b’;
加适当的括号给出6~10题中各表达式的等价形式,并求出他们的值:
6、算术运算表达式和sizeof()运算符
(1)a+c/b*10 (2)a+z/b+x (3)z+b%a*x+c
(4)sizeof(a+3.4) (5)sizeof(‘a’+’b’) (6)ch1/b+ch2
(7)++b+c (8)++x+ ++ch1 (9)x++ +ch1
7、关系表达式
(1)d=a<=b<=c (2)d=a+b>b+c!=ch1
(3)d=a==b<c (4)d=ch1>=a+ch2<=b
8、逻辑表达式
(1)a>1&&x<=2 (2)!a+b<c+4||x>4
(3)!a--&&a>b||x (4)ch1+b>ch2&&x==y
9、赋值表达式
(1)a=b+=4 (2)a+=b*=c+ch1
(3)a+=b+(a=6) (4)d=x>y+ch2
(5)x=a=y=5.4 (6)a=y=8.5
10、逗号表达式
(1)a++,b+=a,b+c (2)x=(y=b,z=b+c)
(3)a=a+2,b++,c=b+d (4)a++,--b,a>b
设有如下的变量说明:
int a=2,b=5,c=9;
float x=2.3,y=4.5,z=6.0;
char ch1=’a’,ch2=’b’;
C语言求z+b%a*x+c的计算过程
6、
(1)a+((c/b)*10) = 12
(2)a+(z/b)+x = 4.3 应该为5.5
(3)z+((b%a)*x)+c = 21 应该为17.3
(4)sizeof(float) = 4
(5)sizeof(int) = 4
(6)(ch1/b)+ch2 = 99 应该为117
(7)++b+c = 15
(8)(++x)+(++ch1) = 101 应该为101.3
(9)(++x)+ch1 = 100 应该为99.3
7、
(1)d=(a<=b)&&(b<=c) = 1
(2)d=((a+b)>(b+c))||(ch1!=(a+b)) = 0
(3)d=(a==b)&&(b<c) = 0
(4)d=((ch1>=(a+ch2))&&(a+ch2<=b)) = 1
8、
(1)(a>1)&&(x<=2) = 1
(2)(!(a+b<c+4))||(x>4) = 1
(3)((!a--)&&(a>b))||x = 0
(4)((ch1+b)>ch2)&&(x==y) = 1
9、
(1)a=(b+=4)=9
(2)a+=(b*=(c+ch1))=116
(3)a+=(b+(a=6))=18
(4)d=(x>(y+ch2))=0
(5)x=(a=(y=5.4))=5.4
(6)a=(y=8.5)=8
10、
(1)(a++,(b+=a),(b+c))=18
(2)x=(y=b,z=b+c)=10.0
(3)(a=(a+2)+(b++),(c=b+d))=16
(4)(a++,--b,(a>b))=0
14、C++中有哪几种数据类型?简述其取值范围。编程显示在你所使用的计算机中各种数据类型的字节数(用sizeof())。
C++中有基本数据类型和复合数据类型两种。
基本数据类型包括整型、浮点型、字符型、布尔型和空类型。其中,整型包括short、int、long、long long等类型,取值范围分别为-32768~32767、-2147483648~2147483647、-2147483648~2147483647、-9223372036854775808~9223372036854775807;浮点型包括float、double、long double等类型,取值范围分别为1.2E-38~3.4E38、2.2E-308~1.8E308、3.4E-4932~1.1E4932;字符型包括char类型,取值范围为-128~127或0~255;布尔型包括bool类型,取值范围为true或false;空类型包括void类型,表示无类型。
复合数据类型包括数组、结构体、共用体、枚举等类型,其取值范围与其内部的基本数据类型有关。
以下是在Windows系统下各种数据类型的字节数:
short:2字节
int:4字节
long:4字节
long long:8字节
float:4字节
double:8字节
long double:12字节
char:1字节
bool:1字节
void:无大小
15、用C++表达式描述下列命题:
(1)a小于b且b大于c
(2)a大于b或大于c
(3)a大于b且小于c
(4)a不能被b整除
(1) a < b && b > c
(2) a > b || a > c
(3) a > b && a < c
(4) a % b != 0
上机题:
2、分析下列程序的输出结果
#include <iostream>
using namespace std;
int main() {
char x, y;
int n;
x = 'a';
y = 'b';
n = x < y;
cout << n << endl;
n = y == x + 1;
cout << n << endl;
n = ((x < y) && (y == x + 1) + 5);
cout << n << endl;
}
结果:
1
1
1
3、分析下列程序的输出结果
#include <iostream>
using namespace std;
int main() {
int x, y, n;
x = y = 1;
n = --x && ++y;
cout << "n=" << n << " x=" << x << " y=" << y << endl;
n = (--x) || (++y);
cout << n << endl;
cout << "x=" << x << " y=" << y << endl;
}
结果:n=0 x=0 y=1
1
x=-1 y=1
4、分析下列程序的输出结果
#include <iostream>
using namespace std;
int main() {
int x, y;
x = 3;
y = 6;
x += 3;
y *= x;
cout << "x=" << x << " y=" << y << endl;
}
结果:
x=6 y=36
第二章 流程控制语句
1**、编写一个C++程序,要求从键盘输入两个整数,并输出它们中绝对值较大者。**
#include
#include
using namespace std;
int main(){
int num1, num2;
cout << "请输入两个整数:" << endl;
cin >> num1 >> num2;
int abs1 = abs(num1);
int abs2 = abs(num2);
if (abs1 > abs2) {
cout << "绝对值较大的数是:" << num1 << endl;
} else {
cout << "绝对值较大的数是:" << num2 << endl;
}
return 0;
}
在程序中,我们首先定义了两个整数变量num1和num2,然后通过cin语句从键盘输入这两个整数。接着,我们使用cmath库中的abs函数分别计算出num1和num2的绝对值,并将其存储在abs1和abs2变量中。最后,我们使用if语句比较abs1和abs2的大小,输出绝对值较大的数。
2**、编写一个C++程序,要求从键盘输入三个整数,并按从小到大的次序将它们输出。**
#include
using namespace std;
int main(){
int num1,num2,num3;
cout<<"请输入三个整数:"<<endl;
cin>>num1>>num2>>num3;
if(num1>num2){
int temp=num1;
num1=num2;
num2=temp;
}
if(num1>num3){
int temp=num1;
num1=num3;
num3=temp;
}
if(num2>num3){
int temp=num2;
num2=num3;
num3=temp;
}
cout<<"从小到大的次序输出为:"<<num1<<" "<<num2<<" "<<num3<<endl;
return 0;
}
在程序中,我们首先定义了三个整数变量num1、num2和num3,然后通过cin语句从键盘输入这三个整数。接着,我们使用if语句进行三次比较,将它们按从小到大的次序排列。最后,我们使用cout语句输出排列后的结果。
3**、编写一个C++程序,判断输入的年份是否为闰年。**
#include
using namespace std;
int main(){
int year;
cout<<"请输入一个年份:"<<endl;
cin>>year;
if((year%4==0&&year%100!=0)||year%400==0){
cout<<year<<"年是闰年"<<endl;
}else{
cout<<year<<"年不是闰年"<<endl;
}
return 0;
}
在程序中,我们首先定义了一个整数变量year,然后通过cin语句从键盘输入一个年份。接着,我们使用if语句判断该年份是否为闰年,如果是,则输出“年份是闰年”,否则输出“年份不是闰年”。判断闰年的方法是:能被4整除但不能被100整除的年份为闰年,或者能被400整除的年份也为闰年。
7**、编写一个C++程序,求100以内的自然数中所有奇数的和。**
#include <iostream>
using namespace std;
int main() {
int sum = 0;
for (int i =
1; i <= 100; i++) {
if (i % 2
== 1) {
sum
+= i;
}
}
cout <<
"100以内的自然数中所有奇数的和为:"
<< sum << endl;
return 0;
}
输出结果为:
100以内的自然数中所有奇数的和为:2500
8**、编写一个程序,求出1~1000之间的完全平方数。所谓完全平方数是指能够表示为另一个整数的平方的整数。要求每行输出6个数。**
以下是C++代码:
#include
#include
using namespace std;
int main() {
int count = 0; // 计数器,每行输出6个数
for (int i = 1; i <= 1000; i++) {
int root = sqrt(i); // 求平方根
if (root
root == i) { // 判断是否为完全平方数
cout << i << " ";
count++;
if (count == 6) { // 每行输出6个数
cout << endl;
count = 0;
}
}
}
return 0;
}
输出结果为:
1 4 9 16 25 36
49 64 81 100 121 144
169 196 225 256 289 324
361 400 441 484 529 576
625 676 729 784 841 900
961
9、编写一个程序,求出1~1000之间的完全数。所谓完全数是指该数恰好等于它的因子(本身除外)之和的数,比如:6=1+2+3.
#include
using namespace std;
int main(){
for(int i=1;i<=1000;i++){
int sum=0;//因子之和
for(int j=1;j<i;j++){
if(i%j==0){//判断j是否为i的因子
sum+=j;//累加因子
}
}
if(sum==i){//判断是否为完全数
cout<<i<<" ";
}
}
return 0;
}
输出结果为:6 28 496。
10**、编写一个程序,求出1~1000之间的素数。要求每行输出6个数。**
#include
using namespace std;
int main(){
int count=0;//计数器,每行输出6个数
for(int i=2;i<=1000;i++){//从2开始判断
bool flag=true;//标记是否为素数
for(int j=2;j<i;j++){
if(i%j==0){//判断是否能被整除
flag=false;
break;//如果能被整除,跳出循环
}
}
if(flag){//如果是素数
cout<<i<<" ";
count++;
if(count==6){//每行输出6个数
cout<<endl;
count=0;
}
}
}
return 0;
}
输出结果为:
2 3 5 7 11 13
17 19 23 29 31 37
41 43 47 53 59 61
67 71 73 79 83 89
97 101 103 107 109 113
127 131 137 139 149 151
157 163 167 173 179 181
191 193 197 199 211 223
227 229 233 239 241 251
257 263 269 271 277 281
293 307 311 313 317 331
337 347 349 353 359 367
373 379 383 389 397 401
409 419 421 431 433 439
443 449 457 461 463 467
479 487 491 499 503 509
521 523 541 547 557 563
569 571 577 587 593 599
601 607 613 617 619 631
641 643 647 653 659 661
673 677 683 691 701 709
719 727 733 739 743 751
757 761 769 773 787 797
809 811 821 823 827 829
839 853 857 859 863 877
881 883 887 907 911 919
929 937 941 947 953 967
971
12**、编写一个程序,求出所有的水仙花数。水仙花数是指一个三位数,其各位数字的立方和恰好等于该数本身。**
#include
using namespace std;
int main(){
for(int i=100;i<=999;i++){
int a=i/100;//百位数
int b=i%100/10;//十位数
int c=i%10;//个位数
if(i==aaa+bbb+ccc){//判断是否为水仙花数
cout<<i<<" ";
}
}
return 0;
}
输出结果为:153 370 371 407
13**、求出1~1000中能被3整除,但不能被7整除,且至少有一位数为5的所有整数。**
#include
using namespace std;
int main(){
for(int i=1;i<=1000;i++){
if(i%3==0 && i%7!=0){//判断能否被3整除,且不能被7整除
int temp=i;
while(temp>0){//判断是否至少有一位数为5
if(temp%10==5){
cout<<i<<endl;
break;
}
temp/=10;
}
}
}
return 0;
}
15**、设计一个程序,求斐波那契数列的前40项。**
#include
using namespace std;
int main(){
int a=0,b=1,c;
cout<<a<<" "<<b<<" ";
for(int i=3;i<=40;i++){
c=a+b;
cout<<c<<" ";
a=b;
b=c;
}
return 0;
}
输出结果为:0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986。
17**、数学史上有名的“百鸡”问题:鸡翁一,值钱五,鸡母一,值钱三,鸡雏一,值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?编写一程序求解该问题。**
#include
using namespace std;
int main(){
for(int i=0;i<=20;i++){//枚举鸡翁的数量
for(int j=0;j<=33;j++){//枚举鸡母的数量
int k=100-i-j;//计算鸡雏的数量
if(i5+j3+k/3==100 && k%3==0 && i+j+k==100){//判断是否符合条件
cout<<"鸡翁:"<<i<<",鸡母:"<<j<<",鸡雏:"<<k<<endl;
}
}
}
return 0;
}
输出结果为:
鸡翁:0,鸡母:25,鸡雏:75
鸡翁:4,鸡母:18,鸡雏:78
鸡翁:8,鸡母:11,鸡雏:81
鸡翁:12,鸡母:4,鸡雏:84
其中,鸡翁、鸡母、鸡雏的数量均为整数。
实验题:
2**、改错题,找出下面程序的错误。**
#include
void main(){
int i=1;
do{
i++;
cout<<i<<endl;
};
while(i=3);
cout<<”ok”<<endl;
}
3、填空题:用1、2、3、4这四个数组成四位数,编写一个程序,打印出所有可能组成的四位数,并统计出四位数的个数。程序如下,请补全程序。
#include<iostream.h>
void main(){
int a,b,c,d,sum=0,x;
for(a=1;;)
for(b=1;;)
for(c=1;;)
for(d=1; ;){
x=a*+b*+c*10+d;
cout<<” ”<<x;
sum=_____+1;
}
cout<<”\nsum=”<<sum;
}
结果:
#include
using namespace std;
int main() {
int a, b, c, d, sum = 0, x;
for (a = 1; a <= 4; a++)
for (b = 1; b <= 4; b++)
for (c = 1; c <= 4; c++)
for (d = 1; d <= 4; d++) {
if (a != b && a != c && a != d && b != c && b != d && c != d) { // 判断四个数字不重复
x = a 1000 + b 100 + c * 10 + d;
cout << " " << x;
sum = sum + 1; // 统计四位数的个数
}
}
cout << "\nsum=" << sum << endl;
return 0;
}
第3章 函数和编译预处理
1、设计一个函数,要求将其字符型的参数转化为小写字母。
#include <iostream>
using namespace std;
char toLowerCase(char c) {
if (c >= 'A' && c <= 'Z') {
return c + ('a' - 'A');
} else {
return c;
}
}
int main() {
char c = 'A';
cout << toLowerCase(c) << endl; // 输出 a
return 0;
}
2、编写一个函数,将华氏温度转换为摄氏温度。公式为C=(F-32)*5/9。
#include <iostream>
using namespace std;
double fahrenheitToCelsius(double fahrenheit) {
double celsius = (fahrenheit - 32) * 5 / 9;
return celsius;
}
int main() {
double f = 100;
double c = fahrenheitToCelsius(f);
cout << f << "°F = " << c << "°C" << endl; // 输出 100°F = 37.7778°C
return 0;
}
3、设计一个程序,输入两个整数,求出这两个整数的最大公约数和最小公倍数,要求用两个函数分别求最大公约数和最小公倍数。
5、编写一个函数trans(int n, int base)实现数制转换。第一个参数n为要转换的十进制数,第二个参数可为2、8、16、32,分别表示将n转换为二进制、八进制数、十六进制数和三十二进制数。第二个参数的默认值为8。
6、编写一个函数判断一个整数是否为素数。并在主函数中通过该函数求出所有三位数的素数,要求每行输出5个素数。
7、编写三个重载函数,分别求两个整数、实数和双进度型数中最大的数。
8、定义一个内联函数,求任一个实数的绝对值。
9、编写一个递归函数Power(int x, int y),计算x的y次幂,并在主函数中实现输入输出。
11、用递归的方法求出勒让德多项式的第n项的值。并在主函数中根据输入的x值求勒让德多项式的前20项,要求每行输出5项。
12、编程求解问题:若一头小母牛,从出生起第四个年头开始每年生一头母牛,按此规律,第n年时共有多少头母牛?试分别用递归法和递推法实现。
14、设计一个函数,求n的阶乘,其中参数n的默认值为5。
15、设计一个参数数目可变的函数,该函数求出n个数中的最大数并输出,其中n为该函数的第一个参数,表示可变参数的个数。
16、设计一个程序,定义带参数的宏MAX(A,B)和MIN(A,B),分别求出两数中的大数和小数。在主函数中输入三个数,并求出这三个数中的最大数和最小数。
17、用条件编译方法实现以下功能:
输入一行电报文字,可有两种输出方式,一种方式为原文输出,另一种方式将字母变成其下一个字母输出(如‘a’变成’b’,……,‘z’变成’a’。其他字符不变)。用#define命令来控制是否要翻译成密码,例如:
#define CHANGE 1
则输出密码,若
#define CHANGE 0
则不译成密码,按原码输出。
实验题
2**、分析以下程序的运行结果:**
#include <iostream.h>
int sum(int);
void main(){
int s;
for(int i=1;i<=10;i++)
s=sum(i);
cout<<”s=”<<s<<endl;
}
int sum(int k){
static int x=0; //A
return (x+=k);
}
结果:s=55
3**、将上题中的A行换成:**
int x=0;
则程序的输出结果有什么不同?为什么?
答:如果将上题中的 A 行替换成 int x=0;,程序的输出结果将是 10。这是因为在这种情况下,x 是一个普通的局部变量,每次调用 sum 函数时都会重新初始化为 0,所以函数每次都只会返回传入的参数 k 的值。在主函数中,调用 sum 函数 10 次,每次传入的参数 i 从 1 到 10 递增,因此程序最终输出的结果是 10。
与前面的情况相比,这里的 x 不再是静态变量,所以它的生命周期只存在于函数调用的过程中,每次函数调用结束后都会被销毁。因此,每次调用 sum 函数时,变量 x 的初始值都是 0,而不是上一次函数调用结束时的值。这也就导致了程序输出结果的不同。
4**、分析下列程序的运行结果:**
#include <iostream.h>
int Func(int,int);
void main(){
extern int x,y;
cout<<Func(x,y)<<endl;
}
int x=15, y=-5;
int Func(int a, int b){
int s;
s=a+b+x+y;
return s;
}
结果:20
5**、分析下列程序的运行结果:**
#include <iostream.h>
int add(int x=15,int y=10){
return x+y;
}
void main(){
int a=8;
cout<<add()<<’\t’;
cout<<add(a)<<’\t’;
cout<<add(a,add(a))<<’\t’;
cout<<add(a,add(a,add()))<<’\n’;
}
结果:25 18 26 41
第3章 数组
习题
1、判断下列各题是否正确。如果不正确,请说明原因。
(1)数组可以存放许多不同类型的数值。
(2)数组下标可以为float数据类型。
(3)如果初始值表中的初始化值少于数组元素个数,则其余元素自动初始化为零。
(4)初始值表中的初始值的数量可以多余数组元素个数。
(5)将某个数组元素传递给函数并修改该元素值,那么在被调用函数执行结束时仍保留修改后的值。
2、设计一个程序,输入数组int a[10]的每一个元素,并求该数组中奇数的个数和平均值以及偶数的个数和平均值。
3、设计一个程序,输入数组a[10]的每一个元素,再输入一个数x,检查a中是否有值为x的元素,若有,则输出其下标,否则,输出-1。
4、求200以内所有素数之和。
5、17人围成圈,依次编号为1~17,从第1号开始报数,报到3的倍数的人离开,一直数下去,直到最后只剩下1人。求此人的编号。
6、设计一个程序,利用插入排序算法,对具有n个元素的数组a排序(升序)。
7、设计一个函数:
void reverse(int a[], int n);
颠倒数组a的前n个元素的顺序。例如对于数组a,假设其初始值为{1,2,3,4,5,6,7,8},则经过函数调用reverse(a,5)之后,数组a变为:{5,4,3,2,1,6,7,8}.
8、设计一个函数:
void add(int a[],int b[],int n);
将数组b的前n个元素加到数组a的相应的前n个元素上。
9、设计一个函数:
bool removeFirst(float a[], int n, float x);
该函数从数组a的查找x。如果找到x,则删除找到的第一个x,该位置以后所有元素依次向前移动一位,并返回true表示删除成功。如果为找到x,则数组不变,并返回false。
10、求矩阵Amn与Bmn的和矩阵Cmn和差矩阵Dmn。
11、设计一个程序,求5*5矩阵两对角线元素之和。
12、设计一个函数:int strlen(char s[]);
求出字符串s中所包含的字符的个数,并作为函数的返回值(要求不使用库函数strlen())。
13、设计一个函数:void strcpy(char s1[], char s2[]);
实现将字符串s2拷贝给字符串s1(要求不要使用库函数strcpy())。
14、设计一个函数:void strcat(char s1[], char s2[]);
实现将字符串s2加到字符串s1的末尾(要求不使用库函数strcat())。
实验题:
2、完成下列程序,并上机验证其正确性。
该程序重新排列a[N]的元素,使相等的元素放在一起,并保持它们在数组中第一次出现的相对位置。例如:
原数组:2 4 3 5 2 3 4 5 2 3
重排后:2 2 2 4 4 3 3 3 5 5
采用的算法是:统计各不同元素出现的次数(存放在数组c中),并依次记录下这些不同的元素,用数组b[j]标识a的第j个元素是否在前面出现过。最后按各元素重复排列的次数写回到数组a中。
#include <iostream.h>
#define N 10
void main(){
int a[N],b[N],c[N], i, j, k, j;
cout<<”输入数组a中的各元素:\n”;
for(i=0;i<N;i++){
b[i]=c[i]=i;
cin>>a[i];
}
k=0;
for(i=0;i<N;i++)
if(___){
a[k]=a[i];
for(_____;j<N;j++)
if(a[j]==a[i])
b[j]=0;c[k]++;
__;
}
t=N-1;
for(i=k-1;i>=0;i--)
for(j=0;__;j++)
__;
for(i=0;i<N;i++)
cout<<a[i]<<’\t’;
cout<<’\n’;
}
3、完成下列程序,并上机验证其正确性。
该程序的功能是输入正整数num,按从小到大的次序输出它的所有的因子。所利用的算法是:i从2开始,如果num能整除i,则可以得到一大一小两个因子,将它们分别放在数组a的两端。
#define N 40
void main(){
int num, t, i, j=0, k, a[N];
cout<<”请输入一个正整数:\n”;
cin>>num;
i=2, t=num;
k=N-1;
a[0]=1, a[N-1]=num;
while(i<t){
if(__){
t=num/i;
a[++j]=i;
if(i<t)
__;
}
__;
}
cout<<”整数”<<num<<”的因子依次为:”;
for(i=0;i<=j;i++)cout<<a[i]<<’\t’;
for(i=k;i<N;i++)cout<<a[i]<<’\t’;
cout<<’\n’;
}
第一空:num%i==0;
第二空:a[--k]=t
第三空:i++
程序的主要思路是:
1. 从2开始遍历到num的平方根,如果num能够整除i,则num除以i就是另一个因子。
2. 将两个因子分别放在数组a的两端。
3. 输出数组a。
程序的正确性可以通过以下测试验证:
输入:12。输出:1 2 3 4 6 12。
输入:25。输出:1 5 25。
输入:27。输出:1 3 9 27。
输入:35。输出:1 5 7 35。
输入:50。输出:1 2 5 10 25 50。
第5章 结构体、共用体和枚举类型
1、定义一个有关时间的结构体变量(成员包括小时、分、秒),并从键盘上输入数据并输出。
2、指出下面程序中的错误,并说明原因。
struct{int x,y,z}t1,t2;
struct test{int x,y,z}t3,t4;
cin>>t1>>t2;
t3=t1;
t4=t2;
cout<<t3<<t4;
enum str{“abc”,”bcd”,”dca”}
3、定义一个描述点三维坐标(x,y,z)的结构体变量,完成点的输入和输出,并求两点之间的距离。
4、建立50名学生信息登记表(结构体数组),每个学生的数据包括学号、姓名、性别、及三门成绩。要求:
(1)从键盘输入50名学生的数据。
(2)显示每个学生三门课的平均分。
(3)显示每门课程的全班平均分。
(4)显示名为“LiMing”的学生的三门成绩。
(5)按平均成绩由高到低将学生排名次,并按名次顺序输出这些学生的所有数据。
5、定义一个描述三种颜色的枚举类型(Red,Blue,Green),输出这三种颜色的全部排列组合结果
第6章 指针和引用
1、定义指针pa和pb,使它们分别指向整型变量a和b。通过指针pa和pb完成下列操作:
(1)输入变量a和b的值。
(2)输出这两个变量的和、差、积、商(包括整数商和实数商,且要判断除数是否为0)。
(3)调整指针的指向关系,使pa总是指向值较大的变量,而pb指向较小的变量。
2、定义一个描述“商品信息”的结构类型和结构类型的变量,以及指向结构的指针类型和指针变量,通过指针变量完成结构变量的输入和输出。设结构类型含有商品编号、商品名称、计量单位、单价、生产厂家、供货日期(一个子结构,包括年、月、日)、数量等内容。
3、设某仓库共有N种商品,描述商品的结构类型如题2,试完成下列操作:
(1)统计商品的总价值。
(2)统计供货日期在某时段的商品总数和总价值。
(3)将商品按名称排序后,再按供货日期输出。
4、编写一个函数,统计一个英文句子中字母的个数,在主程序中实现输入输出。
5、编写一个函数,统计实性数组中整数(包括0)的个数和负数的个数,以及正数的平均值和负数的平均值。
6、编写一个函数int index(char s, char t),返回一个子串t在另一个字符串s中出现的次数,如果该字串不出现,则返回0。
7、编写一个函数int strcmp(const char , const char ),实现两个字符串之间的比较。
8、编写一个函数char strcpy(char *, const char),实现两个字符串的复制。
9、编写一个函数,返回一维数组中最大元素的值。函数原型为:
float max(float p[], int n);
10、编写一个函数,将参数p中的元素颠倒次序。函数原型为:
float mirror(float p[], int n)
11、定义一个二维字符串数组,输入若干个字符串,按升序排序后输出。要求设计一个通用的排序函数实现这一功能。排序函数的原型为:
void sort(char *p[], int n)
12、输入一个二维整型数组a[6][6]。用三种方法输出该二维数组中所有元素的平均值、最大元素和最小元素。每一种方法都用一个函数实现,三个函数的原型为:
void fun1(int *p, int n);
void fun2(int a[][6], int n);
void fun3(int (*p)[6], int n);
13、设计一个程序,用指向函数的指针完成下述功能:
编写两个对一维数组(int a[N])排序的函数,其中一个按升序排序,另一个按降序排序。主函数中定义一个指向函数的指针,根据需要调用上面两个函数之一,将实参排序。
16、用new运算符产生一个一维数组,输入并输出数组中的各个元素的值,然后将数组元素颠倒排列后,再次输出各元素的值。
17、试编写一个函数,将链表head2中的所有结点全部连接到链表head1的结点之后,形成一个新的链表(头结点指针仍为head1)。
18、试编写一个函数,把两个链表合并为一个链表,使得两个链表中的结点交替地在新链表中出现。若原来某个链表中具有较多的结点,则把多余的结点接在新链表的末尾。
19、建立一个无序链表,每一个结点包含:学号、姓名、年龄和C++成绩。要求编写实现如下操作的四个函数:建立链表、输出链表中各个结点的值、删除具有某个学号的结点、在某个位置插入结点、释放链表中结点所占用的动态存储空间。
实验题
2、指出下列程序的错误,说明理由并改正。
void main(){
int p1, p2;
*p1=4;
p2=new int(3);
int &i, j, &k=*p2;
i=j;
}
第9章 类及对象的封装性
习题
1、定义一个描述学生基本情况的类,数据成员包括姓名、学号、英语、数学、计算机成绩。成员函数包括设置姓名、学号和三门课的成绩、输出数据、以及求平均成绩。
2、定义一个满足如下要求的类CDate:
(1)有三个成员数据:年、月、日;
(2)有设置日期的成员函数;
(3)有用格式“月/日/年“输出日期的成员函数;
(4)有对当前日期加一天的成员函数;
3、有如下类的说明和引用,请指出错误的地方:
Class CSample{
第10章 类的成员
习题
1、使用函数重载的方法定义两个重名函数,分别求出整型数的两点间距离和实型数的两点间距离。
2、定义一个Cpoint类,用成员函数的重载实现上题的功能。并编写主函数测试。
3、使用重载的方法编写一个求整数、实数和双精度数的平方数的类。并用一个主函数进行测试。
4、定义一个描述复数的类,成员数据包括实部和虚部。成员函数包括构造函数和输出复数。并编写主函数来测试数据与成员函数的正确性。
5、设计一个类,实现求n的阶乘。并编写程序输出8的阶乘。
6、设计一个类,实现十进制到十六进制的转换。并编写主函数进行测试。
7、设计一个类,类中包括成员数据以及求两个数的最大公约数和最小公倍数的成员函数。并编写主函数进行测试。
实验题
2、编写一个实现两个数相减的类的测试程序,请写出类的定义,构成一个完整的程序,要求调用类的构造函数和析构函数时均有明确的输出信息。程序主函数如下:
void main(){
Test t(88,32);
t.print();
}
3、编写一个类Cpoint表示一个点的信息。在此基础上编写一个表示三角形的类tria,顶点为其对象成员。编写完整的程序输出三角形的面积。
4、将上题用于输出三角形面积的成员函数改为用友元函数来实现。
5、设计一个名为football的类,用于统计一个俱乐部的联赛成绩。其中使用一个静态成员数据totals来存储总分以及一个静态成员函数re_totals()返回该总分。并编写相应的测试程序。
第11章 继承
习题
1、定义一个图形类,其中有保护类型的成员数据:高度和宽度,一个公有的构造函数。由该图形类建立两个派生类:矩形类和等腰三角形类。在每个派生类中都包含一个函数Area(),分别用来计算矩形和等腰三角形的面积。
2、定义一个人员类CPeople,其属性有(保护类型):姓名、性别、年龄;从中派生出学生类CStudent,添加属性:学号、入学时间和入学成绩;从CPeople类再派生出教师类CTeacher,添加属性:职务、部门、工作时间;由CStudent类派生出研究生类CGraduate,添加属性:研究方向和导师,由CGraduate和CTeacher共同派生出在职研究生类CGradOnWork,分别定义其中的构造函数和输出函数。主函数中定义各种类的对象,并完成测试。
3、定义一个基类CAnimal,有私有整型数据成员age,并由其派生一个新类CDog,在该类的成员函数SetAge(int n)中直接给age赋值,看看会有什么问题,把age改为公有成员后,还会有问题吗?
4、定义一个形状基类CShape,在此基础上派生出矩形类CRectangle和圆类CCircle,两者都有GetArea()函数计算对象的面积。CRectangle类再派生一个正方形类Square。试编写一个完整的程序。
5、设计一个描述儿童、成人和老人的类系统,儿童分为学龄前和学龄期儿童,成人有工作,老人已经退休。提取其中的共性作为基类,并派生出满足要求的各个类及每一个类上的必要的操作。试编写一个完整的程序。
6、定义一个存折类,并派生出信用卡类,存折类可以实现开户、存款、取款和查询余额的操作,取款金额必须小于余额,信用卡类对取款操作进行修改,允许透支一定金额。模拟有10个人到银行进行存折操作,其中有2人还进行信用卡交易的过程。试编写一个完整的程序。
7、定义一个车类CVehicle作为基类,具有max_speed、weight等数据成员,Run、Stop等成员函数,由此派生出自行车类CBicyle、汽车类CMotocar。自行车类CBicycle有高度height等属性,汽车类CMotocar有座位数seat_num等属性,从CBicycle和CMotocar派生出摩托车类CMotocycle,在派生过程中,注意把CVehicle设置为虚基类。
第12章 虚函数和多态性
习题
1、编写一个程序计算三角形、正方形和圆形的面积。
分析:依题意,可以抽象出一个基类CBase,在其中说明一个虚函数,用来求面积,并利用单接口、多实现版本设计各个图形求面积的方法。
2、编写一个程序计算正方体、球体和圆柱体的表面积和体积。
分析:依题意,抽象出一个公共基类CContainer为抽象类,在其中定义求表面积和体积的纯虚函数(该抽象类本身试没有表面积和体积可言的)。抽象类中定义一个公共的数据成员radius,此数据可作为球体的半径、正方体的边长、圆柱体底面圆半径。由此抽象类派生出要描述的三个类,在这三个类中都具有求表面积和体积的重定义版本。
3、编写一个程序,先设计一个整数链表CList类,然后从此链表派生出一个整数集合类CSet,在集合类中增加一个元素个数的数据项。集合类的插入操作与链表相似,只是不插入重复元素,并且插入后,元素个数的数据成员需增值。集合类的删除操作是在链表删除操作的基础上对元素个数减1操作。而查找和显示操作是相同的。
4、编写一个程序实现图书和杂志销售管理。当输入一系列图书和杂志销售记录后,将销售记录良好(图书每月售500本以上,杂志每月2500本以上)的图书和杂志名称显示出来。
分析:依题意,设计一个基类CBase为抽象类,其中包括GetTitle()和PrintTitle()两个成员函数,另有一个纯虚函数IsGood()。由该类派生CBook和CJournal两个类,分别实现纯虚函数IsGood(),对于前者版本,如果每月图书销售量超过500,则返回true,对于后者版本,如果每月杂志销售量超过2500,则返回true。
第13章 运算符重载
习题
1、在C++中,通常将重载运算符的成员函数称为( )。
A.运算符函数 B.重载函数 C.函数重载运算符 D.以上都不对
2、下列运算符中,( )运算符在C++中不能重载。
A.?: B.+ C.- D.<=
3、下列运算符中,( )运算符在C++中不能重载。
A.&& B.[] C.:: D.new
4、下列关于运算符重载的描述中,( )是正确的。
A.运算符重载可以改变运算数的个数
B.运算符重载可以改变优先级
C.运算符重载可以改变结合性
D.运算符重载不可以改变语法结构
5、运算符重载函数是( )。
A.成员函数
B.友元函数
C.内联函数
D.带默认参数的函数
6、定义描述平面上一个点的类Point,重载“++”和“--”运算符,并区分这两种运算符的前置和后置操作,构成一个完整的程序。
7、构造一个分数类rationalNumber,该类中包括分子和分母两个成员数据,并具有下述功能:
(1)建立构造函数,它能防止分母为零,当分数不是最简形式时进行约分,并避免分母为负数。
(2)重载加法、减法、乘法以及除法运算符。
(3)重载关系运算符:>、<、==等。
8、定义一个链表类,重载下标运算符,使之返回链表中某个给定的成员。
第14章 模板
1、编写一个函数模板,它返回两个值的最小值。要求确保能正确处理字符串。
2、编写一个函数模板,它返回数值类型值的绝对值。
3、编写一个通用的数组(Array)类模板,要求包括对数组进行写数据和读数据操作。
4、编写一个通用的队列(Queue)类模板,要求包括对队列进行入队、出队和打印操作。
第15章 异常处理
习题
2、在程序中用new分配内存空间时,如果操作未成功,则用try语句触发一个字符型常数,用catch语句捕获此异常。试编写一个完整的程序实现这一功能。
3、定义一个异常类CException,它具有成员函数Reason(),用来显示异常的类型,定义函数fun()触发异常,在主函数的一个try块中调用函数fun(),在相应的catch块中捕获异常,设计一个完整的程序,并观察程序的执行流程。
第16章 输入/输出流
习题
1、选择题
(1)进行文件操作时需要包含( )文件。
A. iostream.h B. fstream.h C. stdio.h D. stdlib.h
(2)使用流操纵算子对数据进行格式输出时,应包含( )文件。
A. iostream.h; B. fstream.h; C. iomanip.h D.stdlib.h
(3)已知:int a,*pa=&a;输出指针pa十进制的地址值的方法试( )。
A. cout<<pa; B. cout<<*pa; C. cout<<&pa; D. cout<<long(pa);
(4)下列输出字符’A’的方法中,( )是错误的。
A. cout<<put(‘A’); B. cout<<’A’; C. cout.put(‘A’); D. char a=’A’;cout<<A;
(5)关于getline()函数的下列描述中,( )是错的。
A.该函数可用来从键盘上读取字符串;
B.该函数读取的字符串长度是受限制的;
C.该函数读取字符串时遇到终止符便停止;
D.该函数中所使用的终止符只能是换行符。
(6)关于read()函数的下列描述中,( )是对的。
A.该函数只能从键盘输入中获取字符串;
B.该函数所获取的字符多少是不受限制的;
C.该函数只能用于文本文件的操作中;
D.该函数只能按规定读取所指定的字符数。
(7)在ios中提供控制格式的标志位中,( )是转换为十六进制形式的标志位。
A. hex B. oct C. dec D. left
(8)控制格式输入输出的流操纵算子中,( )是设置域宽的。
A. ws B. oct C. setfill() D. setw()
(9)下列函数中,( )是对文件进行写操作的。
A. get() B. read() C. seekg() D. put()
(10)从类库的层次结构来看,fstream直接从( )类派生。
A. istream B. ostream C. iostream D. ios
2、判断题
(1)使用插入符“<<”可以输出各种类型的变量值,也可以输出指针值。
(2)预定义的插入符和提取符是可以重载的。
(3)到cerr的输出是非缓冲输出,到clog的输出是缓冲输出。
(4)记录流的当前格式化的状态标志字中每一位用于记录一种格式,这种格式是不能被设置或清除的。
(5)流操纵算子本身是一个对象,它可以直接被插入符或提取符操作。
(6)get()函数不能从流中提取终止字符,终止字符仍留在流中;getline()函数从流中提取终止字符,但终止字符被丢弃。
(7)以app方式打开文件时,当前的读指针和写指针都定位于文件尾。
(8)打开文本文件和二进制文件时,打开方式是相同的。
(9)使用关闭文件函数close()关闭一个文件时,但流对象仍存在。
(10)read()和write()函数可以读/写文本文件,也可以读写二进制文件。
3**、编程题**
(1)编写一个程序能实现复数的输入/输出与复数的加减运算,要求先输入两组复数,然后对两组复数分别进行加减运算,并输出原来两组复数及运算后复数的值。
(2)编写一个程序,从键盘输入一个字符串,判断字符串的长度,然后以字符串长度的两倍作为域宽打印出该字符串。
(3)输入一个浮点数,要求以人民币的格式形式输出该数,长度一律10位,小数点后两位,币值前有一‘¥’符号。
(4)编写程序建立输出文件,向该文件中写入信息,然后关闭文件,再打开该文件,将文件的信息读出显示在屏幕上。
(5)编一个程序拷贝文本文件,在拷贝文件过程中,将所有小写改成大写。
(6)实现一个通讯录打印程序。通讯录的记录格式为:(姓名、单位、电话、住址、宅电),要求先建立一个Person类,然后按对象读入和打印。