C++练习题.docx
- 文档编号:9860127
- 上传时间:2023-02-07
- 格式:DOCX
- 页数:19
- 大小:22.98KB
C++练习题.docx
《C++练习题.docx》由会员分享,可在线阅读,更多相关《C++练习题.docx(19页珍藏版)》请在冰豆网上搜索。
C++练习题
1、创建一个单链表,写一个链表。
单向链表的反转是一个经常被问到的一个面试题,也是一个非常基础的问题。
比如一个链表是这样的:
1->2->3->4->5通过反转后成为5->4->3->2->1。
#include
#include
usingnamespacestd;
classFID
{
public:
intnum;
FID*next;
};
FID*head=NULL;
voidcreate(intnum)
{
while(num>0)
{
FID*p=newFID;
cout<<"数字:
";
cin>>p->num;
if(head==NULL)
{
head=p;
p->next=NULL;
}
else{
FID*temp=head;
while(temp->next!
=NULL)
{
temp=temp->next;
}
temp->next=p;
p->next=NULL;
}
num--;
}
}
voidreserve()
{
FID*pre,*cur,*next;
pre=head;
cur=pre->next;
while(cur!
=NULL)
{
next=cur->next;
cur->next=pre;
pre=cur;
cur=next;
}
head->next=NULL;
head=pre;
}
voidshow()
{
FID*ps=head;
while(ps!
=NULL)
{
cout<
ps=ps->next;
}
}
intmain()
{
create(5);
reserve();
show();
return0;
}
2、已知string类定义如下:
classString
{
public:
String(constchar*str=NULL);//通用构造函数
String(constString&another);//拷贝构造函数
~String();//析构函数
String&operater=(constString&rhs);//赋值函数
private:
char*m_data;//用于保存字符串
};
String:
:
String(constchar*str)
{
if(str==NULL)//strlen在参数为NULL时会抛
异常才会有这步判断
{
m_data=newchar[1];
m_data[0]='\0';
}
else
{
m_data=newchar[strlen(str)+1];
strcpy(m_data,str);
}
}
String:
:
String(constString&another)
{
m_data=newchar[strlen(another.m_data)+1];
strcpy(m_data,other.m_data);
}
String&String:
:
operator=(constString&rhs)
{
if(this==&rhs)
return*this;
delete[]m_data;//删除原来的数据,新开一块内
存
m_data=newchar[strlen(rhs.m_data)+1];
strcpy(m_data,rhs.m_data);
return*this;
}
String:
:
~String()
{
delete[]m_data;
}
3、已知strcpy的函数原型:
char*strcpy(char*strDest,constchar*strSrc)其中strDest是目的字符串,strSrc是源字符串。
不调用C++/C的字符串库函数,请编写函数strcpy。
char*strcpy(char*strDest,constchar*strSrc)
{
if((strDest==NULL)||(strSrc==NULL))//[1]
throw"Invalidargument(s)";//[2]
char*strDestCopy=strDest;//[3]
while((*strDest++=*strSrc++)!
='\0');//[4]
returnstrDestCopy;
}
3、求下面函数的返回值。
intfunc(x)
{
intcountx=0;
while(x)
{
countx++;
x=x&(x-1);
}
returncountx;
}
x=9999时,x-1=9998,用二进制表示
10011100001111
10011100001110
当他们执行&运算并赋值给x,结果x为
10011100001110
此时x-1为
10011100001101
当他们执行&运算并赋值给x,结果x为
10011100001100
如此类推到结果为00000000000000,应该发现x=x&(x-1)就是将x最右边的二进制位1变为0。
x为9999时二进制为1的位有8个,所以结果为8
4、什么是“引用”?
申明和使用“引用”要注意哪些问题?
1:
引用就是对某个变量其别名。
对引用的操作与对应变量的操作的效果完全一样。
2:
申明一个引用的时候,要对其进行初始化。
引用申明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,不能再把该引用名作为其他变量名的别名。
声明一个引用,不是新定义一个变量,他只表示该引用名是目标变量名的一个别名,他本身不是一中数据类型,因此引用本身不是储存单元,系统也不给引用分配储存单元。
3:
不能创建数组引用。
5、将“引用”作为函数参数有哪些特点?
1:
传递引用给函数与传递指针的效果一样。
2:
使用引用传递函数的参数,在内存中并没有产生实参的副本,他是直接对实参操作。
6、在什么时候需要使用“常引用”?
如果既要利用引用提高程序的效率,又要保护传递给函数的数据不在函数中被改变,就应使用常引用。
7、将“引用”作为函数返回值类型的格式、好处和需要遵守的规则?
1:
格式:
类型标识符&函数名
2:
好处:
在内存中不产生被返回值的副本
3:
需要遵守:
一、不能返回局部变量的引用;二、不能返回函数内部new分配的内存的引用;
三、可以返回类成员引用,但最好是const。
8、“引用”与多态的关系?
引用是除指针外另一个可以产生多态效果的手段。
这意味这,一个积累的引用可以指向他的派生类实例。
9、“引用”与指针的区别是什么?
指针通过某个指针变量指向一个对象后,对它所指向的变量间接操作。
程序中使用指针,程序的可读性差;而引用本身就是目标变量的别名,对引用的操作就是对目标变量的操作。
此外,就是对函数传ref和pointer的区别。
10、什么时候需要“引用”?
复杂类型要用,避免拷贝构造函数被调用
12、.h头文件中的ifndef/define/endif的作用?
这个是预编译的命令,是用来防止头文件重复包含的。
13、#include
<>是标准库头文件:
查找时在系统定义的库中查询,””是用户自定义库头文件:
查找时在用户自己定义的文件中查找。
14、在C++程序中调用被C编译器编译后的函数,为什么要加extern“C”?
作为extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,该关键字告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用。
通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。
15、面向对象的四个基本特征,并简单叙述之?
抽象,继承,封装,多态
16、重载(overload)和重写(overried,有的书也叫做“覆盖”)的区别?
从定义上来说:
重载:
是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。
重写:
是指子类重新定义父类虚函数的方法。
从实现原理上来说:
重载:
编译器根据函数不同的参数表,对同名函数的名称做修饰,然后这些同名函数就成了不同的函数。
重写:
和多态真正相关。
当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的。
17、多态的作用?
允许父类指针或名称来引用子类对象,或对象方法,而实际调用的方法为对象的类类型方法。
18、newdelete与mallocfree的联系与区别?
malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。
它们都可用于在堆区上申请动态内存和释放内存。
用malloc函数需要指定分配的字节数并且不能初始化对象,new会自动调用对象的构造函数,delete会调用对象的析构函数,而free不会调用对象的析构函数。
19、#defineDOUBLE(x)x+x,i=5*DOUBLE(5);i是多少?
i=30
20、有哪几种情况只能用intializationlist而不能用assignment?
无论是在构造函数初始化列表中初始化成员,还是在构造函数体中对它们赋值,最终结果都是相同的。
不同之处在于,使用构造函数初始化列表初始化数据成员,没有定义初始化列表的构造函数在构造函数体中对数据成员赋值。
对于const和reference类型成员变量,它们只能够被初始化而不能做赋值操作,因此只能用初始化列表。
还有一种情况就是,类的构造函数需要调用其基类的构造函数的时候。
20、C++是不是类型安全的?
不是。
两个不同类型的指针之间可以强制转换(用reinterpretcast)。
C#是类型安全的。
21、main函数执行以前,还会执行什么代码?
全局对象的构造函数会在Main前执行。
22、描述内存分配方式以及它们的区别?
1) 从静态存储区域分配。
内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。
例如全局变量,static 变量。
2) 在栈上创建。
在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。
栈内存分配运算内置于处理器的指令集。
3) 从堆上分配,亦称动态内存分配。
程序在运行的时候用malloc 或new 申请任意多少的内存,程序员自己负责在何时用free 或delete 释放内存。
动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。
24、struct和class的区别。
默认继承权限。
默认情况下,class的继承是以private来继承而struct则是按照public进行继承。
成员的默认访问权限。
class的成员默认是private权限,struct默认是public权限。
25、当一个类A中没有生命任何成员变量与成员函数,这时sizeof(A)的值是多少,如果不是零,请解释一下编译器为什么没有让它为零。
当一个类A中没有生命任何成员变量与成员函数,这时sizeof(A)的值是多少,如果不是零,请解释一下编译器为什么没有让它为零。
(Autodesk)
26、比较C++中的4种类型转换方式?
1.static_cast
最常用的类型转换符,在正常状况下的类型转换,如把int转换为float;
2.const_cast
用于取出const属性,把const类型的指针变为非const类型的指针;
3.dynamic_cast
用于运算时检查该转换是否类型安全,但只在多态类型是合法;
4.reinterpret_cast
Interpret是解释的意思,reinterpret即为重新解释,此标识符的意思即为数据的二进制心事重新解释
27、分别写出BOOL,int,float,指针类型的变量a与“零”的比较语句。
BOOL:
if(!
a)orif(a)
int:
if(a==0)
float:
constEXPRESSIONEXP=0.000001
if(a
pointer:
if(a!
=NULL)orif(a==NULL)
28、请说出const与#define相比,有何优点?
1)const常量有数据类型,而宏常量没有数据类型。
编译器可以对前者进行类型安全检查。
而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。
2)有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。
29、简述数组与指针的区别?
数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。
指针可以随时指向任意类型的内存块。
(1)修改内容上的差别
chara[]=“hello”;
a[0]=?
X?
;
char*p=“world”;//注意p指向常量字符串
p[0]=?
X?
;//编译器不能发现该错误,运行时错误
(2)用运算符sizeof可以计算出数组的容量(字节数)。
sizeof(p),p为指针得到的是一个指针变量的字节数,而不是p所指的内存容量。
C++/C语言没有办法知道指针所指的内存容量,除非在申请内存时记住它。
注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。
chara[]="helloworld";
char*p=a;
cout< cout< 计算数组和指针的内存容量 voidFunc(chara[100]) { cout< } 30、类成员函数的重载、覆盖和隐藏区别? a.成员函数被重载的特征: (1)相同的范围(在同一个类中); (2)函数名字相同; (3)参数不同; (4)virtual关键字可有可无。 b.覆盖是指派生类函数覆盖基类函数,特征是: (1)不同的范围(分别位于派生类与基类); (2)函数名字相同; (3)参数相同; (4)基类函数必须有virtual关键字。 c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下: (1)如果派生类的函数与基类的函数同名,但是参数不同。 此时,不论有无virtual关键字,基类的函数将被隐藏(注意别与重载混淆)。 (2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。 此时,基类的函数被隐藏(注意别与覆盖混淆) 31、如何判断一段程序是由C编译程序还是由C++编译程序编译的? #ifdef__cplusplus; cout<<"c++&qu; #else; cout<<"c"; #endif; 32、文件中有一组整数,要求排序后输出到另一个文件中。 #include #include usingnamespacestd; voidOrder(vector { intcount=data.size(); inttag=false;//设置是否需要继续冒泡的标志位 for(inti=0;i { for(intj=0;j { if(data[j]>data[j+1]) { tag=true; inttemp=data[j]; data[j]=data[j+1]; data[j+1]=temp; } } if(! tag) break; } } voidmain(void) { vector ifstreamin("c: \\data.txt"); if(! in) { cout<<"fileerror! "; exit (1); } inttemp; while(! in.eof()) { in>>temp; data.push_back(temp); } in.close();//关闭输入文件流 Order(data); ofstreamout("c: \\result.txt"); if(! out) { cout<<"fileerror! "; exit (1); } for(i=0;i out< out.close();//关闭输出文件流 } 33、输入一个字符串,将其逆序后输出。 #include usingnamespacestd; voidmain() { chara[50];memset(a,0,sizeof(a)); inti=0,j; chart; cin.getline(a,50,'\n');
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 练习题