第三章????? 函數(shù)
?
3-1 C++中的函數(shù)是什么?什么叫主調(diào)函數(shù),什么叫被調(diào)函數(shù),二者之間有什么關(guān)系?如何調(diào)用一個函數(shù)?
解:
一個較為復雜的系統(tǒng)往往需要劃分為若干子系統(tǒng),高級語言中的子程序就是用來實現(xiàn)這種模塊劃分的。C和C++語言中的子程序就體現(xiàn)為函數(shù)。調(diào)用其它函數(shù)的函數(shù)被稱為主調(diào)函數(shù),被其它函數(shù)調(diào)用的函數(shù)稱為被調(diào)函數(shù)。一個函數(shù)很可能既調(diào)用別的函數(shù)又被另外的函數(shù)調(diào)用,這樣它可能在某一個調(diào)用與被調(diào)用關(guān)系中充當主調(diào)函數(shù),而在另一個調(diào)用與被調(diào)用關(guān)系中充當被調(diào)函數(shù)。
調(diào)用函數(shù)之前先要聲明函數(shù)原型。按如下形式聲明:
類型標識符 被調(diào)函數(shù)名 (含類型說明的形參表);
聲明了函數(shù)原型之后,便可以按如下形式調(diào)用子函數(shù):
函數(shù)名(實參列表)
?
3-2 觀察下面程序的運行輸出,與你設(shè)想的有何不同?仔細體會引用的用法。
?
源程序:
#include <iostream.h>
int main()
{
int intOne;
int &rSomeRef = intOne;
intOne = 5;
cout << "intOne:\t\t" << intOne << endl;
cout << "rSomeRef:\t" << rSomeRef << endl;
int intTwo = 8;
rSomeRef = intTwo; // not what you think!
cout << "\nintOne:\t\t" << intOne << endl;
cout << "intTwo:\t\t" << intTwo << endl;
cout << "rSomeRef:\t" << rSomeRef << endl;
return 0;
}
程序運行輸出:
intOne: 5
rSomeRef: 5
intOne: 8
intTwo: 8
rSomeRef: 8
3-3 比較值調(diào)用和引用調(diào)用的相同點與不同點。
?
解:
值調(diào)用是指當發(fā)生函數(shù)調(diào)用時,給形參分配內(nèi)存空間,并用實參來初始化形參(直接將實參的值傳遞給形參)。這一過程是參數(shù)值的單向傳遞過程,一旦形參獲得了值便與實參脫離關(guān)系,此后無論形參發(fā)生了怎樣的改變,都不會影響到實參。
引用調(diào)用將引用作為形參,在執(zhí)行主調(diào)函數(shù)中的調(diào)用語句時,系統(tǒng)自動用實參來初始化形參。這樣形參就成為實參的一個別名,對形參的任何操作也就直接作用于實參。
?
3-4 什么叫內(nèi)聯(lián)函數(shù)?它有哪些特點?
?
解:
定義時使用關(guān)鍵字 inline的函數(shù)叫做內(nèi)聯(lián)函數(shù);
編譯器在編譯時在調(diào)用處用函數(shù)體進行替換,節(jié)省了參數(shù)傳遞、控制轉(zhuǎn)移等開銷;
內(nèi)聯(lián)函數(shù)體內(nèi)不能有循環(huán)語句和switch語句;
內(nèi)聯(lián)函數(shù)的定義必須出現(xiàn)在內(nèi)聯(lián)函數(shù)第一次被調(diào)用之前;
對內(nèi)聯(lián)函數(shù)不能進行異常接口聲明;
?
3-5 函數(shù)原型中的參數(shù)名與函數(shù)定義中的參數(shù)名以及函數(shù)調(diào)用中的參數(shù)名必須一致嗎?
?
解:
不必一致,所有的參數(shù)是根據(jù)位置和類型而不是名字來區(qū)分的。
3-6 重載函數(shù)時通過什么來區(qū)分?
?
解:
重載的函數(shù)的函數(shù)名是相同的,但它們的參數(shù)的個數(shù)和數(shù)據(jù)類型不同,編譯器根據(jù)實參和形參的類型及個數(shù)的最佳匹配,自動確定調(diào)用哪一個函數(shù)。
3-7 編寫函數(shù),參數(shù)為兩個unsigned short int型數(shù),返回值為第一個參數(shù)除以第二個參數(shù)的結(jié)果,數(shù)據(jù)類型為short
int;如果第二個參數(shù)為0,則返回值為-1。在主程序中實現(xiàn)輸入輸出。
?
解:
源程序:
#include <iostream.h>
short int Divider(unsigned short int a, unsigned short int b)
{
if (b == 0)
return -1;
else
return a/b;
}
typedef unsigned short int USHORT;
typedef unsigned long int ULONG;
int main()
{
USHORT one, two;
short int answer;
cout << "Enter two numbers.\n Number one: ";
cin >> one;
cout << "Number two: ";
cin >> two;
answer = Divider(one, two);
if (answer > -1)
cout << "Answer: " << answer;
else
cout << "Error, can't divide by zero!";
return 0;
}
程序運行輸出:
Enter two numbers.
Number one:8
Number two:2
Answer: 4
?
3-8 編寫函數(shù)把華氏溫度轉(zhuǎn)換為攝氏溫度,公式為:C = (F - 32) * 5/9; 在主程序中提示用戶輸入一個華氏溫度,轉(zhuǎn)化后輸出相應(yīng)的攝氏溫度。
?
解:
源程序見"實驗指導"部分實驗三
?
3-9 編寫函數(shù)判斷一個數(shù)是否是質(zhì)數(shù),在主程序中實現(xiàn)輸入、輸出。
?
解:
#include <iostream.h>
#include <math.h>
int prime(int i); //判一個數(shù)是否是質(zhì)數(shù)的函數(shù)
void main()
{
int i;
cout << "請輸入一個整數(shù):";
cin >> i;
if (prime(i))
cout << i << "是質(zhì)數(shù)." << endl;
else
cout << i << "不是質(zhì)數(shù)." << endl;
}
int prime(int i)
{
int j,k,flag;
flag = 1;
k = sqrt(i);
for (j = 2; j <= k; j++)
{
if(i%j == 0)
{
flag = 0;
break;
}
}
if (flag)
return 1;
else
return 0;
}
程序運行輸出:
請輸入一個整數(shù):1151
1151是質(zhì)數(shù).
3-10 編寫函數(shù)求兩個整數(shù)的最大公約數(shù)和最小公倍數(shù)。
?
解:
源程序:
#include <iostream.h>
#include <math.h>
int fn1(int i,int j); //求最大公約數(shù)的函數(shù)
void main()
{
int i,j,x,y;
cout << "請輸入一個正整數(shù):";
cin >> i ;
cout << "請輸入另一個正整數(shù):";
cin >> j ;
?
x = fn1(i,j);
y = i * j / x;
cout << i << "和" << j << "的最大公約數(shù)是:" << x << endl;
cout << i << "和" << j << "的最小公倍數(shù)是:" << y << endl;
}
int fn1(int i, int j)
{
int temp;
if (i < j)
{
temp = i;
i = j;
j = i;
}
while(j != 0)
{
temp = i % j;
i = j;
j = temp;
}
return i;
}
程序運行輸出:
請輸入一個正整數(shù):120
請輸入另一個正整數(shù):72
120和72的最大公約數(shù)是:24
120和72的最小公倍數(shù)是:360
?
3-11 什么叫作嵌套調(diào)用?什么叫作遞歸調(diào)用?
?
解:
函數(shù)允許嵌套調(diào)用,如果函數(shù)1調(diào)用了函數(shù)2,函數(shù)2再調(diào)用函數(shù)3,便形成了函數(shù)的嵌套調(diào)用。
函數(shù)可以直接或間接地調(diào)用自身,稱為遞歸調(diào)用。
?
3-12 在主程序中提示輸入整數(shù)n,編寫函數(shù)用遞歸的方法求1 + 2 + … + n的值。
?
解:
#include <iostream.h>
#include <math.h>
int fn1(int i);
void main()
{
int i;
cout << "請輸入一個正整數(shù):";
cin >> i ;
?
cout << "從1累加到" <<i << "的和為:" << fn1(i) << endl;
}
int fn1(int i)
{
if (i == 1)
return 1;
else
return i + fn1(i -1);
}
程序運行輸出:
請輸入一個正整數(shù):100
從1累加到100的和為:5050
?
3-13 編寫遞歸函數(shù)GetPower(int x, int y)計算x的y次冪, 在主程序中實現(xiàn)輸入輸出。
?
解:
源程序:
#include <iostream.h>
long GetPower(int x, int y);
int main()
{
int number, power;
long answer;
cout << "Enter a number: ";
cin >> number;
cout << "To what power? ";
cin >> power;
answer = GetPower(number,power);
cout << number << " to the " << power << "th power is " <<answer << endl;
return 0;
}
long GetPower(int x, int y)
{
if(y == 1)
return x;
else
return (x * GetPower(x,y-1));
}
程序運行輸出:
Enter a number: 3
To what power? 4
3 to the 4th power is 81
?
3-14 用遞歸的方法編寫函數(shù)求Fibonacci 級數(shù),公式為fib(n) = fib(n-1) + fib(n-2),n>2;
fib(1) = fib(2) = 1;觀察遞歸調(diào)用的過程。
?
解:
源程序見"實驗指導"部分實驗三
?
3-15 用遞歸的方法編寫函數(shù)求n階勒讓德多項式的值,在主程序中實現(xiàn)輸入、輸出;
?
解:
#include <iostream.h>
float p(int n, int x);
void main()
{
int n,x;
cout << "請輸入正整數(shù)n:";
cin >> n;
cout << "請輸入正整數(shù)x:";
cin >> x;
?
cout << "n = " << n << endl;
cout << "x = " << x << endl;
cout << "P" << n << "(" << x << ") = " << p(n,x) << endl;
}
float p(int n, int x)
{
if (n == 0)
return 1;
else if (n == 1)
return x;
else
return ((2*n-1)*x*p(n-1,x) - (n-1)*p(n-2,x)) /n ;
}
程序運行輸出:
請輸入正整數(shù)n:1
請輸入正整數(shù)x:2
n = 1
x = 2
P1(2) = 2
請輸入正整數(shù)n:3
請輸入正整數(shù)x:4
n = 3
x = 4
P3(4) = 154
?
3-16 使用模板函數(shù)實現(xiàn)Swap( x, y ),函數(shù)功能為交換x、y的值。
?
解:
源程序:
#include <iostream.h>
template <typename T> void swap(T &x, T &y)
{
T z;
z = x;
x = y;
y = z;
}
void main()
{
int j = 1, k = 2;
double v = 3.0, w = 4.0;
cout << "j = " <<j << " k = " << k << endl;
cout << "v = " <<v << " w = " << w << endl;
swap(j, k); //int
swap(v, w); //double
cout << "After swap:" << endl;
cout << "j = " <<j << " k = " << k << endl;
cout << "v = " <<v << " w = " << w << endl;
}
程序運行輸出:
j = 1 k = 2
v = 3.14 w = 4.35
After swap:
j = 2 k = 1
v = 4.35 w = 3.14
?
?
第 四 章 ? ? 類
?
4-1 解釋public和private的作用,公有類型成員與私有類型成員有些什么區(qū)別?
?
解:
公有類型成員用public關(guān)鍵字聲明,公有類型定義了類的外部接口;私有類型的成員用private關(guān)鍵字聲明,只允許本類的函數(shù)成員來訪問,而類外部的任何訪問都是非法的,這樣,私有的成員就整個隱蔽在類中,在類的外部根本就無法看到,實現(xiàn)了訪問權(quán)限的有效控制。
?
4-2 protected關(guān)鍵字有何作用?
?
解:
protected用來聲明保護類型的成員,保護類型的性質(zhì)和私有類型的性質(zhì)相似,其差別在于繼承和派生時派生類的成員函數(shù)可以訪問基類的保護成員。
?
4-3 構(gòu)造函數(shù)和析構(gòu)函數(shù)有什么作用?
?
解:
構(gòu)造函數(shù)的作用就是在對象被創(chuàng)建時利用特定的值構(gòu)造對象,將對象初始化為一個特定的狀態(tài),使此對象具有區(qū)別于彼對象的特征,完成的就是是一個從一般到具體的過程,構(gòu)造函數(shù)在對象創(chuàng)建的時候由系統(tǒng)自動調(diào)用。
析構(gòu)函數(shù)與構(gòu)造函數(shù)的作用幾乎正好相反,它是用來完成對象被刪除前的一些清理工作,也就是專門作掃尾工作的。一般情況下,析構(gòu)函數(shù)是在對象的生存期即將結(jié)束的時刻由系統(tǒng)自動調(diào)用的,它的調(diào)用完成之后,對象也就消失了,相應(yīng)的內(nèi)存空間也被釋放。
?
4-4 數(shù)據(jù)成員可以為公有的嗎?成員函數(shù)可以為私有的嗎?
?
解:
可以,二者都是合法的。數(shù)據(jù)成員和成員函數(shù)都可以為公有或私有的。但數(shù)據(jù)成員最好定義為私有的。
?
4-5 已知class A中有數(shù)據(jù)成員int a,如果定義了A的兩個對象A1、A2,它們各自的數(shù)據(jù)成員a的值可以不同嗎?
?
解:
可以,類的每一個對象都有自己的數(shù)據(jù)成員。
4-6 什么叫做拷貝構(gòu)造函數(shù)?拷貝構(gòu)造函數(shù)何時被調(diào)用?
?
解:
拷貝構(gòu)造函數(shù)是一種特殊的構(gòu)造函數(shù),具有一般構(gòu)造函數(shù)的所有特性,其形參是本類的對象的引用,其作用是使用一個已經(jīng)存在的對象,去初始化一個新的同類的對象。在以下三種情況下會被調(diào)用:在當用類的一個對象去初始化該類的另一個對象時;如果函數(shù)的形參是類對象,調(diào)用函數(shù)進行形參和實參結(jié)合時;如果函數(shù)的返回值是類對象,函數(shù)調(diào)用完成返回時;
?
4-7 拷貝構(gòu)造函數(shù)與賦值運算符(=)有何不同?
?
解:
賦值運算符(=)作用于一個已存在的對象;而拷貝構(gòu)造函數(shù)會創(chuàng)建一個新的對象。
?
4-8 定義一個Dog 類,包含的age、weight等屬性,以及對這些屬性操作的方法。實現(xiàn)并測試這個類。
?
解:
源程序:
#include <iostream.h>
class Dog
{
public:
Dog (int initialAge = 0, int initialWeight = 5);
~Dog();
int GetAge() { return itsAge;} // inline!
void SetAge (int age) { itsAge = age;} // inline!
int GetWeight() { return itsWeight;} // inline!
void SetWeight (int weight) { itsAge = weight;} // inline!
private:
int itsAge, itsWeight;
};
Dog::Dog(int initialAge, int initialWeight)
{
itsAge = initialAge;
itsWeight = initialWeight;
}
Dog::~Dog() //destructor, takes no action
{
}
int main()
{
Dog Jack(2,10);
cout << "Jack is a Dog who is " ;
cout << Jack.GetAge() << " years old and";
cout << Jack.GetWeight() << " pounds weight.\n";
Jack.SetAge(7);
Jack.SetWeight(20);
cout << "Now Jack is " ;
cout << Jack.GetAge() << " years old and";
cout << Jack.GetWeight() << " pounds weight.";
?
return 0;
}
程序運行輸出:
Jack is a Dog who is 2 years old and 10 pounds weight.
Now Jack is 7 years old 20 pounds weight.
?
4-9 設(shè)計并測試一個名為Rectangle的矩形類,其屬性為矩形的左下角與右上角兩個點的坐標,能計算矩形的面積。
?
解:
源程序:
#include <iostream.h>
class Rectangle
{
public:
Rectangle (int top, int left, int bottom, int right);
~Rectangle () {}
int GetTop() const { return itsTop; }
int GetLeft() const { return itsLeft; }
int GetBottom() const { return itsBottom; }
int GetRight() const { return itsRight; }
void SetTop(int top) { itsTop = top; }
void SetLeft (int left) { itsLeft = left; }
void SetBottom (int bottom) { itsBottom = bottom; }
void SetRight (int right) { itsRight = right; }
int GetArea() const;
private:
int itsTop;
int itsLeft;
int itsBottom;
int itsRight;
};
Rectangle::Rectangle(int top, int left, int bottom, int right)
{
itsTop = top;
itsLeft = left;
itsBottom = bottom;
itsRight = right;
}
int Rectangle::GetArea() const
{
int Width = itsRight-itsLeft;
int Height = itsTop - itsBottom;
return (Width * Height);
}
int main()
{
Rectangle MyRectangle (100, 20, 50, 80 );
int Area = MyRectangle.GetArea();
cout << "Area: " << Area << "\n";
return 0;
}
程序運行輸出:
Area: 3000
Upper Left X Coordinate: 20
?
4-10
設(shè)計一個用于人事管理的People(人員)類??紤]到通用性,這里只抽象出所有類型人員都具有的屬性:number(編號)、sex(性別)、birthday(出生日期)、id(身份證號)等等。其中"出生日期"定義為一個"日期"類內(nèi)嵌子對象。用成員函數(shù)實現(xiàn)對人員信息的錄入和顯示。要求包括:構(gòu)造函數(shù)和析構(gòu)函數(shù)、拷貝構(gòu)造函數(shù)、內(nèi)聯(lián)成員函數(shù)、帶缺省形參值的成員函數(shù)、聚集。
?
解:
本題用作實驗四的選做題,因此不給出答案。
?
4-11 定義一個矩形類,有長、寬兩個屬性,有成員函數(shù)計算矩形的面積
?
解:
#include <iostream.h>
class Rectangle
{
public:
Rectangle(float len, float width)
{
Length = len;
Width = width;
}
~Rectangle(){};
float GetArea() { return Length * Width; }
float GetLength() { return Length; }
float GetWidth() { return Width; }
private:
float Length;
float Width;
};
void main()
{
float length, width;
cout << "請輸入矩形的長度:";
cin >> length;
cout << "請輸入矩形的寬度:";
cin >> width;
Rectangle r(length, width);
cout << "長為" << length << "寬為" << width << "的矩形的面積為:"
<< r.GetArea () << endl;
}
程序運行輸出:
請輸入矩形的長度:5
請輸入矩形的寬度:4
長為5寬為4的矩形的面積為:20
?
?
/*4-11-2 已有點類Point定義,定義一個矩形類,有左下角,右上角兩個點,面積,周長屬性,面積,周長由左下角,右上角兩個點決定;有成員函數(shù)有(1)構(gòu)造函數(shù)(2)返回矩形的面積(3)返回周長
(提示:用類組合實現(xiàn))
?
解:
*/
#include <iostream.h>
class Point
{
?? public:
?????? ? ?Point(int xx=0,int yy=0){X=xx; Y=yy;}//構(gòu)造函數(shù)
?????? ?? Point(Point&? p);
?????? ?? int GetX() {return X;}
?????? ?? int GetY() {return Y;}
?? private:
?????? ?? int? X,Y;
};
Point::Point (Point& p)
{ X=p.X;
Y=p.Y;
//cout<<"拷貝構(gòu)造函數(shù)被調(diào)用"<<endl;
}
?
class Rectangle
{public:
Rectangle(Point xp1, Point xp2);//構(gòu)造函數(shù)
Rectangle(Rectangle &);//拷貝構(gòu)造函數(shù)
float getarea(){return area;}
float getlen(){return len;}
private:
Point p1,p2;
float area,len;
};
?
Rectangle::Rectangle(Point xp1,Point xp2):p1(xp1),p2(xp2)
{ float h=p2.GetY()-p1.GetY();
? float w=p2.GetX()-p1.GetX();
? area=h*w;
? len=2*(h+w);
}
Rectangle::Rectangle(Rectangle &Rect):p1(Rect.p1),p2(Rect.p2)
{ area=Rect.area;
? len=Rect.len;
}
void main()
{
?????? int x,y;
?????? cout << "請輸入矩形的左下角點坐標p1的x y坐標:";
?????? cin >> x>>y;? Point myp1(x,y);
?????? cout << "請輸入矩形的右上角點坐標p2的x y坐標:";
?????? cin >> x>>y;? Point myp2(x,y);
?????? Rectangle Rect1(myp1, myp2);
?????? Rectangle Rect2(Rect1);
??????
?????? cout << "第一個矩形的面積為:" << Rect1.getarea() << "? 周長為:" << Rect1.getlen()<<endl;
?????? cout << "第二個矩形的面積為:" << Rect2.getarea() << "? 周長為:" << Rect2.getlen()<<endl;
}
?
?
?
4-12 定義一個"數(shù)據(jù)類型" datatype類,能處理包含字符型、整型、浮點型三種類型的數(shù)據(jù),給出其構(gòu)造函數(shù)。
?
解:
#include <iostream.h>
class datatype{
enum{
character,
integer,
floating_point
} vartype;
union
{
char c;
int i;
float f;
};
public:
datatype(char ch) {
vartype = character;
c = ch;
}
datatype(int ii) {
vartype = integer;
i = ii;
}
datatype(float ff) {
vartype = floating_point;
f = ff;
}
void print();
};
void datatype::print() {
switch (vartype) {
case character:
cout << "字符型: " << c << endl;
break;
case integer:
cout << "整型: " << i << endl;
break;
case floating_point:
cout << "浮點型: " << f << endl;
break;
}
}
void main() {
datatype A('c'), B(12), C(1.44F);
A.print();
B.print();
C.print();
}
程序運行輸出:
字符型: c
整型: 12
浮點型: 1.44
?
4-13 定義一個Circle類,有數(shù)據(jù)成員半徑Radius,成員函數(shù)GetArea(),計算圓的面積,構(gòu)造一個Circle的對象進行測試。
?
解:
#include <iostream.h>
class Circle
{
public:
Circle(float radius){ Radius = radius;}
~Circle(){}
float GetArea() { return 3.14 * Radius * Radius; }
private:
float Radius;
};
void main()
{
float radius;
cout << "請輸入圓的半徑:";
cin >> radius;
Circle p(radius);
cout << "半徑為" << radius << "的圓的面積為:" << p.GetArea ()
<< endl;
}
程序運行輸出:
請輸入圓的半徑:5
半徑為5的圓的面積為:78.5
?
4-14 定義一個tree類,有成員ages,成員函數(shù)grow(int years)對ages加上years,age()顯示tree對象的ages的值。
?
解:
#include <iostream.h>
class Tree {
int ages;
public:
Tree(int n=0);
~Tree();
void grow(int years);
void age();
};
Tree::Tree(int n) {
ages = n;
}
Tree::~Tree() {
age();
}
void Tree::grow(int years) {
ages += years;
}
void Tree::age() {
cout << "這棵樹的年齡為" << ages << endl;
}
void main()
{
Tree t(12);
?
t.age();
t.grow(4);
}
?
程序運行輸出:
這棵樹的年齡為12
這棵樹的年齡為16