习题纠错09

使用重载函数编程序的目的是()//A
A
使用相同的函数名调用功能相似的函数
B
共享程序代码
C
提高程序的运行速度
D
节省存储空间
//函数重载的主要目的是让程序员能够使用相同的函数名来编写具有不同参数列表的函数,
//以实现功能相似但参数类型或数量不同的操作。这样可以提高代码的可读性和可维护性。

下面程序输出结果是什么?//A

include

using namespace std;
class A{
public:
A(char *s)
{
cout<<s<<endl;
}
~A(){}
};
class B:virtual public A
{
public:
B(char s1,chars2):A(s1){
cout<<s2<<endl;
}
};
class C:virtual public A
{
public:
C(char s1,chars2):A(s1){
cout<<s2<<endl;
}
};
class D:public B,public C
{
public:
D(char *s1,char *s2,char *s3,char *s4):B(s1,s2),C(s1,s3),A(s1)
{
cout<<s4<<endl;
}
};
int main() {
D *p=new D("class A","class B","class C","class D");
delete p;
return 0;
}

A
class A class B class C class D
B
class D class B class C class A
C
class D class C class B class A
D
class A class C class B class D
//当一个对象的创建,首先会给对象划分的内存空间,之后便是按照继承表的顺序进行调用父类的构造
//函数,其中的D的继承表是从B到C,所以所以会先给B调用构造函数,之后才会是C,而且BC也有父类
//也就是A,因为BC是虚继承A的,所以在D在继承BC的时候,即使是多个路径继承同一个基类,但是还是
//只保留A,而且因为A是BC的基类,所以A先构造,之后是BC,最后是D

/对拷贝构造函数的描述正确的是//D
A
该函数名同类名,也是一种构造函数,该函数返回自身引用
B
该函数只有一个参数,必须是对某个对象的引用
C
每个类都必须有一个拷贝初始化构造函数,如果类中没有说明拷贝构造函数,则编译器系统会自动生成一个缺省拷贝构造函数,作为该类的保护成员
D
拷贝初始化构造函数的作用是将一个已知对象的数据成员值拷贝给正在创建的另一个同类的对象
//首先A选项拷贝构造没有返回值,四个函数中,只有拷贝赋值有返回值的
//B选项错在,该函数是只有一个参数,但是参数并不是某个对象的引用,而是同类对象的引用
//C选项错在,该类的保护成员,拷贝构造是公开的

a,b均为不等于0的整形变量,以下关系式恒成立的是://C
A
ab/ab == 1
B
a/bb/a == 1
C
a/b
b + a%b == a
D
a/b*b == a
//对于C选项可以理解成a除以b得到商(a/b)和余数(a%b),所以当商乘以除数再加上余数,
//得到的是被除数a
//其他选项,就如D选项整数除法得到的是整数,当5/3时得到的是1,1乘以3时得到不是a

求输出结果//B

include

using namespace std;
class A {
public:
virtual void print() {
cout << "A::print()"
<< "\n";
}
};

class B : public A {
public:
virtual void print() {
cout << "B::print()"
<< "\n";
}
};

class C : public A {
public:
virtual void print() {
cout << "C::print()"
<< "\n";
}
};

void print(A a) { a.print(); }
int main() {
A a, *aa, *ab, *ac;
B b;
C c;
aa = &a;
ab = &b;
ac = &c;
a.print();
b.print();
c.print();
aa->print();
ab->print();
ac->print();
print(a);
print(b);
print(c);
}
A
C::print() B::print() A::print() A::print() B::print() C::print() A::print() A::print() A::print()
B
A::print() B::print() C::print() A::print() B::print() C::print() A::print() A::print() A::print()
C
A::print() B::print() C::print() A::print() B::print() C::print() B::print() B::print() B::print()
D
C::print() B::print() A::print() A::print() B::print() C::print() C::print() C::print() C::print()
//是不是这样的,首先因为BC都是以public继承A,且A做为父类的函数是虚函数,且BC作为子类有和A同名的成员函数,所以构成了多态,且函数是覆盖的,
//那么 A a, *aa, *ab, *ac;,这个是定义一个A类型的a对象,以及A类型的aa、ab、ac指针,之后还定义了b对象和c对象,且aa、ab、ac指针分别指向a、b、c的子类对象。
//a.print(); b.print(); c.print();这个是访问各自的成员函数,之后因为覆盖,访问各个子类的成员函数,最后一个类外的函数,进行强制类型转换,输出A::print()

以下代码是哪一句可能导致的编译错误?//D

include

using namespace std;
class Test
{
public:
Test() { cout << "i like zk"; }
Test(int) { cout << "i like wangyi"; }
void exe() { cout << "this is my choice"; }
};
int main()
{
Test a(1);//1
a.exe(); //2
Test b(); //3
b.exe(); //4
Test c; //5
c.exe(); //6
return 0;
}
A 1
B 2
C 3
D 4
E 5
F 6
//因为第三句Test b(),会被误认为函数名为b,返回值为Text的函数,所以在访问成员函数时,会报错
//也就是第四句话,正确的无参构造的写法是 Test b;

STL中的哪种结构在增加成员时可能会引起原有成员的存储位置发生改变//D
A
map;
B
set;
C
list;
D
vector;
//这个是因为,当vector的容量满时,会进行扩容,过程分为三步
//1、完全弃用现有的内存空间,重新申请更大的内存空间;
//2、将旧内存空间中的数据,按原有顺序移动到新的内存空间中;
//3、最后将旧的内存空间释放。

以下关于内联函数,说法正确的是://ABC
A
一般用于加快程序执行速度
B
可能减小可执行文件大小
C
可能增加可执行文件大小
D
以上说法都不正确
//这里主要疑惑的是C,如果当一个非常小的内联函数取代一个非常大的非内联函数,那么,确实会减少可执行文件的
//的大小

下列哪一个循环会导致死循环?()//D
A
for(int k=0;k<0;k++)
B
for(int k=10;k>0;k--)
C
for(int k=0;k<10;k--)
D
没有答案
//有疑问的是C选项,因为int类型也是有类型的,范围在正负20亿,
//所以会溢出,循环结束

常对象只能调用它的常成员函数, 而不能调用普通的成员函数。//A
A
正确
B
错误
//因为,常成员函数是在函数定义的括号后在加上const,
//例如:double get()const

若要重载+、=、<<、==和[]运算符,则必须作为类成员重载的运算符是//D

A
+和=
B
=和<<
C
==和<<
D
=和[]

有如下代码://B
struct A1{
virtual ~A1(){}
};
struct A2{
virtual ~A2(){}
};
struct B1 : A1, A2{};
int main()
{
B1 d;
A1* pb1 = &d;
A2* pb2 = dynamic_cast<A2>(pb1); //L1
A2
pb22 = static_cast<A2*>(pb1); //L2
return 0;
}
A
L1语句编译失败,L2语句编译通过
B
L1语句编译通过,L2语句编译失败
C
L1,L2都编译失败
D
L1,L2都编译通过

有下列C语言程序片段。将它的功能用汇编程序实现,下面1、2、3、4处那句话有逻辑错误的是()//C
if (X>Y) X = X - Y;
else X = X + Y;
汇编片段为:
MOV AX, X
CMP AX, Y //1
JLE ELSE //2
ADD AX, Y //3
ELSE:
ADD AX, Y //4
OK:
MOV X, AX
A 1
B 2
C 3
D 4
//一句一句解释,当使用MOV时,表示将x存储到AX寄存器中,CMP表示将Y与AX寄存器中的x进行比较
//JLE是一个命令跳转指令,当满足x>y时会跳转到ELSE标签,执行ELSE下的指令,当跳转到后执行的
//是AX寄存器中的x+y,这与原意不符,第二句之后便是满足x小于等于y时,执行X=x+y,满足原本条件
//最后的OK:表示OK标签,用于程序结束后的跳转,最后的MOV X,AX 表示将寄存器中的AX值放回x中

有代码如下所示,则在执行 delete p 时,控制台会输出什么内容()//D
class Base
{
public:
virtual ~Base(){
std::out<<"Base Destructor"<<std::endl;
}
}
class Derived: public Base
{
public :
~Derived(){
std::out<<"Derived Destructor"<<std::endl;
}
}
Base* p=new Derived();
delete p;
A
Base Destructor
B
Derived Destructor
C
Base Destructor Derived Destructor
D
Derived Destructor Base Destructor
//这个地方起初有问题的是,虽然基类的析构函数是虚函数,但由于析够函数不同名造成的
//以为不构成多态,但其实这样是构成多态的,所以,当执行delete时,首先会是执行
//子类的析构函数,然后再执行父类的析构函数

当输入数值数据时,对于整型变量只能输入整型值;对于实型变量只能输入实型值。//B
以上叙述是否正确?

A
正确
B
错误

//这里所谓的实数其实就是带有小数点的数据类型,通常为float和double
//所以,当整型进行赋给给实型变量实际上编译器会进行隐式类型转化

以32位C++程序,请计算sizeof的值__________ //C
void Func ( char str[100] ) { sizeof( str ) = ? }
void*p = malloc( 100 ); sizeof( p ) = ?;
A
100,4
B
4, 100
C
4,4
D
100, 100
//这里有问题就是第一个sizeof(str),主要原因在于str作为函数func的形参,数组名作为
//函数参数的时候,会退化为指针,也就是会sizeof出指针的大小

下面有关new/delete和malloc/free的区别,描述错误的是?//CD
A
malloc与free是标准库函数,new/delete是运算符
B
new初始化对象,调用对象的构造函数,malloc仅仅分配内存
C
new、delete只能在C++使用,而malloc、free只能在C中可以使用
D
new、delete返回的是所分配类型变量(对象)的指针,malloc、free返回的是void指针
//主要是D选项的free是没有返回值的

c++的一个类中声明一个static成员变量,下面描述正确的是()//AB
A
static是加了访问控制的全局变量,不被继承
B
类和子类对象,static变量占有一份内存
C
子类继承父类static变量
D
static 变量在创建对象时分配内存空间
//这里需要注意的是静态成员变量,是不能被继承的,因为它是在所有类的实例之间
//进行共享的,即使子类继承了带有静态成员变量的父类,子类中也不会再创建一个
//静态成员变量,D选项静态成员变量,并不是在创建对象时分配内存空间的,而是在
//程序允许的时候就开始了,在程序运行结束后结束

include

include

using namespace std;
int main(void)
{
vectorarray;
array.push_back(100);
array.push_back(300);
array.push_back(300);
array.push_back(300);
array.push_back(300);
array.push_back(500);
vector::iterator itor;
for(itor=array.begin();itor!=array.end();itor++)
{
if(itor==300)
{
itor=array.erase(itor);
}
}
for(itor=array.begin();itor!=array.end();itor++)
{
cout<<
itor<<"";
}
return 0;
}

这段代码的输出是什么//C
A
100 300 300 300 300 500
B
100 3OO 300 300 500
C
100 300 300 500
D
100 300 500
E
100 500
F
程序错误

//成员函数earse(),的返回值是指向被删除元素之后的迭代器,所以,当
//第一次删除第一个300后,itor就指向了下一个300,一次循环结束,那么
//之后删除第三个300,itor指向第四个300,这次循环结束,指向最后的500
//所以,最后剩下的是C

Which of following C++ code is correct?//C
A
int f() { int *a = new int(3); return *a; }
B
int *f() { int a[3] = {1, 2, 3}; return a; }
C
vector f() {vector v(3); return v; }
D
void f(int *ret) { int a[3] = {1, 2, 3}; ret = a++; return; }

//A选项,因为用new申请了堆内存,但没有进行delete释放,所以错误
//B选a是做为局部变量,在函数结束的时候进行返回的时候,函数f接到的是指向未知位置的指针
//D选项,数组名不能进行自增

x=y+8等价于x=x(y+8)。请问这句话是正确的吗?//A
A
正确
B
错误
//*=运算符是复合运算符,用处是将运算符的左侧和运算符的右侧进行相乘,然后赋值给左侧,所以
//是等价的

下面的程序输出可能是什么?//C
class Printer{
public:
Printer(std::string name) {std::cout << name;}
};
class Container{
public:
Container() : b("b"), a("a") {}
Printer a;
Printer b;
};
int main(){
Container c;
return 0;
}
A
可能是 "ab" 或 "ba"。 依赖于具体的实现
B
一直都是 "ba"
C
一直都是 "ab"
//因为根据对象的创建顺序,类类型的成员变量会先于自己的构造函数,所以根据类类型的定义顺序
//所以打印顺序应该一直为ab

以下代码输出什么?//D
int a = 1, b = 32;
printf("%d,%d", a << b, 1 << 32);
A
1,1
B
1,0
C
0,0
D
取决于编译器

//因为a为int类型,当移动位数大于等于整数类型的位数时,会产生未定义行为,这里移动了32位
//所以可能产生未定义行为

以下程序的输出结果是()//A
int main ()
{
char arr[2][4];
strcpy (arr[0],"you");
strcpy (arr[1],"me");
arr[0][3]='&';
printf("%s \n",arr);
return 0;
}
A
you&me
B
you
C
me
D
err
//这里的arr[2][4],可以理解成有两行,每行元素有四个,当arr[0]为“you”时,且arr[0][3]时,则arr[0]
//刚好满,值为“you&”,arr[1]为“me”,且两者之间并没有搁其他元素,所以,输出为A

以下不能作为合法常量的是://B
A
1.234e04
B
1.234e0.4
C
1.234e+4
D
1.234e0
//首先科学计数法的话,指数部分(e之后)必须是一个整数,对于C选项,+4,表示的是10^4

通过一个对象调用虚函数时,C++系统对该调用采用( )。
A
动态联编
B
静态联编
C
不确定是哪种联编
D
函数重载
//B
//这里需要知道的是,当通过对象调用虚函数就是静态联编,
//通过指针调用虚函数的话,就是动态联编,这里是通过对象调用的
//所以是静态联编

在上下文及头文件均正常的情况下,字符串"Hello"会被输出几次?//C
int main(){
printf("Hello");
fork ();
printf ("Hello");
}
A. 2
B 3
C 4
D. 6
//因为,首先未创建子进程时,先执行一遍printf,之后创建子进程,由于父子进程之间的IO流缓冲区
//之间是共享的,且之前执行的输出缓冲区,并没有清楚干净,所以,这样就造成了fork()执行时,子进程执行一次
//之后执行后序代码,又分别打打印了两次,这样一共打印了四次,如果将\n加上,则打印三次

posted @ 2023-09-07 21:01  优秀还天籁  阅读(9)  评论(0编辑  收藏  举报