注册域名成功后怎样建设网站,wordpress建立仿站,翠竹林wordpress主题,wordpress商品比较【注#xff1a;解答全部为本人所写#xff0c;仅供同学们学习时参考使用#xff0c;请勿照搬抄袭#xff01;】
1、 1#xff09;略 2#xff09;如果main,f1,g1,g2或更多的函数之间有更为复杂的调用关系#xff0c;头文件一般按怎样的规律写呢#xff1f; 一般情况下…【注解答全部为本人所写仅供同学们学习时参考使用请勿照搬抄袭】
1、 1略 2如果main,f1,g1,g2或更多的函数之间有更为复杂的调用关系头文件一般按怎样的规律写呢 一般情况下头文件应按照以下规律编写
头文件名应与包含的函数或类名有关在头文件中应包含必要的预处理指令例如#ifndef、#define和#endif以避免重复包含应包含函数或类的声明但不包括其定义应包含其他必要的头文件以确保在使用特定函数或类时所需的所有内容都可用
3请总结出cpp文件与.h文件的关系以及头文件中存放的内容。 C中.cpp文件包含函数或类的实现而.h文件则包含函数或类的声明。头文件是一种重要的C编程工具可帮助程序员在不同的文件中共享代码。头文件中通常包含函数或类的声明、结构体的定义和宏定义。
4若main,f1,g1,g2函数中都用到常量YEARDAYS(365),和WON(1),TUE(2),WED(3),THU(4),FRI(5),STA(6),SUN(7) 如何写头文件 可以将常量定义放在单独的头文件中并在需要使用这些常量的文件中包含该头文件。这将确保在整个程序中都可以使用这些常量同时也更容易进行修改和维护。因此以下是如何编写包含常量的头文件
// constants.h
#ifndef CONSTANTS_H
#define CONSTANTS_Hconst int YEARDAYS 365;
const int WON 1;
const int TUE 2;
const int WED 3;
const int THU 4;
const int FRI 5;
const int SAT 6;
const int SUN 7;#endif2.以max函数为例实现不同参数传递方式传值/传引用不同参数常量性 以及不同的返回值类型值返回引用返回常量引用返回等情况下,max函数的 参数虚实结合和max的各种使用和它们间的异同。注意参数不同形式时哪些形式的调用是可以的哪些算重载函数哪些是完全等价的 int max(int,int); int max(const int, const int); const int max(int,int); int max(int,int); int max(int,int); int max(const int,const int); const int max(int,int); const int max(const int,const int); … Main函数中可能有如下的调用
int retValue01 max(1,2); int retValue02 max(a,b); max(a,3) 5; max(a,b)max(c,d ); 等形式。 max函数的参数虚实结合和使用方式可以有多种包括传值、传引用、常量参数、返回值类型等。以下是各种情况下max函数的声明和定义 以下是各种情况下max函数的声明和定义以及可能的调用方式和异同点的总结 传值和常量参数 int max(int a, int b); // 值返回 int max(const int a, const int b); // 常量值返回 const int max(int a, int b); // 常量值返回 这些函数接受两个int型参数并返回较大的值。它们是根据传递的参数类型和返回类型的不同而进行重载的。 对于这些函数可以用常量或变量来调用它们。对于常量值返回类型的函数不能用左值调用函数。 传引用和常量引用参数 int max(int a, int b); // 引用返回 int max(int a, int b); // 引用返回 int max(const int a, const int b); // 常量引用返回 const int max(int a, int b); // 常量引用返回 这些函数接受两个int型引用或常量引用参数并返回较大的值。它们是根据传递的参数类型和返回类型的不同而进行重载的。 对于引用返回类型的函数可以用左值调用函数。对于常量引用返回类型的函数可以用常量或变量来调用它们。 有些函数可能是重载函数有些函数可能是完全等价的。例如传递int和const int参数的max函数是重载函数而传递int和const int参数的max函数是完全等价的。 3.练习类的定义与多文件实现 类A的定义在头文件a.h中
class A { public: void Display() const { cout“The argment is NULL”endl; }
void Display(const char * str) const {coutThe argment is strendl;
}
void OtherFunc() {
}};
main函数写在mainApp.cpp文件中 int main(int argc,char * argv[]) { A aA;
if (argc1) {aA.Display(argv[1]);
} else {aA.Display();
}coutsizeof(A)endl;return 0;}
a) 查看上述程序的执行结果。理解命令行参数、对象的大小、函数重载。
程序的执行结果取决于命令行参数的数量。如果argc大于1则将argv[1]传递给A的Display函数否则将调用Display函数的无参版本。 在最后程序会打印出A对象的大小以字节为单位。函数重载是在同一作用域内定义多个具有相同名称但参数列表不同的函数。
b)现将Display函数分别改成以inline形式和纯外联实现试一试。理解内联/外联实现在编程中的注意事项。
将Display函数实现为内联函数的方式是在函数定义之前添加关键字inline。
c) 试一试在a.h中写或不写包含警戒程序是否正确执行。
在a.h文件中应该写包含警戒以确保头文件只被编译一次。如果没有包含警戒可能会导致重复定义的错误。
d)给类A增加一个整型的类变量aStaticInt和一个类方法在main函数中调用该方法。 掌握类变量的声明和定义。进一步试一试类变量是一个数组呢
在类A中添加一个静态成员变量aStaticInt和一个静态成员函数可以在类定义中声明该变量和函数但需要在实现文件中定义它们。在main函数中可以使用作用域解析运算符(::)访问静态成员变量和函数。 例如
// a.h
class A {
public:static int aStaticInt;static void StaticFunc();// 其他成员函数
};// a.cpp
#include a.h
int A::aStaticInt 0;
void A::StaticFunc() {// 实现
}// mainApp.cpp
#include a.h
int main(int argc,char * argv[])
{A::aStaticInt 10;A::StaticFunc();// 其他代码return 0;
}可以将aStaticInt定义为数组例如
static int aStaticInt[10];e)现再增加一个类B并放入b.h中
class B {
public:void Func() { coutThis is member function Func()endl;}
private:A aA;
};并在主函数中调用B中的成员函数Func.在b.h中添加B类的定义并在main函数中创建B对象并调用其成员函数
// b.h
#include a.h
class B {
public:void Func();
private:A aA;
};// mainApp.cpp
#include b.h
int main(int argc,char * argv[])
{B b;b.Func();// 其他代码return 0;
}f) 针对e),重新按c)中的要求试一试。若将Func的实现改成外联实现按c)中的要求,再试一试。 准确理解包含警戒的作用以及各cpp文件独立编译的含义。
如果将Func函数的实现定义为外联函数则需要将函数声明添加到b.h文件中并在另一个文件中实现函数。由于Func函数中包含对A类的引用因此需要包含a.h文件。此外需要确保各个cpp文件都被独立编译并在链接时进行链接。以下是相关代码示例
// b.h
#ifndef B_H
#define B_H
#include a.h
class B {
public:void Func();
private:A aA;
};
#endif // B_H// b.cpp
#include b.h
void B::Func() {// 实现
}// mainApp.cpp
#include b.h
int main(int argc,char * argv[])
{B b;b.Func();// 其他代码return 0;
}g)将e)中的B改成 class B { public: B(A aA) { pA aA; } void Func() { cout“This is member function Func()”endl; } void NewFunc() { pA-OtherFunc(); }
private: A * pA; }; 试一试让程序编译通过并执行。
将B类的构造函数中的参数类型更改为指向A对象的指针并在NewFunc函数中使用指针操作符(-)调用OtherFunc函数。
// b.h
#include a.h
class B {
public:B(A* pa) : pA(pa) {}void Func();void NewFunc();
private:A* pA;
};// b.cpp
#include b.h
void B::Func() {// 实现
}
void B::NewFunc() {pA-OtherFunc();
}// mainApp.cpp
#include a.h
#include b.h
int main(int argc,char * argv[])
{A a;B b(a);b.Func();b.NewFunc();// 其他代码return 0;
}h)将B中的NewFunc函数以外联的形式实现b.h可以怎么写 理解class A;与#include a.h的含义差别理解外联实现的好处。
在b.h文件中添加对A类的前向声明class A;然后在b.cpp文件中包含a.h文件 class A;是A类的前向声明用于告知编译器A类的存在但不包含A类的定义。 这可以减少头文件的依赖性提高编译效率。但是前向声明只能用于声明指向A类对象的指针或引用并不能使用A类的成员函数和数据成员。 #include a.h是包含A类的完整定义可以在当前文件中使用A类的所有成员函数和数据成员。 外联实现的好处在于可以将函数定义放在单独的cpp文件中使得程序模块化和可维护性更好。外联函数的声明在头文件中这样其他文件可以访问该函数但是定义在单独的cpp文件中可以避免重复定义错误。此外外联函数的实现可以放在库文件中可以在多个程序中共享使用提高代码的复用性。
4.练习将实际生活中的事物抽象成类并给出类的设计 (找出数据成员和成员函数并用C的类表示出来即可) 1笔、钢笔 2文件、目录 3打印机、显示器 4太阳、月亮
1笔、钢笔类名Pen数据成员
- inkColor (string)笔的墨水颜色
成员函数
- refill(int inkAmount)加墨水2文件、目录类名File数据成员
- fileName (string)文件名
- fileSize (int)文件大小
- fileExtension (string)文件扩展名
- filePath (string)文件路径
- createdDate (string)文件创建日期成员函数
- open()打开文件
- close()关闭文件
- rename(string newName)重命名文件
-delet(): 删除文件类名Directory数据成员
- dirName (string)目录名
- dirPath (string)目录路径
- subDirectories (vectorDirectory)子目录列表
- files (vectorFile)文件列表成员函数
- addSubDirectory(Directory subDir)添加子目录
- addFile(File file)添加文件
- removeSubDirectory(Directory subDir)移除子目录
- removeFile(File file)移除文件3打印机、显示器类名Printer数据成员
- isConnected (bool)打印机是否已连接
- inkLevel (int)墨水量
- paperLevel (int)纸张量成员函数
- print(string text)打印文本
- checkInkLevel()检查墨水量
- checkPaperLevel()检查纸张量类名Monitor数据成员
- resolution (string)分辨率
- isConnected (bool)显示器是否已连接
- brightness (int)亮度
- contrast (int)对比度成员函数
- displayImage(Image image)显示图像
- adjustBrightness(int value)调节亮度
- adjustContrast(int value)调节对比度4太阳、月亮类名Sun数据成员
- diameter (double)太阳直径
- temperature (int)太阳表面温度
- mass (double)太阳质量成员函数
- emitEnergy()辐射能量
- rotate()自转类名Moon数据成员
- diameter (double)月球直径
- distanceFromEarth (double)距离地球的距离
- mass (double)月球质量成员函数
- orbit()绕地球轨道运动
- reflectSunlight()反射阳光
- string getName(); // 获取名称
- float getRadius(); // 获取半径
- float getDistanceToEarth(); // 获取距离地球的距离
- bool isSun(); // 判断是否为太阳5练习读懂类的代码练习使用已有的类。 下面的TRandom类是用线性调和算法实现的一个伪随机数发生器,仔细阅读代码理解其含义。 线性调和算法的基本原理是对于给定的N、M和K任给一个X 不断用X((N*XM) mod K )进行迭代计算那么得到的无穷多个x值 近似于在K上的均匀分布其中N,M,K为较大的数(N最好是素数)
#include limits.h //声明INT_MAX和ULONG_MAX常量 #include windows.h //声明GetTickCount()函数,其返回从开机到现在经过的毫秒数 //#include stdlib.h //声明rand和srand函数 //#include time.h //声明time函数 class TRandom { public: //缺省使用系统时间(开机后经过的毫秒数)为种子 TRandom (long seed0) { mSeed(seed?seed: GetTickCount()); }
//也可以定义自己的种子
void Seed(long seed0) { mSeed(seed?seed: GetTickCount( )); } //取得一个随机的整数
int Integer() { return Next();} //取得一个在指定范围内的随机整数
int Integer(int min,int max) { return minNext()%(max-min1);} //取得一个随机的0到1之间的小数
double Real() {return double(Next())/double(INT_MAX);}private: //使用调和算法 void Change() {mSeed(314159265*mSeed13579)%ULONG_MAX;} //取得伪随机数发生器的随机数序列中的下一个随机整数
int Next() { int loopsmSeed%3; for (int i0;iloops;i) Change ();return int(mSeed/2); }
unsigned long mSeed; //随机数发生器的种子};
现有一个大小为54的整型数组其元素分别为0,1,2,…,53. ) 注意类中的public和private, 理解访问控制的作用
public和private是C中的访问控制关键字用于限制类的成员的访问权限。 public成员可以被类外的代码访问和调用而private成员只能被类内的成员函数访问和调用。在类的设计中将数据成员设为private可以保证其不被直接访问和修改而必须通过类的公有成员函数来完成相关的操作增强了程序的安全性和可维护性。
请利用给出的TRandom类,完成此数组的”洗牌”过程并输出洗牌后的顺序。写出相应的完整C程序。 思考用TRandom类洗牌后,54张牌的排列大约多少种可能?现实中54张可有多少种排列方法?
#include iostream
#include TRandom.hint main() {int a[54];for (int i 0; i 54; i) {a[i] i;}TRandom r;for (int i 0; i 54; i) {int j r.Integer(i, 53); // 生成i到53之间的随机整数int temp a[i];a[i] a[j];a[j] temp;}for (int i 0; i 54; i) {std::cout a[i] ;}std::cout std::endl;return 0;
}3)利用给出的TRandom使用投针法估算PI值。 投针法在半径为1的1/4圆内随机投针若落在圆内则圆内计数加1 这样若总投掷数为N次落在园内M次随着N的增大 M/N约等于PI/4,即PI约等于4*M/N.
#include iostream
#include cmath
#include TRandom.hint main() {TRandom r;int total 1000000; // 投针总次数int inside 0; // 落在圆内的次数for (int i 0; i total; i) {double x r.Real();double y r.Real();if (x*x y*y 1) {inside;}}double pi 4.0 * inside / total;std::cout Estimated pi value: pi std::endl;std::cout Error: std::abs(pi - 3.141592653589793) std::endl;return 0;
}通过投掷1000000次针估算得到的π值约为3.141748误差为0.000156。由于投针法的随机性每次运行结果可能不同但随着投掷次数的增加估算结果逐渐趋近于π的真实值。6一个骰子(dice)有6个面各面的点数分别为123456但各面之间的相对位置是固定的。 请实现Dice类其主要完成 (1) 模拟掷骰子过程Cast并返回掷得的点数 (2报告当前各面的点数。 (3) 模拟一次掷两个或多个骰子并返回得到的总点数。 实现该类时取得随机数可使用系统函数srand和rand也可使用上例中的TRandom类。
注本题算法不是很好采用了6个if条件判断原因是抛掷一次骰子所得到的点数所在面与观察者所面向的面的相对位置关系并不确定。也可以采用随机化三次分别表示骰子在空中旋转时沿x,y,z轴方向旋转的次数的方法来解决。
#include iostream
#include cstdlib
#include ctime
using namespace std;class Dice {
public:Dice() {srand(time(NULL));up 1;down 6;left 2;right 5;front 3; back 4;}// 掷一次骰子默认向上的点数为结果 int cast() {int idx rand() % 6 1; // 生成1~6的随机数up idx;down 7 - up;if (up 3) {while(1) {temp rand() % 6 1;if (temp ! up temp ! down) break;}front temp;back 7 - front;if (front 6) {left 2;right 5;}if (front 1) {left 5;right 2;}if (front 2) {left 1;right 6;}if (front 5) {left 6;right 1;}}if (up 4) {while(1) {temp rand() % 6 1;if (temp ! up temp ! down) break;}front temp;back 7 - front;if (front 1) {left 2;right 5;}if (front 6) {left 5;right 2;}if (front 2) {left 6;right 1;}if (front 5) {left 1;right 6;}}if (up 1) {while(1) {temp rand() % 6 1;if (temp ! up temp ! down) break;}front temp;back 7 - front;if (front 3) {left 2;right 5;}if (front 4) {left 5;right 2;}if (front 2) {left 4;right 3;}if (front 5) {left 3;right 4;}}if (up 6) {while(1) {temp rand() % 6 1;if (temp ! up temp ! down) break;}front temp;back 7 - front;if (front 3) {left 5;right 2;}if (front 4) {left 2;right 5;}if (front 2) {left 3;right 4;}if (front 5) {left 4;right 3;}}if (up 2) {while(1) {temp rand() % 6 1;if (temp ! up temp ! down) break;}front temp;back 7 - front;if (front 1) {left 3;right 4;}if (front 6) {left 4;right 3;}if (front 3) {left 6;right 1;}if (front 4) {left 1;right 6;}}if (up 5) {while(1) {temp rand() % 6 1;if (temp ! up temp ! down) break;}front temp;back 7 - front;if (front 6) {left 3;right 4;}if (front 1) {left 4;right 3;}if (front 3) {left 1;right 6;}if (front 4) {left 6;right 1;}}return up; }// 输出当前各面的点数void report() {cout Points: endl;cout 上面的点数为 up endl;cout 下面的点数为 down endl;cout 前面的点数为 front endl;cout 后面的点数为 back endl;cout 左面的点数为 left endl; cout 右面的点数为 right endl;cout endl;}// 掷n个骰子返回总点数int castMulti(int n) {int totalPoints 0;for (int i 0; i n; i) {totalPoints cast();}return totalPoints;}private:
// int m_points[6]; // 存储各面的点数int up;int down;int front;int back;int left;int right; int temp;
};// 测试代码
int main() {Dice d;d.report(); // 输出初始点数int point d.cast();cout Cast: point endl;int totalPoints d.castMulti(3);cout Total points: totalPoints endl;return 0;
}