cpp错题本
命名空间
缺省参数
**下面关于C++缺省参数描述错误的是( ) (多选)【不定项缺省】
A.缺省参数是声明或定义函数时为函数的参数指定一个默认值.
B.在调用有缺省参数的函数时,如果没有指定实参则采用该默认值,否则使用指定的实参
C.C和C++都支持缺省参数
D.全缺省就是参数全部给缺省值,半缺省就是缺省一半的值
答案:c d A.缺省参数就是给出的函数参数的默认值
B.很明显,这是给出缺省值的意义所在
C.纯C语言,即.c文件,函数不支持缺省参数,C++即.cpp文件支持
D.半缺省不能随便缺省一半,必须从右往左缺省,否则编译出错
函数重载
**下面关于函数重载描述错误的是( )【多选择】
A.构成函数重载的条件是函数名相同就可以
B.重载的函数参数可以相同
C.重载的函数返回值可以相同
D.C和C++都支持函数重载
答案 A B D A.函数名相同只是函数重载的条件之一
B.重载函数必须参数列表有所不同(包括参数类型和参数个数)
C.重载函数不依靠返回值来区分,所以返回值可以相同
D.C不支持函数重载
引用
**关于引用以下说法错误的是( )(阿里巴巴2015笔试题)
A.引用必须初始化,指针不必
B.引用初始化以后不能被改变,指针可以改变所指的对象
C.不存在指向空值的引用,但是存在指向空值的指针
D.一个引用可以看作是某个变量的一个“别名”
E.引用传值,指针传地址
F.函数参数可以声明为引用或指针类型
答案 E A.引用必须初始化,必须在定义引用时明确引用的是哪个变量或者对象,否则语法错误,指针不初 始化时值为随机指向
B.引用一旦定义时初始化指定,就不能再修改,指针可以改变指向
C.引用必须出示化,不能出现空引用,指针可以赋值为空
D.简单粗暴的引用理解可以理解为被引用变量或对象的”别名”
E.引用表面好像是传值,其本质也是传地址,只是这个工作有编译器来做,所以错误
F.函数调用为了提高效率,常使用引用或指针作为函数参数传递变量或对象
内联inline
**关于c++的inline关键字,以下说法正确的是( )
A.使用inline关键字的函数会被编译器在调用处展开
B.头文件中可以包含inline函数的声明
C.可以在同一个项目的不同源文件内定义函数名相同但实现不同的inline函数
D.递归函数也都可以成为inline函数
答案 C A.不一定,因为inline只是一种建议,需要看此函数是否能够成为内联函数
B. inline函数不支持声明和定义分离开,因为编译器一旦将一个函数作为内联函数处理,就会在调用位置展开,即该函数是没有地址的,也不能在其他源文件中调用,故一般都是直接在源文件中定义内联函数的
C.inline函数会在调用的地方展开,所以符号表中不会有inline函数的符号名,不存在链接冲突。
D.比较长的函数,递归函数就算定义为inline,也会被编译器忽略,故错误
类的定义
this指针
下面描述错误的是( )
A.this指针是非静态成员函数的隐含形参.
B.每个非静态的成员函数都有一个this指针.
C.this指针是存在对象里面的.
D.this指针可以为空
答案 C A.静态成员函数没有this指针,只有非静态成员函数才有,且为隐藏指针
B.非静态成员函数的第一个参数就是隐藏的this指针
C.this指针在非静态的成员函数里面,对象不存在,故错误
D.单纯的对this赋空是不可以的,不过可以强转直接赋空,不过一般不进行这样的操作
构造函数和析构函数
“=”赋值运算符
下列关于赋值运算符“=”重载的叙述中,正确的是( )
A.赋值运算符只能作为类的成员函数重载
B.默认的赋值运算符实现了“深层复制”功能
C.重载的赋值运算符函数有两个本类对象作为形参
D.如果己经定义了复制拷贝构造函数,就不能重载赋值运算符
答案 A A. 赋值运算符在类中不显式实现时,编译器会生成一份默认的,此时用户在类外再将赋值运算符重载为全局的,就和编译器生成的默认赋值运算符冲突了,故赋值运算符只能重载成成员函数
B.默认的赋值运算符是按成员成员,属于浅赋值
C.参数只有一个,另一个通过this指针传递
D.两个函数的调用场景不同,相互没有影响
构造函数初始化列表
**在一个cpp文件里面,定义了一个static类型的全局变量,下面一个正确的描述是:( )
A.只能在该cpp所在的编译模块中使用该变量
B.该变量的值是不可改变的
C.该变量不能在类的成员函数中引用
D.这种变量只能是基本类型(如int,char)不能是C++类型
答案 A A.正确,static限制了变量具有文件域
B.static变量是可以被改变的
C.可以被正常访问使用,以及通过成员来进行引用
D.静态变量也可以是自定义类型的变量
内存分配
内存分配堆栈
**下面有关c++内存分配堆栈说法错误的是( )
A.对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制
B. 对于栈来讲,生长方向是向下的,也就是向着内存地址减小的方向;对于堆来讲,它的生长方向是向上的,是向着内存地址增加的方向增长
C.对于堆来讲,频繁的 new/delete 势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题
D.一般来讲在 32 位系统下,堆内存可以达到4G的空间,但是对于栈来讲,一般都是有一定的空间大小的
答案 C A.栈区主要存在局部变量和函数参数,其空间的管理由编译器自动完成,无需手动控制,堆区是自己申请的空间,在不需 要时需要手动释放
B.栈区先定义的变量放到栈底,地址高,后定义的变量放到栈顶,地址低,因此是向下生长的,堆区则相反
C.频繁的申请空间和释放空间,容易造成内存碎片,甚至内存泄漏,栈区由于是自动管理,不存在此问题
D.32位系统下,最大的访问内存空间为4G,所以不可能把所有的内存空间当做堆内存使用,故错误
堆与栈
**C++中关于堆和栈的说法,哪个是错误的:( )
A.堆的大小仅受操作系统的限制,栈的大小一般较小
B.在堆上频繁的调用new/delete容易产生内存碎片,栈没有这个问题
C.堆和栈都可以静态分配
D.堆和栈都可以动态分配
答案 C A.堆大小受限于操作系统,而栈空间一般有系统直接分配
B.频繁的申请空间和释放空间,容易造成内存碎片,甚至内存泄漏,栈区由于是自动管理,不存在此问题
C.堆无法静态分配,只能动态分配
D.栈可以通过函数_alloca进行动态分配,不过注意,所分配空间不能通过free或delete进行释放
构造与析构次数知识
对于内置类型(比如 char, int, double 等):
-
多数编译器能正确释放整个内存块,不会泄漏。
-
因为内置类型没有析构函数,delete 只需要释放内存,不涉及调用析构函数链。
-
但这是未定义行为(UB),C++ 标准不保证一定正确。 对于自定义类类型:
-
如果类有析构函数,delete 只会调用第一个元素的析构函数,其余对象的析构函数不会被调用,可能导致资源泄漏。
-
这是严重的错误。
构造与析构(自定义类型)
ClassA * pclassa=new ClassA[5];
delete pclassa;
c++语言中,类ClassA的构造函数和析构函数的执行次数分别为( )
A.5,1
B.1,1
C.5,5
D.程序可能崩溃
答案 D A.申请对象数组,会调用构造函数5次,delete由于没有使用[],此时只会调用一次析构函数,但往往会引发程序崩溃
B.构造函数会调用5次
C.析构函数此时只会调用1次,要想完整释放数组空间,需要使用[]
D.正确
构造与析构(内置类型)
使用 char* p = new char[100]申请一段内存,然后使用delete p释放,有什么问题?( )
A.会有内存泄露
B.不会有内存泄露,但不建议用
C.编译就会报错,必须使用delete []p
D.编译没问题,运行会直接崩溃
答案 B A.对于内置类型,此时delete就相当于free,因此不会造成内存泄漏
B.正确
C.编译不会报错,建议针对数组释放使用delete[],如果是自定义类型,不使用方括号就会运行时错误
D.对于内置类型,程序不会崩溃,但不建议这样使用
指针大小
**指针大小至于机器架构(写址能力)有关与指向类型无关
- 32位->4字节
- 64位->8字节
string的特性与使用
比较
关于代码输出正确的结果是( )(vs2013 环境下编译运行)
int main(int argc, char *argv[])
{
string a="hello world";
string b=a;
if (a.c_str()==b.c_str())
{
cout<<"true"<<endl;
}
else cout<<"false"<<endl;
string c=b;
c="";
if (a.c_str()==b.c_str())
{
cout<<"true"<<endl;
}
else cout<<"false"<<endl;
a="";
if (a.c_str()==b.c_str())
{
cout<<"true"<<endl;
}
else cout<<"false"<<endl;
return 0;
A.false false falseB.true false falseC.true true trueD.true true false
分析:a 和 b的值虽然相同,但是a.c_str()==b.c_str()比较的是存储字符串位置的地址,a和b是两个不同的对象,内部数据存储的位置也不相同,因此不相等,后面c="",a=""与b对象都没有任何的影响,所以都不相等
故答案为:A}find_first_of与substr
下面程序的输出结果正确的是( )
int main(int argc, char *argv[])
{
string strText = "How are you?";
string strSeparator = " ";
string strResult;
int size_pos = 0;
int size_prev_pos = 0;
while((size_pos=strText.find_first_of(strSeparator, size_pos)) != string::npos)
{
strResult = strText.substr(size_prev_pos, size_pos-size_prev_pos);
cout<<strResult<<" ";
size_prev_pos = ++size_pos;
}
if(size_prev_pos != strText.size())
{
strResult = strText.substr(size_prev_pos, size_pos-size_prev_pos);
cout<<strResult<<" ";
}
cout<<endl;
return 0;
}
A.Howareyou?B.How Are You?C.How areD.How are you?
分析:程序的目的是以字符串strSeparator = " "作为分隔符,对字符串string strText = "How are you?";进行分割,每分割出一个单词就进行一次打印
find_first_of 如果没有找到,就返回npos,而不是不返回值
故答案为 D文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!

