1.若要定义一个只允许本源文件中所有函数使用的全局变量,则该变量需要使用的存储类型是?
A.extern
B.register
C.auto
D.static
答案:D
解析:
A.外部变量,可供所有源文件使用
B.寄存器变量,放在寄存器而非内存中,效率更高,一般是临时变量
C.自动变量,所有未加 static 关键字的都默认是 auto 变量,也就是我们的普通变量
D.静态变量,在内存中只存在一个,可供当前源文件的所有函数使用
2.下面哪个指针表达式可以用来引用数组元素a[i][j][k][l]
A.(((a+i)+j)+k)+l)
B.((((a+i)+j)+k)+l)
C.(((a+i)+j)+k+l)
D.((a+i)+j+k+l)
答案:B
解析:
a:整个四维数组的地址
*(a+i) = a[i] *(a+i)+j = a[i] +j *(*(a+i)+j) = a[i][j] *(*(a+i)+j)+k = a[i][j]+k *(*(*(a+i)+j)+k ) = a[i][j][k] *(*(*(a+i)+j)+k )+l = a[i][j][k]+l *(*(*(*(a+i)+j)+k )+l ) = a[i][j][k][l]
3.下面有关vector和list的区别,描述错误的是?
A.vector拥有一段连续的内存空间,因此支持随机存取,如果需要高效的随即存取
B.list拥有一段不连续的内存空间,如果需要大量的插入和删除,应该使用list
C.vector::iterator支持“+”、“+=”、“<”等操作符
D.list::iterator则不支持“+”、“+=”、“<”等操作符运算,但是支持了[ ]运算符4
答案:D
解析:
vector拥有一段连续的内存空间,并且起始地址不变,因此它能非常好的支持随即存取,即[]操作符,但由于它的内存空间是连续的,所以在中间进行插入和删除会造成内存块的拷贝,另外,当该数组后的内存空间不够时,需要重新申请一块足够大的内存并进行内存的拷贝,这些都大大影响了vector的效率。
list就是数据结构,中的双向链表,因此它的内存空间可以是不连续的,通过指针来进行数据的访问,这个特点使得它的随即存取变的非常没有效率,因此它没有提供[]操作符的重载。但由于链表的特点,它可以以很好的效率支持任意地方的删除和插入
4.设已经有A,B,C,D4个类的定义,程序中A,B,C,D析构函数调用顺序为?
C c;
void main()
{
A*pa=new A();
B b;
static D d;
delete pa;
}
答案:A B D C
解析:全局变量和静态局部变量是从静态(全局)变量区中划分空间
全局变量作用域大于静态局部变量
先调用A的析构,因为delete pa,A
再释放栈上的对象b,B
关键看CD的顺序,
c是全局对象,对它的初始化是在main函数之前,所以析构时候要放在最后,
也就是先析构d,然后再析构c
5.以下哪种STL容器中的对象是连续存储的?
A.list
B.vector
C.map
D.set
答案:B
解析:vector 封装了数组 ,是一种动态数组,在内存中具有连续的存储空间,支持[]运算符
A 选项 list 封装了链表 list 是采用双向链表实现的,内存不连续,不支持[]运算符
C D 选项 map 和 set 是标准关联容器,使用了非常高效的平衡检索二叉树:红黑树,内存不连续,他的插入删除效率比其他序列容器高是因为不需要做内存拷贝和内存移动,而直接替换指向节点的指针即可
只有dqeue和vector是连续存储的
6.一个 const 对象()
A.能访问所有成员函数
B.只能访问const成员函数
C.能访问static成员函数
D.能访问volatile成员函数
答案:B
解析:在一个对象调用其成员函数时,它隐含的一个形参 this 指针。
*例如,我们定义了一个函数 CTest::ttt();实际上在编译器中该函数的定义就是 CTest::ttt(CTest const this) ,该 this 指针所指向的内容可以改变,但是该 this 指针不可以被改变。当我们用 CTest 的一个对象 test1 调用 ttt 函数时即 test1.ttt() 时,编译器就会将它解释为 ttt(&test1) ,所以我们在 ttt 中使用 this 指针就可以改变对象 test1 的成员变量了
但是,当我们的对象是 const 对象时,即 const CTest ttt; 这时候表示什么意思呢, ttt 的内容是不可以改边的,当我们把 &ttt 作为一个参数传到形参 this 时,矛盾出现了: ttt 是一个常量,其成员不可以被改变; this 指针的成员变量是可以改变的。如果我能正确的将 ttt 的地址传给 this ,那么 ttt 这个常量的值不是可以在 this 中被改变了吗,所以,编译器是不允许这种情况出现的,就提示错误了。故, const 对象不能访问非 const 成员函数。
同理,当我们的成员函数是 const 成员函数时,例: CTest::ttt() const,在编译器解释时会将该函数解释为 CTest::ttt(const CTest * const this),this 指针及其所指向的内容都不可以被修改,前面提到的矛盾也就不存在了,所以 const 对象可以访问 const 成员变量
7.基类的公有成员是其私有派生类的( )成员?
A.不可见
B.私有
C.保护
D.公有
答案:B
解析:
基类的公有成员,保护成员是其私有派生类的私有成员。 基类的公有成员,保护成员是其保护派生类的保护成员。 基类的公有成员,保护成员是其公有派生类的公有成员。 基类的私有成员对其派生类均不可见
8.关于子类型的描述中,( )是错误的?
A.在公有继承下,派生类是基类的子类型
B.子类型关系是不可逆的
C.子类型就是指派生类是基类的子类型
D.一种类型当它至少提供了另一种类型的行为,则这种类型是另一种类型的子类型
答案:C
解析:
子类型必须是子类继承了父类的所有可继承特性,也即公有继承,才能说是子类型,否则就只是单纯的子类
“子类”和“子类型”是不同的,替换原则只适合于"子类型"关系,而一般编程语言只是考虑了"子类"关系
子类 : 说明了新类是继承自父类
子类型 : 强调的是新类具有父类一样的行为(未必是继承)
那么,什么时候才应该使用继承?
那就是符合子类型关系的时候,或者一般所说的”is a"关系, 你必须保证新类的行为与父类完全一致!!!
在任何使用父类的场合,新类应该表现一样的行为
9.对于void类型函数,调用时不可作为( )
A.自定义函数体中的语句
B.循环体里的语句
C.if 语句的成分语句
D.表达式
答案:D
解析:
表达式是要计算值的,void函数的调用是没有值的,所以void函数调用不能出现在表达式里
表达式:是由变量+常量+各种操作符组成的一个计算过程,表达式计算以后返回一个结果值,void型函数无返回值,无法进行运算,只能作为语句,故不可以出现在表达式中
表达式的作用有两点,一个是放在赋值语句的右边,另一个是作为函数的参数
10.代码可以通过编译吗?如果不能应该如何修改?
templateclass Foo{ T tVar; public: Foo(T t) : tVar(t) { } }; template class FooDerived:public Foo { }; int main() { FooDerived d(5); return 0; }
A.代码可以正确通过编译。
B.编译错误,FooDerived是一个继承模板类的非模板类,它的类型不能改变。
C.编译错误,tVal变量是一个不确定的类型。
D.编译错误,可以在FooDerived类中添加一个构造函数解决问题。
答案:D
解析:当基类构造函数需要外部传递参数才能进行初始化时,派生类必须显式定义构造函数,为基类传递参数;基类如果不需要传递或者可以不传递参数,派生类可以不用显式定义构造函数
11.struct 的成员默认是公有的,class 的成员默认是私有的,class继承默认是私有继承,struct 继承默认是公有继承



