牛客c++练习题库01个人总结整理参考模板.docx
《牛客c++练习题库01个人总结整理参考模板.docx》由会员分享,可在线阅读,更多相关《牛客c++练习题库01个人总结整理参考模板.docx(13页珍藏版)》请在冰点文库上搜索。
牛客c++练习题库01个人总结整理参考模板
1.下面哪几种是STL容器类型()
答:
C++11STL中的容器有四种:
一.顺序容器:
vector:
可变大小数组;
deque:
双端队列;
list:
双向链表;
forward_list:
单向链表;
array:
固定大小数组;
string:
与vector相同的容器,但专门用于保存字符。
二.关联容器:
按关键字有序保存元素:
(底层实现为红黑树)
map:
关联数组;保存关键字-值对;
set:
关键字即值,即只保存关键字的容器。
multimap:
关键字可重复的map;
multiset:
关键字可重复的set;
三.无序容器:
unordered_map:
用哈希函数组织的map;
unordered_set:
用哈希函数组织的set;
unordered_multimap:
哈希组织的map;关键字可以重复出现;
unordered_multiset:
哈希组织的set;关键字可以重复出现。
四.其他项:
stack、queue、valarray、bitset
2.C语言中运算对象必须是整型的运算符是()
答:
~、^、&、|、%等都必须两边是整型
/是除法运算符,对运算前后数字类型没有要求。
例如:
2.4/1.2=2
%是取余运算符,运算符前后必须是整型
例如:
4%3=1
3.下面程序的输出结果是()
答:
这题里变量i定义类型分为局部变量和全局变量。
局部值为2,全局为0。
main函数里{}中执行的出来的k值为5+3*2=11;//作用的是局部变量
括号外的K=11+0*3=11;//作用的是全局变量
反映了局部变量的有限性。
4.阅读以下代码:
答:
memset的作用:
void*memset(void*s,intch,size_tn);
函数解释:
将s中前n个字节(typedefunsignedintsize_t)用ch替换并返回s.
作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法,通常为新申请的内存做初始化工作.
1.memset是以字节为单位,初始化内存块。
当初始化一个字节单位的数组时,可以用memset把每个数组单元初始化成任何你想要的值,比如,
chardata[10];
memset(data,1,sizeof(data));//right
memset(data,0,sizeof(data));//right
而在初始化其他基础类型时,则需要注意,比如,
intdata[10];
memset(data,0,sizeof(data));//right
memset(data,-1,sizeof(data));//right
memset(data,1,sizeof(data));//wrong,data[x]wouldbe0x0101insteadof1
2.当结构体类型中包含指针时,在使用memset初始化时需要小心。
比如如下代码中,
structParameters{
intx;
int*p_x;
};
Parameterspar;
par.p_x=newint[10];
memset(&par,0,sizeof(par));
当memset初始化时,并不会初始化p_x指向的int数组单元的值,而会把已经分配过内存的p_x指针本身设置为0,造成内存泄漏。
同理,对std:
:
vector等数据类型,显而易见也是不应该使用memset来初始化的。
3.当结构体或类的本身或其基类中存在虚函数时,也需要谨慎使用memset。
这个问题就是在开头项目中发现的问题,如下代码中,
classBaseParameters
{
public:
virtualvoidreset(){}
};
classMyParameters:
publicBaseParameters
{
public:
intdata[3];
intbuf[3];
};
MyParametersmy_pars;
memset(&my_pars,0,sizeof(my_pars));
BaseParameters*pars=&my_pars;
//......
MyParameters*my=dynamic_cast(pars);
程序运行到dynamic_cast时发生异常。
原因其实也很容易发现,我们的目的是为了初始化数据结构MyParameters里的data和buf,正常来说需要初始化的内存空间是sizeof(int)*3*2=24字节,但是使用memset直接初始化MyParameters类型的数据结构时,sizeof(my_pars)却是28字节,因为为了实现多态机制,C++对有虚函数的对象会包含一个指向虚函数表(V-Table)的指针,当使用memset时,会把该虚函数表的指针也初始化为0,而dynamic_cast也使用RTTI技术,运行时会使用到V-Table,可此时由于与V-Table的链接已经被破坏,导致程序发生异常。
5.下面哪种情况下,B不能隐式转换为A?
答:
B。
答案A,表示A是基类,B是派生类,向上级类型转换是隐式的,因为部分元素丢弃可以自动完成,向下转型是显式的因为不知道应该增加的值是什么。
所以B不能。
答案C,Operator除了表示函数重载操作符,还可以表示B类型可以装换为A类型。
这个知识点就有点偏了。
答案D,拷贝构造函数,Bb=A肯定是可以的。
6.在函数调用过程中,如果函数funA调用了函数funB,函数funB又调用了函数funA,则()
答:
直接递归调用:
在函数a(或过程)中直接引用(调用)函数a本身
间接递归调用:
在函数a(或过程)中调用另外一个函数b,而该函数b又引用(调用)了函数a
循环调用:
一个函数里有一个循环,然后在循环里面调用这个函数。
7.请选择下面代码的输出结果
答:
8.关于vector<>初始化问题下面那个是非法的?
答:
vector初始化方式有四种:
1.vectorv(10);表示创建size为10的vector,每个元素执行默认初始化;
2.vectorv(10,1);表示创建size为10的vector,每个元素初始化为1;
3.vectorv{1,2,3,4};表示创建size为4的vector,元素的值分别为1,2,3,4。
4.vectorv;表示创建size为0的vector;
vector>svvec(10),表示元素个数。
初始化方式有两种,数组和push_back
9.inta=5,则++(a++)的值是?
答:
a++返回的是右值
++a的前提条件是可修改的左值。
而且,(a++)是一个表达式,自增运算不能作用于表达式。
10.如下程序:
#include"stdio.h"
classBase
{
public:
Base()
{
Init();
}
virtualvoidInit()
{
printf("BaseInit\n");
}
voidfunc()
{
printf("Basefunc\n");
}
};
classDerived:
publicBase
{
public:
virtualvoidInit()
{
printf("DerivedInit\n");
}
voidfunc()
{
printf("Derivedfunc\n");
}
};
intmain()
{
Derivedd;
((Base*)&d)->func();
return0;
}
该程序的执行结果:
答:
在构造函数不要调用虚函数。
在基类构造的时候,虚函数是非虚,不会走到派生类中,既是采用的静态绑定。
显然的是:
当我们构造一个子类的对象时,先调用基类的构造函数,构造子类中基类部分,子类还没有构造,还没有初始化,如果在基类的构造中调用虚函数,如果可以的话就是调用一个还没有被初始化的对象,那是很危险的,所以C++中是不可以在构造父类对象部分的时候调用子类的虚函数实现。
但是不是说你不可以那么写程序,你这么写,编译器也不会报错。
只是你如果这么写的话编译器不会给你调用子类的实现,而是还是调用基类的实现。
在析构函数中也不要调用虚函数。
在析构的时候会首先调用子类的析构函数,析构掉对象中的子类部分,然后在调用基类的析构函数析构基类部分,如果在基类的析构函数里面调用虚函数,会导致其调用已经析构了的子类对象里面的函数,这是非常危险的。
(本资料素材和资料部分来自网络,仅供参考。
请预览后才下载,期待您的好评与关注!
)