计算机类
公务员类
工程类
语言类
金融会计类
计算机类
医学类
研究生类
专业技术资格
职业技能资格
学历类
党建思政类
计算机等级考试(NCRE)
全国计算机应用水平考试(NIT)
计算机软件水平考试
计算机等级考试(NCRE)
全国高校计算机等级考试CCT
行业认证
信息素养
计算机等级考试二级
计算机等级考试一级
网络工程师(计算机等级考试四级)
计算机等级考试二级
数据库工程师(计算机等级考试四级)
计算机等级考试三级
信息安全工程师(计算机等级考试四级)
嵌入式系统开发工程师(计算机等级考试四级)
软件测试工程师(计算机等级考试四级)
C++语言程序设计
Python语言程序设计
WPS Office高级应用与设计
C语言程序设计
C++语言程序设计
Java语言程序设计
Visual Basic语言程序设计
Web程序设计
Access数据库程序设计
MySQL数据库程序设计
Visual FoxPro数据库程序设计
办公软件高级应用
问答题改错题 使用VC6打开考生文件夹下的工程test9_1,此工程包含一个源程序文件test9_1.cpp,但该程序运行有问题,请改正程序中的错误,使程序的输出结果如下: 4,5 20 源程序文件test9_1.cpp清单如下: #include class A { protected: int n,m; public: void set(int a,int b){m=a; n=b;} void show(){cout<
进入题库练习
问答题使用VC6打开考生文件夹proj3下的工程proj3,其中定义了一个字符串变量类StringVar。类成员的说明在程序注释中。请在//**********333**********和//**********666**********之间填写StringVar成员函数和友元函数的实现代码。在main函数中给出了一组测试数据,运行时输入:Hello Kitty此情况下程序的输出应该是:Hello KittyBorgBorg注意:只需在//**********333**********和//**********666**********之间填入所编写的若干语句,不要改动程序中的其他内容。//StringVar.h#include<iostream>#include<cstdlib>#include<cstddef>#include<cstring>using namespacestd;void writeToFile(const char*path);class StringVar{public:StringVar(int size);//构造函数,size为字符串长度(字符个数)初始值;字符串内容初始化为空串StringVar(const char a[]);//构造函数,用参数数组a的内容初始化当前对象StringVar(const StringVar& strobj);//复制构造函数~StringVar(){delete[]value;};//析构函数int length()const{return strlen(value);}//从输入流ins输入一个字符串,其中可以包括空格void input_line(istream& ins);//返回字符串首地址char*getValue()const{return value;}private:char*value;//字符串首地址int max_length;//字符串最大长度(字符个数最大值)};//将the_string通过输出流outs输出ostream& operator<<(ostream& outs,const StringVar the_string);//main.cpp#include<iostream>#include<string>#include"StringVar.h"//**********333**********//**********666**********int main(){StringVar name1(30),name2("Borg");name1.input_line(cin);StringVar name3(name2);cout<<namel<<endl:cout<<name2<<endl:cout<<name3<<endl:writeToFile(".\\");return0;}//writeToFile.cpp#include<iostream>#include<fstream>#include<sstream>#include<string>using namespace std;#include"StringVar.h"void writeToFile(const char*path){char filename[30];strcpy(filename,path);strcat(filename,"out.dat");ofstream fout(filename);istringstream is(string("Jenny Zheng"));StringVar name1(40),name2("John");name1.input_line(is);StringVar name3(name2);fout<<name1<<name2<<name3:fout.close();}
进入题库练习
问答题使用VC6打开考生文件夹下的源程序文件modi3.cpp,其中定义了用于表示学生学号的类CStudentID,但类CStudentID的定义并不完整。 运行结果为: 学生的学号为:200805 学生名为:李伟 删除学生学号为:200805 请按要求完成下列操作,将类CStudentID的定义补充完成: (1)定义class CStudentID类的私有数据成员IDvalue表示学生的学号,为long型的数据。请在注释//********1********之后添加适当的语句。 (2)完成默认构造函数CStudentID的定义,使CStudentID对象的默认值为:id=0,并把学生的学号赋给IDvalue,并输出“赋给学生的学号:”及学号。请在注释//********2********之后添加适当的语句。 (3)完成默认析构函数CStudentID的定义,使CStudentID析构时输出“删除学号:”及学号。请在注释//********3********之后添加适当的语句。 (4)完成默认构造函数CStudentlnfo的定义。对应两个默认参数:要求定义char stName[],其默认值为“no name”,定义long stID,其默认值设为0,并使它们赋值给相应的类数据成员。请在注释//********4********之后添加适当的语句。 注意:除在指定位置添加语句之外,请不要改动程序中的其他内容。#include<iostream.h>#include<string.h>class CStudentID{//********1********定义私有数据成员public: //********2********定义默认构造函数 { IDvalue=id; cout<<"学生的学号为:"<<IDvalue<<end1; } //********3********定义析构函数 { cout<<"删除学生学号为:"<<IDvalue<<end1; } }; class CStudentInfo { private: CStudentID id; char name[20];public: //********4********定义默认构造函数完成数据成员初始化 { cout<<"学生名为:"<<stName<<end1; strcpy(name,stName); } }; void main() { CStudentInfo st("李伟",200805); }
进入题库练习
问答题使用VC6打开 下的源程序文件modi3.cpp。其中定义的类并不完整,按要求完成下列操作,将类的定义补充完整。完成以下功能: (1)完成CMyClass的构造函数,请改正注释//********1********后的错误。 (2)完成func()函数定义,请改正注释//********2********后的错误。 (3)初始化CmyClass的成员变量Number3为4,请改正注释//********3********后的错误。 (4)完成func()函数,请改正注释//********4********后的错误。 输出的结果为: Number1=12 Number2=18 Number3=16 Number1=4 Number2=2 Number3=19 注意:除在指定位置添加语句之外,请不要改动程序中的其他内容。 #include <iostream.h> class CMyClass { public: //********1******** CMyClass(int i,int j) { Number1=i; Number3+=i; } void display() { cout "Number1=" Number1 endl; cout "Number2 =" Number2 endl; cout "Number3 =" Number3 endl; } void AddNum(int i) { Number3+=i; } private: int Number1; const int Number2; static int Number3; //********2******** }; //********3******** void func() { CMyClass obj(1,2); obj.Number1=4; //********4******** obj.AddNum( ); obj.display(); } void main() { CMyClass myObj (12,18); myObj.display(); func(); return; }
进入题库练习
问答题使用VC6打开考生文件夹下的工程test11_1,此工程包含一个源程序文件test11_1.cpp,但该程序运行有问题,请改正程序中的错误,使程序的输出结果如下: ch1=7 ch2=9 源程序文件test11_1.cpp清单如下: #include<iostream.h> class Sample /**************** found ***************/ char ch1,ch2 public: /************** found ***************/ friend void set(Sample s, char c1,char c2) s.ch1=c1; s.ch2=c2; void print() cout<<"ch1="<<" ch2="<<ch2<<end1; ; void main() Sample obj; /************* found ****************/ obj.set(obj,'7','9'); obj.print();
进入题库练习
问答题使用VC6打开 下的源程序文件modi1.cpp,该程序运行时有错,请改正其中的错误,使程序正常运行,并使程序输出的结果为: Max is 7 提示:max()函数实现找出两个数中的最大值,并作为函数值返回。 注意:错误的语句在//******error******的下面,修改该语句即可。 # include <iostream> using namespace std; //******error****** int max(int a,int b) { if(a<b) { int t=a; a=b; b=t; } return b; } int main () { int m=-3; int n=7; //******error****** max (-3,n); cout "Max is " m endl; return 0; }
进入题库练习
问答题使用VC6打开考生文件夹下的源程序文件modi3.cpp,其中定义的类并不完整,按要求完成下列操作,将类的定义补充完整。 (1)定义类CPlanet的保护数据成员distance和revolvePeriod,它们分别表示行星距太阳的距离和行星的公转周期。其中,distance为double型,revolvePeriod为int型。请在注释//********1********之后添加适当的语句。 (2)定义类CEarth的构造函数CEarth(double d,intr),并在其中计算地球绕太阳公转的轨道周长。假定:circumference=2*d*3.1416 。 请 在 注 释//********2********之后添加适当的语句。 (3)定义类Earth的成员display(),用于显示所有信息。包括地球距太阳的距离,地球的公转周期,以及地球绕太阳公转的轨道周长。请在注释//********3********之后添加适当的语句。 注意:增加代码,或者修改代码的位置已经用符号表示出来。请不要修改其他的程序代码。#include<iostream>using namespace std;class CPlanet{protected: //********1********public: CPlanet(double d,int r) { distance=d; revolvePeriod=r; } }; class CEarth:public CPlanet{ double circumference; public: //********2******** CEarth(double d,int r) { circumference=2*d*3.1416; ) //********3******** { cout<<"distance="<<distance<<end1; cout<<"revolution Period="<<revolvePeriod<<end1; cout<<"revolution circumference="<<circumference<<end1 } }; void main() { CEarth earth(9300000,365); earth.display(); }
进入题库练习
问答题用VC6打开下的源程序文件modi3.cpp,其中定义了多个类,但类不能达到输出要求,按照定义的输出修改函数,使得输出如下:TestClass3TestClass2TbstClass1其中定义的类并不完整,按照要求完成下列操作,将类的定义补充完整。(1)类TestClass2公共继承于TestClass1,请在注释//********1********后添加适当的语句。(2)print函数为虚函数,请在注释//********2********后添加适当的语句。(3)修改语句,使得p指定对象obj3,请在注释//********3********后添加适当的语句。(4)修改语句,利用p调用print()函数,完成输出信息,注释//********4********后添加适当的语句。注意:仅在函数指定位置添加语句,请勿改动主函数main与其他函数中的任何内容。#include<iostream>usingnamespacestd;classTestClass1{public:voidprint(){cout"TestClass1"endl;}};//********1********classTestClass2{public://********2********voidprint(){}};classTestClass3:publicTestClass2{public:voidprint(){}};intmain(){TestClass2obj2;TestClass3obj3;TestClass1*p;obj2.print();obj3.print();//********3********p=obj3;//********4********p.print();return0;}
进入题库练习
问答题请使用VC6或使用【答题】菜单打开考生文件夹proj2下的工程proj2,其中定义了vehicle类,并派生出motorcar类和bicycle类。然后以motorcar和bicyele作为基类,再派生出motorcycle类。要求将vehicle作为虚基类,避免二义性问题。请在程序中的横线处填写适当的代码并删除横线,以实现上述类定义。此程序的正确输出结果应为: 80 150 100 1 注意:只能在横线处填写适当的代码,不要改动程序中的其他内容,也不要删除或移动“//****found****”。#include<iostream.h>clasS vehicle{private: int MaxSpeed; int Weight;public://**********found********** vehicle (int maxspeed, int weight):_______ 一vehicle(){); int getMaxSpeed() { return Max—Speed;) int getWeight(){return Weight;) }; //**********found********** class bicycle:_______public vehicle { private: int Height;public: bicycle(int maxspeed,int weight,int height):vehicle (maxspeed,weight),Height(height){} int getHeight(){return Height;}; }; //**********found********** class motorcar:_______public vehicle { private: int SeatNum;public: motorcar(int maxspeed,int weight int seatnum):vehicle (maxspeed weight),SeatNum(seatnum)f) int getSeatNum(){return SeatNum;); }; //********** found********** class motorcycle :________ { public: motorcycle (int maxspeed, in weight,int height):vehicle(ma,speed,weight),bicycle(maxspeed weight,height),motorcar(maxspeed weight,1){}};,void main(){ motorcycle a(80,150,100); cout<<a.getMaxSpeed()<<endl; cout<<a.getWeight()<<endl; cout<<a.getHeight()<<endl; cout<<a.getSeatNum()<<endl; }
进入题库练习
问答题请编写一个函数unsigned short fun(unsigned short s)。其中s是一个大于10的无符号整数,若s是一个n(n≥2)位整数,函数求出s的n位数之和作为函数的返回值。 例如,s值为4315,则函数返回13。s值为13函数,则返回4。注意:部分源程序已存在文件PROC15.cpp中。 请勿修改主函数和其他函数中的任何内容,仅在函数fun()的花括号中填写若干语句。 文件PROC15.cpp的内容如下: //PROC15.cpp #include<iostream> using namespace std; unsigned short fun(unsigned short s); int main() unsigned short a; cout<<"Enter a unsigned short integer number:"; cin>>a; if(a<10) cout<<"Data error!"; else cout<<"The result: "<<fun(a)<<end1; return 0; unsigned short fun(unsigned short s) //* * * * * *
进入题库练习
问答题请使用VC6或使用【答题】菜单打开 proj1下的工程proj1,此工程包含一个源程序文件proj1.cpp。文件中将表示数组元素个数的常量Size定义为4,并用int类型对类模板进行了实例化。文件中位于每个注释“// ERROR ****found****”之后的一行语句存在错误。请改正这些错误,使程序的输出结果为: 1 2 3 4 注意:模板参数名用T。只修改注释“// ERROR *******found*******”的下一行语句,不要改动程序中的其他内容。 //proj1.cpp #include <iostream> using namespace std; //将数组元素个数Size定义为4 // ERROR *******found******* const int Size; template <typename T> class MyClass { public: MyClass (T * p) { for(int i=0;i < Size;i ++) array[i] = p[i]; } void Print(); private: T array[Size]; }; template <typename T> // ERROR *******found******* void MyClass::Print() { for(int i = 0;i <Size;i ++) cout << array[i] << "/t"; } int main() { int intArray[Size] = {1,2,3,4}; // ERROR *******found******* MyClass <double> obj (intArray); obj.Print(); cout << endl; return 0; }
进入题库练习
问答题请使用VC6或使用【答题】菜单打开 prog2下的工程prog2,此工程中包含一个程序文件main.cpp,其中有“班级”类Class和“学生”类Student的定义,还有主函数main的定义。在主函数中定义了两个“学生”对象,他们属于同一班级。程序展示,当该班级换教室后,这两个人的教室也同时得到改变。请在横线处填写适当的代码,然后删除横线,以实现上述类定义。此程序的正确输出结果应为: 改换教室前: 学号:0789 姓名:张三 班级:062113 教室:521 学号:0513 姓名:李四 班级:062113 教室:521 改换教室后: 学号:0789 姓名:张三 班级:062113 教室:311 学号:0513 姓名:李四 班级:062113 教室:311 注意:只能在横线处填写适当的代码,不要改动程序中的其他内容。 #include <iostream> using namespace std; class Class{ //“班级”类 public: Class(const char * id, const char * room) { strcpy(class_id, id); // *******found******* ______ } const char * getClassID() const {return class_id;} //返回班号 // *******found******* const char * getClassroom() const {______} //返回所在教室房号 void changeRoomTo(const char * new_room) { //改换到另一个指定房号的教室 strcpy (classroom, new_room); } private: char class_id[20]; //班号 char classroom[20]; //所在教室房号 }; class Student{ //“学生”类 char my_id[10]; //学号 char my_name[20]; //姓名 Class //所在教室 public: // **********found********** Student (const char * the_id, const char * the_name, Class strcpy (my_name, the_name); } const char * getID() const {return my_id;} const char * getName() const {return my_name;} Class getClass() const {return my_class;} }; void showStudent (Student * stu) { cout << "学号:" << stu -> getID() << " "; cout << "姓名:" << stu -> getName() << " "; cout << "班级:" << stu -> getClass().getClassID() << " "; cout << "教室:" << stu -> getClass().getClassroom() << endl; } int main() { Class cla("062113","521"); Student Zhang ("0789", "张三", cla), Li("0513", "李四", cla); cout << "改换教室前:" << endl; showStudent ( showStudent ( //062113班的教室由521改换到311 // **********found********** cout << "改换教室后:" << endl; showStudent ( showStudent ( return 0; }
进入题库练习
问答题使用VC6打开 proj3下的工程proj3,其中定义了一个字符串变量类StringVar。类成员的说明在程序注释中。请在//********333********和//********666********之间填写StringVar成员函数和友元函数的实现代码。在main函数中给出了一组测试数据,运行时输入: Hello Kitty 此情况下程序的输出应该是: Hello Kitty Borg Borg 注意:只需在//********333********和//********666********之间填入所编写的若干语句,不要改动程序中的其他内容。 //StringVar.h #include<iostream> #include<cstdlib> #include<cstddef> #include<cstring> using namespace std; void writeToFile(const char*path); class StringVar { public: StringVar(int size);//构造函数,size为字符串长度(字符个数)初始值;字符串内容初始化为空串 StringVar(const char a[]);//构造函数,用参数数组a的内容初始化当前对象 StringVar(const StringVar//复制构造函数 ~StringVar(){delete[]value;);//析构函数 int length()const{return strlen(value);} //从输入流ins输入一个字符串,其中可以包括空格 void input_line(istream //返回字符串首地址 char*getValue()const{return value;} private: char*value;//字符串首地址 int max_length;//字符串最大长度(字符个数最大值) }; //将the_string通过输出流outs输出 ostream //main.cpp #include<iostream> #include<string> #include"StringVar.h" //*********333********* //*********666********* int main() { StringVar name1(30),name2("Borg"); name1.input_line(cin); StringVar name3(name2); cout<<name1<<endl; cout<<name2<<endl; cout<<name3<<endl; writeToFile("./"); return 0; } //writeToFile.cpp #include<iostream> #include<fstream> #include<sstream> #include<string> using namespace std; #include"StringVar.h" void writeToFile(const char*path) { char filename[30]; strcpy(filename,path); strcat(filename,"out.dat"); ofstream fout(filename); istringstream is(string("Jenny Zheng")); StringVar name1(40),name2("John"); name1.input_line(is); StringVar name3(name2); fout<<name1<<name2<<name3; fout.close(); }
进入题库练习
问答题使用VC6打开考生文件夹下的源程序文件modi3.cpp。请完成以下部分,实现在屏幕上输出为: TestClass3 TestClass2 这个程序需要修改的部分,请按照以下部分实现。 (1)类TestClass0不能被实例化,请定义一个纯虚函数print,在注释∥********1********后添加适当的语句。 (2)类TestClassl私有虚继承类TestClass0,请在注释∥********2********后添加适当的语句。 (3)类TestClass2公有继承类TestClass0,请在注释∥********3********后添加适当的语句。 (4)类TestClass3公有继承类TestClass2与TestClassl,请在注释∥********4********后添加适当的语句。 注意:仅在函数指定位置添加语句,请勿改动主函数main与其他函数中的任何内容。 1 #include 2 class TestClass0 3 { 4 ∥********1******** 5 6 }; 7 ∥********2******** 8 C1ass TestClassl: 9 { 10 public: 11 void print() 12 { 13 cout<<”TestClassl”<
进入题库练习
问答题请使用VC6或使用【答题】菜单打开考生文件夹proj1下的工程proj1,其中有枚举DOGCOLOR、狗类Dog和主函数main的定义。程序中位于每个“//ERROR****found****”下的语句行有错误,请加以改正。改正后程序的输出结果应该是: There is a white dog named Hoho. There is a black dog named Haha. There is a motley dog named Hihi. 注意:只修改每个//ERROR****found****下的那一行,不要改动程序中的其他内容。 #include<iostream> using namespace std; //狗的颜色:黑、白、黄、褐、花、其他 enum DOGCOLOR{BLACK,WHITE,YELLOW,BROWN,PIEBALD,OTHER}; class Dog{//狗类 DOGCOLOR color; char name[20]; static int count; public: Dog(char name[],DOGCOLOR color){ strcpy(this->name,name); //ERROR**********found********** strcpy(this->color,color); } DOGCOLOR getColor()const{return color;} //ERROR**********found********** const char*getName()const{return*name;} const char*getColorString()const{ switch(color){ case BLACK:return"black": case WHITE:return"white": case YEULLOW:return"yellow": case BROWN:return"brown"; case PIEBALD:return"piebald"; } return"motley"; } void show()const{ cout<<"There is a"<<getColorString()<<"dog named"<<name<<'.'<<endl; } }; int main(){ //ERROR**********found********** Dog dogl("Hoho",WHITE),dos2("Haha",BLACK);dog3("Hihi",OTHER); dog1.show(); dog2.show(); dog3.show(); return 0; }
进入题库练习
问答题使用VC6打开考生文件夹proj3下的工程pmj3,其中定义了一个字符串变量类StringVar。类成员的说明在程序注释中。请在//**********333**********和//**********666**********之间填写StringVar成员函数和友元函数的实现代码。在main函数中给出了一组测试数据,运行时输入: Hello Kitty 此情况下程序的输出应该是: Hello Kitty Borg Borg 注意:只需在//**********333**********和//**********666**********之间填入所编写的若干语句,不要改动程序中的其他内容。//StringVar.h#include<iostream>#include<cstdlib>#include<cstddef>#include<cstring>using namespace std;void writeToFile(const char*path);class StringVar{public: StringVar(int size);//构造函数,size为字符串长度(字符个数)初始值;字符串内容初始化为空串 StringVar(const char a[]);//构造函数,用参数数组a的内容初始化当前对象 StringVar(const StringVar&strobj);//复制构造函数 ~StringVar(){delete[]value;};//析构函数 int length()const{return strlen(value);} //从输入流ins输入一个字符串,其中可以包括空格 void input_line(istream&ins); //返回字符串首地址 char*getValue()const{return value;}private: char*value;//字符串首地址 int max_length;//字符串最大长度(字符个数最大值)};//将the_string通过输出流outs输出ostream&operator<<(ostream&outs,const StringVar the_string);//main.cpp#include<iostream>#include<string>#include"StringVar.h"//**********333**********//**********666**********int main(){ StringVar namel(30),name2("Borg"); name1.input_line(cin); StringVar name3(name2); cout<<name1<<endl: cout<<name2<<endl: cout<<name3<<endl: writeToFile(".\\"); return 0;}//writeToFile.cpp#include<iostream>#include<fstream>#include<sstream>#include<string>using namespace std;#include"StringVar.h"void writeToFile(const char*path){ char filename[30]; strcpy(filename,path); strcat(filename,"out.dat"); ofstream fout(filename); istringstream is(string("Jenny Zheng")); StringVar namel(40),name2("John"); namel.input_line(is); StringVar name3(name2); fout<<name1<<name2<<name3: fout.close();}
进入题库练习
问答题请编写函数void swap(int *px,int *py)与void swap(int swap(a,b); cout<<a<<" "<<b<<endl; swap( cout<<a<<" "<<b<<endl;
进入题库练习
问答题使用VC6打开考生文件夹下的源程序文件modi3.cpp。此程序的运行结果为: In CDerive's display().b=1 In CDerive2’s display().b=2 其中定义的类并不完整,按要求完成下列操作,将类的定义补充完整。 (1)定义函数display()为无值型纯虚函数。请在注释∥********1********之后添加适当的语句。 (2)建立类CDerive的构造函数,请在注释∥********2********之后添加适当的语句。 (3)完成类CDerive2成员函数diaplay0的定义。请在注释∥********3********之后添加适当的语句。 (4)定义类Derivel的对象指针d1,类CDerive2的对象指针d2。其初始化值分别为1和2。请在注释∥********4********之后添加适当的语句。 注意:增加代码,或者修改代码的位置已经用符号表示出来。请不要修改其他的程序代码。 #include using namespace std; Class CBase { public: CBase(int i){b=i;) ∥********1******** protected: int b; }; class CDerive:public CBase { public: ∥********2******** void di splay() { coutdi splay(); } void main() { ∥********4******** func(d1); func(d2); }
进入题库练习
问答题请使用VC6或使用[答题]菜单打开考生文件夹proj1下的工程proj1,此工程中含有一个源程序文件proj1.cpp。其中每个注释“//ERROR ****found****”之后的一行语句存在错误。请改正这些错误,使程序的输出结果为: The perimeter is 62.8 The area is 314 注意:只修改注释“//ERROR ****found****”的下一行语句,不要改动程序中的其他内容。 // proj1.cpp #include <iostream> using namespace std; const double PI=3.14; class Circle { public: // ERROR ********** found********** Circle(int r) { radius =r; } void Display(); private: const int radius; }; //ERROR ********** found********** void Display() { cout <<"The perimeter is" <<2* PI * radius << endl; cout <<"The area is" <<PI* radius* radius <<endl; } int main() { Circle c(10); //ERROR ********** found********** c::Display(); return 0; }
进入题库练习
问答题使用VC6打开考生文件夹下的源程序文件modi2.cpp。完成函数fun(char*str,char*s)空出部分。函数fun(char*str,char*s)的功能是:将在字符串str中下标为偶数位置上的字符,紧随其后重复出现一次,放在一个新串S中,S中字符按原字符串中字符的顺序排列。(注意0为偶数) 例如:当sttr中的字符串为:"abcdef"时,s中的字符串应为:"aaccee"。 注意:不要改动main()函数,不得增行或删行,也不得更改程序的结构。 #include void fun(char*str,char*s) { } void main() { char str[100],s[100]; cout<<"P1ease enter string string:"<
进入题库练习