C++小题(十一)

/*
下列 C 代码中,不属于未定义行为的有:______。
正确答案: C   

A int i=0;i=(i++);
B char *p=”hello”;p[1]=’E’
C char *p=”hello”;char ch=*p++
D int i=0;printf(“%d%d\n”,i++ i--)
E 都是未定义行为
F 都不是未定义行为
*/

/*
以下选项中不属于C语言标识符的是?
正确答案: A   

常量
用户标识符
关键字
预定义标识符

C语言的标识符包括:用户标识符,关键字和预定义标识符
*/

/*
下面这段程序的输出是什么?
class A{
    public:
        A(){p();}
        virtual void p(){print("A")}
        virtual ~A(){p();}
};
class B:public A{
    public:
        B(){p();}
        void p(){print("B")}
        ~B(){p();}
};
int main(int, char**){
        A* a=new B();
        delete a;
}

正确答案: D   你的答案: D (正确)

AABB
BBAA
ABAB
ABBA

调用基类,在调用子类的构造函数,析构的时候先调用子类的,在调用基类的。
a类中的p()函数是虚函数。但是此时构造函数没有完全初始化,所以还是调用基类自己的p()函数,同理子类的虚函数
*/

/*
在C++,下列哪一个可以做为对象继承之间的转换()
正确答案: C   

static_cast
reinterpret_cast
dynamic_cast
const_cast

reinterpret_cast:一个指针转化为其他类型的指针时,不做类型检测,操作结果是一个指针指向另一个指针的值的二进制拷贝;
static_cast:允许执行隐式转换和相反的转换操作,父类转换为子类是强制转换Son *son=static_cast(father),而子类转换为父类就是隐式转换;
dynamic_cast:用于对象的指针和引用,当用于多态类型转换时,允许隐式转换及相反的过程中,
			与static_cast的不同之处在于,在相反的转换过程中,dynamic_cast会检测操作的有效性,
			如果返回的不是被 请求的 有效完整对象,则返回null,反之返回这个有效的对象,
			如果是引用返回无效时则会抛出bad_cast异常;
const_cast:这个转换操作会操纵传递对象的const属性,或者设置或者移除该属性。
*/

/*
#include<iostream>
using namespace std;
int main(){
	int a=0,b=0,c=0;
	a=(b++,c++);
	cout<<a<<b<<c;
}
输出0.而c++返回的c原来的值,之后再加1 ,所以仍然是0 
*/

/*
#include<file.h> 与 #include "file.h"的区别?
正确答案: B   

A前者首先从当前工作路径搜寻并引用file.h,而后者首先从Standard Library的路径寻找和引用file.h
B前者首先从Standard Library的路径寻找和引用file.h,而后者首先从当前工作路径搜寻并引用file.h
C两者都是首先从Standard Library的路径寻找和引用file.h
D两者都是首先从当前工作路径搜寻并引用file.h

<>  :表示只从从标准库文件目录下搜索,对于标准库文件搜索效率快。
""首先在当前目录下寻找,如果找不到,再到系统目录中寻找。 这个用于include自定义的头文件,让系统优先使用当前目录中定义的。
*/

/*
以下代码打印的结果是(假设运行在 i386 系列计算机上):
struct st_t  
{
  int status;
  short *pdata;
  char errstr[32];
};
 
st_t st[16];
char *p = (char *)( st[2].errstr + 32 );
printf( "%d", ( p - (char *)(st) ) );
正确答案: C   你的答案: C (正确)

A 32
B 114
C 120
D 1112

sizeof(st_t)是40
st [ 2 ]. errstr + 32 相当于st[3]的地址
( p - ( char *)( st ) 是 st[3]的地址减去 st的首地址。
*/

/*
有以下程序
#include < stdio. h > 
main ( )
{ 
    int a [ 3 ] [ 4 ] = { 1,3,5,7,9,11,13,15,17,19,21,23 } , (*p) [4] = a , i , j , k = 0 ;
    for ( i =0 ; i < 3 ; i + + )
    for ( j =0 ; j < 2 ; j + + ) 
        k = k + * ( * ( p+i )+j );
    printf ( "%d" , k );
}
程序运行后的输出结果是?
正确答案: B   

40
60
80
100

int (*p)[4]= a;说明 p是一个指针数组,长度为4,存储的是二维数组每行的地址。
p指向a的首地址 &a[0][0].
*(p+i) 相当于p[i],p[i]存储的是二维数组a的i行的数据地址。即p[i]=&a[i][0];
*(p+i)+j 存储的是a[i][j]的地址。*(*(p+i)+j)即是a[i][j]的值。
根据i j循环。i<3,j<2,即是取二维数组三行的前两列的值的总和。
1+3+9+11+17+19=60
*/

/*
class A
{
public:
    A()
    {
        printf("A ");
    }
    ~A()
    {
        printf("deA ");
    }
};
 
class B
{
public:
    B()
    {
        printf("B ");
    }
    ~B()
    {
        printf("deB ");
    }
};
 
class C: public A, public B
{
public:
    C()
    {
        printf("C ");
    }
    ~C()
    {
        printf("deC ");
    }
};
int main()
{
    A *a = new C();
    delete a;
    return 0;
}

正确答案: A   你的答案: A (正确)

A B C deA
C A B deA
A B C deC
C A B deC

构造函数的执行先执行父类,再执行子类。析构顺序相反

A B的析构函数不是虚函数,所以不会执行子类的虚函数。 
*/

/*
在小端序的机器中,如果 
union X{
    int x;
    char y[4];
};
如果:
X a;
a.x=0x11223344;//16 进制 则:______
正确答案: D   你的答案: D (正确)

a.y[0]=11
a.y[1]=11
a.y[2]=11
a.y[3]=11
a.y[0]=22
a.y[3]=22

union内的类型共享一段内存,大小按照最大的类型算。
小端是数据地位存储在内存低位,在四个字节上按照从高到低排列0x11223344。所以y[0]=0x44 y[1]=0x33..... 
*/

/*
以下关于STL的描述中,____是错的。
正确答案: C   

A STL容器是线程不安全的
B 当容量不够时,vector内部内存扩展方式是翻倍
C std::sort是稳定排序
D std::bitset不是一个STL容器
E std::stack默认是用deque实现的
F std::string中可以存储多个’\0’字符

A:“很多程序员希望STL实现是完全线程安全的“。所以不安全。
B:vector的存在可以使开发者不必关心内存的申请和释放。但是,vector的一个缺点就是它的内存分配是按照2的倍数分配内存的。
C:错误。要知道 std::sort 不是稳定的排序算法,它不保证“相等”元素的相对位置,使用 std::stable_sort 来保证这一点
D:STL的容器可以分为以下几个大类: 
一:序列容器, 有vector, list, deque, string.
二 : 关联容器,     有set, multiset, map, mulmap, hash_set, hash_map, hash_multiset, hash_multimap
三: 其他的杂项: stack, queue, valarray, bitset
E:正确。堆栈是一个线性表,插入删除操作都在一端进行,deque是先进先出的,操作原理和stack是一样的
*/

/*
#include<iostream>
#include<string>
using namespace std;

string& func1(const string& a){
	return a;//出错,需要的返回类型为非const引用,而返回的对象本身却是const,出错 
}
void func2(string& a){}

int main(){
	const string a="abc";
	func2(a);//出错,传递一个const对象给非const引用,出错 
}
*/

/*
在Windows编程中下面的说法正确的是:
正确答案: B   

A两个窗口,他们的窗口句柄可以是相同的
B两个窗口,他们的处理函数可以是相同的
C两个窗口,他们的窗口句柄和窗口处理函数都不可以相同.

窗口句柄就相当于一个身份证,是一个整数,如果两个窗口的句柄相同的话,就会出现消息不知道传给哪个窗口了。
*/

/*
下面有关类的静态成员和非静态成员,说法错误的是? 
正确答案: C   你的答案: C (正确)

A静态成员存在于内存,非静态成员需要实例化才会分配内存
B非静态成员可以直接访问类中静态的成员
C静态成员能访问非静态的成员
D非静态成员的生存期决定于该类的生存期,而静态成员则不存在生存期的概念

因为静态成员存在于内存,非静态成员需要实例化才会分配内存,所以静态成员函数不能访问非静态的成员。
因为静态成员存在于内存,所以非静态成员函数可以直接访问类中静态的成员
*/

/*
已知fun(int)是类Test的公有成员函数,p是指向成员函数fun()的指针,采用( )是正确的。
正确答案: D   你的答案: D (正确)

A p=fun
B p=Test::fun()
C p=fun()
D p=Test::fun

对成员函数指针的调用
    指向公有非静态的成员函数,调用时必须创建一个对象。
class Container{
    public:
    void print(){
        printf("printf()");
    }
};

int main()
{
    void (Container::*p)();//指明是指向成员函数的指针
    p = &Container::print;
    Container c;
    (c.*p)();//通过对象调用 
    return 0;
}

指向静态函数
class Container{
    public:
    static void print(){
        printf("printf()");
    }
};
int main()
{
    void (*p)();
    p = &Container::print;
    p();
    return 0;
}
*/

/*
现有一个程序如下:
class A
{
public:
    void f()
    {
        cout << “A::f()”;
    }
};
class B
{
public:
    void f()
    {
cout << “B: f()”;
    }
    void g()
    {
cout << “B: g()”;
    }
};
class C : public A, public B
{
public:
    void g()
    {
        cout << ”C::g()”;
    }
    void h()
    {
        cout << ”C::h()”;
        f(); //语句1
    }
};
void main()
{
    C obj;
    obj.f();    //语句2
    obj.A::f(); //语句3
    obj.B::f(); //语句4
    obj.g(); //语句5
}

则编译时会产生错误的语句有
正确答案: A B   你的答案: A B (正确)

语句1
语句2
语句3
语句4
语句5

语句1,2由于出现歧义,所以编译的时候会报错,假如把这两行注释起来,再编译就通过了,结果为A::f() B: f() C::g(),
注意最后输出的是 C::g(),这是因为在类B和C中g()函数同名,并且父类B中g()不是虚函数,这时隐藏了父类B中的g()函数,
仅调用子类C中的g()函数。
*/

/*
如何引用一个已经定义过的全局变量?
正确答案: B   你的答案: B (正确)

A用引用头文件的方式
B用extern关键字方式
C使用static方式
*/

/*
函数原型:void *calloc(size_t n, size_t size);
功 能: 在内存的动态存储区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。
与malloc的区别:calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据。
*/

/*
写出下列程序所有可能的运行结果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int a;
int b;
int c;
 
void F1()
{
    b = a * 2;
    a = b;
}
 
void F2()
{
    c = a + 1;
    a = c;
}
 
main()
{
    a = 5;
    //Start F1,F2 in parallel
    F1();
    F2();
    printf("a=%d\n", a);
}

正确答案: A B C   你的答案: A (错误)

11
6
12
以上都不正确
*/

/*
写出下列程序所有可能的运行结果。
int a;
int b;
int c;
 
void F1()
{
    b = a * 2;
    a = b;
}
 
void F2()
{
    c = a + 1;
    a = c;
}
 
main()
{
    a = 5;
    //Start F1,F2 in parallel
    F1();
    F2();
    printf("a=%d\n", a);
}

正确答案: A B C   你的答案: A (错误)

A 11
B 6
C 12
D 以上都不正确

先F1(),后F2(),得A
先F2(),后F1(),得C
先c = a + 1,再F1(),后a = c,得B
*/

/*
下面哪个指针表达式可以用来引用数组元素a[i][j][k][l]()
正确答案: B   你的答案: B (正确)

A (((a+i)+j)+k)+l)
B *(*(*(a+i)+j)+k)+l)
C (((a+i)+j)+k+l)
D ((a+i)+j+k+l)

除了一维数组,其他高维数组都有a=*a,表示数组的首地址。而在一维数组int a[N]中,a代表数组首地址,*a代表数组第一个元素的值。
*/

/*
关于内联函数说法错误的是:
正确答案: C   你的答案: C (正确)

A不是任何一个函数都可定义成内联函数
B内联函数的团数休内不能含有复杂的结构控制语句
C递归函数可以被用来作为内联函数
D内联图数一般适合于只有1~5行语句的小函数
*/

/*
下面有关vector和list的区别,描述错误的是?
正确答案: D   你的答案: D (正确)

vector拥有一段连续的内存空间,因此支持随机存取,如果需要高效的随即存取
list拥有一段不连续的内存空间,如果需要大量的插入和删除,应该使用list
vector<int>::iterator支持“+”、“+=”、“<”等操作符
list<int>::iterator则不支持“+”、“+=”、“<”等操作符运算,但是支持了[ ]运算符
*/

/*
下面不是面向对象的基本原则的是?
正确答案: C   你的答案: C (正确)

A单一职责原则(Single-Resposibility Principle)
B开放封闭原则(Open-Closed principle)
C抽象类原则(Abstract-Class principle)
D依赖倒置原则(Dependecy-Inversion Principle)
E接口隔离原则(Interface-Segregation Principle)

五个基本原则: 
单一职责原则(Single-Resposibility Principle):一个类,最好只做一件事,只有一个引起它的变化。
			单一职责原则可以看做是低耦合、高内聚在面向对象原则上的引申,将职责定义为引起变化的原因,
			以提高内聚性来减少引起变化的原因。 
开放封闭原则(Open-Closed principle):软件实体应该是可扩展的,而不可修改的。也就是,对扩展开放,对修改封闭的。

Liskov替换原则(Liskov-Substituion Principle):子类必须能够替换其基类。这一思想体现为对继承机制的约束规范,
			只有子类能够替换基类时,才能保证系统在运行期内识别子类,这是保证继承复用的基础。 
依赖倒置原则(Dependecy-Inversion Principle):依赖于抽象。具体而言就是高层模块不依赖于底层模块,二者都同依赖于抽象;
			抽象不依赖于具体,具体依赖于抽象。 
接口隔离原则(Interface-Segregation Principle):使用多个小的专门的接口,而不要使用一个大的总接口
*/

/*
*/

/*
*/

/*
*/

/*
*/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值