C++习题记录-牛客网

下面哪些调用转换支持可变长度参数 cdecl
会导致用户进程从用户态切换到内核的操作是   
a.  系统调用 b.  异常 c.  外围设备的中断 
面向对象的基本原则   
单一职责原则(Single-Resposibility Principle) 
开放封闭原则(Open-Closed principle) 
依赖倒置原则(Dependecy-Inversion Principle) 
接口隔离原则(Interface-Segregation Principle) 
用户双击鼠标时产生的消息序列,下面正确的是() 
WM_LBUTTONDOWN,WM_LBUTTONUP,WM_LBUTTONDBLCLK,WM_LBUTTONUP
main 主函数执行完毕后,是否可能会再执行一段代码,给出说明?
答案:可以,可以用_onexit 注册一个函数,它会在main 之后执行int fn1(void), fn2(void), fn3(void), fn4 (void);
如何判断一段程序是由C 编译程序还是由C++编译程序编译的?
#ifdef __cplusplus
    cout<<"c++";
#else
    cout<<"c";
#endif

STL中vector的实现原理 (衍生:Map, Set等实现原理) 如果要实现一个多线程(非MFC)程序, 选择多线程CRT, 创建线程的时候应该用CreateThread还是_beginthreadex()?
如果在代码中有使用标准C运行库中的函数时,尽量使用 _beginthreadex() 来代替 CreateThread(),_beginthreadex()比较于 CreateThread()有更高的线程安全性,不会造成多个线程共用同一个全局变量的情况
vector的数据安排以及操作方式,与array非常相似。两者的唯一区别在于空间的运用的灵活性。array是静态空间,一旦配置了就不能改变;要换个大(或小)一点的房子,可以,一切琐细都得由客户端自己来:首先配置一块新空间,然后将元素从旧址一一搬往新址,再把原来的空间释还给系统。vector是动态空间,随着元素的加入,它的内部机制会自行扩充空间以容纳新元素。因此,vector的运用对于内存的合理利用与运用的灵活性有很大的帮助,我们再也不必因为害怕空间不足而一开始要求一个大块头的array了,我们可以安心使用array,吃多少用多少。 
      vector的实现技术,关键在于其对大小的控制以及重新配置时的数据移动效率。一旦vector的旧有空间满载,如果客户端每新增一个元素,vector的内部只是扩充一个元素的空间,实为不智。因为所谓扩充空间(不论多大),一如稍早所说,是”  配置新空间/数据移动/释还旧空间  “的大工程,时间成本很高,应该加入某种未雨绸缪的考虑。稍后我们便可看到SGI vector的空间配置策略了。 
      另外,由于  vector维护的是一个连续线性空间,所以vector支持随机存取   
      注意:vector动态增加大小时,并不是在原空间之后持续新空间(因为无法保证原空间之后尚有可供配置的空间),而是以原大小的两倍另外配置一块较大的空间,然后将原内容拷贝过来,然后才开始在原内容之后构造新元素,并释放原空间。因此,  对vector的任何操作,一旦引起空间重新配置,指向原vector的所有迭代器就都失效了  。这是程序员易犯的一个错误,务需小心。
float x 与“零值”比较的if语句为?
</pre><pre name="code" class="cpp"><div style="font-size: 16.3636360168457px; widows: auto; color: rgb(102, 102, 102); font-family: arial, STHeiti, 'Microsoft YaHei', 宋体; line-height: 28px;">float x;</div><div style="font-size: 16.3636360168457px; widows: auto; color: rgb(102, 102, 102); font-family: arial, STHeiti, 'Microsoft YaHei', 宋体; line-height: 28px;">if(x>-0.0000001 && x<0.0000001)</div>


10 
class A
{
        int a;
        short b;
        int c;
        char d;
};
class B
{
        double a;
        short b;
        int c;
        char d;
};
在32位机器上用gcc编译以上代码,求sizeof(A),sizeof(B)分别是多少。 16 24
根据以下条件进行计算:
1、  结构体的大小等于结构体内最大成员大小的整数倍
2、  结构体内的成员的首地址相对于结构体首地址的偏移量是其类型大小的整数倍,比如说double型成员相对于结构体的首地址的地址偏移量应该是8的倍数。
3、  为了满足规则1和2编译器会在结构体成员之后进行字节填充!
11 有哪几种情况只能用intialization list 而不能用assignment?
当类中含有const成员变量、基类无默认构造函数时,有参的构造函数都需要初始化表、当类中含有reference成员变量
12 391个汉字在UTF-16和UTF-8情况下分别呢占据多少空间  
784 bytes in UTF-16 encoding、1176 bytes in UTF-8 encoding
如果只是论一个汉字占用的字节数,那么 UTF-8 占用3个字节, UTF-16 占用2个字节。但是如果存储文本的话,需要在文本使用 EF BB BF 三个字节表示使用 UTF-8 编码,使用 FE FF 表示使用 UTF-16 编码。
UTF-16 固定表示两个字节表示一个字符,不管是字母还是汉字; UTF-8 使用 1- 3 个字节表示一个字符
13 一张1024×640分辨率的图片,假定每个像素用16位色彩表示,用位图文件(bitmap)格式存储,则这张图片文件需要占用多大的存储空间____。
1024*640*16 bit = 1024*640*16/8 B = 1024*640*16/8/1024 KB = 1280KB
14 如何定义一个只能在堆上(栈上)生成对象的类?
1、只能在堆上生成对象:将析构函数设置为私有
原因:C++是静态绑定语言,编译器管理栈上对象的生命周期,编译器在为类对象分配栈空间时,会先检查类的析构函数的访问性。若析构函数不可访问,则不能在栈上创建对象。

2、只能在栈上生成对象:将new 和 delete 重载为私有
原因:在堆上生成对象,使用new关键词操作,其过程分为两阶段:第一阶段,使用new在堆上寻找可用内存,分配给对象;第二阶段,调用构造函数生成对象。
将new操作设置为私有,那么第一阶段就无法完成,就不能够再堆上生成对象。
15 C++中static关键字作用有哪些?
1、隐藏:当同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。
static可以用作函数和变量的前缀,对于函数来讲,static的作用仅限于隐藏.
2、static的第二个作用是保持变量内容的持久:存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。
共有两种变量存储在静态存储区:全局变量和static变量,只不过和全局变量比起来,static可以控制变量的可见范围,
说到底static还是用来隐藏的。虽然这种用法不常见
3、static的第三个作用是默认初始化为0(static变量)
4、C++中的作用
1)不能将静态成员函数定义为虚函数。   
2)静态数据成员是静态存储的,所以必须对它进行初始化。 (程序员手动初始化,否则编译时一般不会报错,但是在Link时会报错误)  
3)静态数据成员在<定义或说明>时前面加关键字static。    
16 C++中成员函数能够同时用static和const进行修饰? 
否,因为static表⽰示该函数为静态成员函数,为类所有;而const是用于修饰成员函数的,两者相矛盾
17 下列运算符,在C++语言中不能重载的是() 
.*和::和sizeof
18 std::vector::iterator重载了下面哪些运算符? 
++和*(前置)和==
19 定义一个函数指针,指向的函数有两个int形参并且返回一个函数指针,返回的指针指向一个有一个int形参且返回int的函数? 
int (*(*F)(int, int))(int)
20 声明一个指向含有10个元素的数组的指针,其中每个元素是一个函数指针,该函数的返回值是int,参数是int*,正确的是() 
int (*(*p)[10])(int *)
21 使用 char* p = new char[100]申请一段内存,然后使用delete p释放,有什么问题?
C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]。 
关于 new[] 和 delete[],其中又分为两种情况:(1) 为基本数据类型分配和回收空间;(2) 为自定义类型分配和回收空间。
基本类型的对象没有析构函数,所以回收基本类型组成的数组空间用 delete 和 delete[] 都是应该可以的;但是对于类对象数组,只能用 delete[]。
所以一个简单的使用原则就是:new 和 delete、new[] 和 delete[] 对应使用。
22 给出以下定义,下列哪些操作是合法的?
1
2
const char *p1 = “hello”;
char *const p2 = “world”;
  • p1++;
  • p1[2] = ‘w’;
  • p2[2] = ‘l’;
  • p2++;
23 要对绝对地址0x100000赋值,我们可以用 (unsigned int*)0x100000 = 1234; 那么要是想让程序跳转到绝对地址是0x100000去执行,应该怎么做?
*((void (*)( ))0x100000 ) ( ); 首先要将0x100000强制转换成函数指针,即: (void (*)())0x100000 然后再调用它: *((void (*)())0x100000)(); 用typedef可以看得更直观些: typedef void(*)() voidFuncPtr; *((voidFuncPtr)0x100000)();
24 什么函数不能声明为虚函数?静态成员函数 内联函数 构造函数
25 下面有关回调函数的说法,错误的是?
回调函数本身可以是全局函数 ,静态函数和某个特定的类的成员函数所谓的回调函数,就是预先在系统的对函数进行注册,让系统知道这个函数的存在,以后,当某个事件发生时,再调用这个函数对事件进行响应。 定义一个类的成员函数时在该函数前加CALLBACK即将其定义为回调函数,函数的实现和普通成员函数没有区别
26 一个双目运算符作为类的成员函数重载时,重载函数的参数表中有()个参数。
重载为类成员函数时,类本身是该双目运算符的一个参数,所以还需要一个参数,如果重载为友元函数则需要两个参数
27 下列关于虚函数的说法正确的是() 
静态函数不可以是虚函数 虚函数可以声明为inline 【由于类的构造次序是由基类到派生类,所以在构造函数中调用虚函数,这个虚函数不会呈现出多态; 相反,类的析构是从派生类到基类,当调用继承层次中某一层次的类的析构函数时往往意味着其派生类部分已经析构掉,所以也不会呈现出多态】【虚函数可以声明为inline,但是编译器会忽略inline属性
28 以下关于内联函数,说法正确的是: 
一般用于加快程序执行速度 可能减小可执行文件大小 可能增加可执行文件大小  如果不内联展开函数体,编译器可能会要产生更多代码来压入/弹出寄存器内容和参数。对于很小的函数来说会是这样。如果优化器能够通过顺序集成消除大量冗余代码的话,那么对大函数也会起作用(也就是说,优化器能够使大函数变小)。
29 
friend int f1(A &); 传入f1(0)则为错误:非常量的引用必须为左值,常量的引用则不必:
friend int f2(const A &); 传入f2(0)则为正确。
30 
class A
{
    public:
        A()
        {
            printf(“0”);
        }
        A(int a)
        {
            printf(“1”);
        }
        A& operator=(const A& a)
        {
            printf(“2”);
            return*this;
        }
}
int main()
{
    A al;
    al=10;
}

则程序输出是:012
A a1; //调用A默认构造函数
a1=10; //类型不匹配,调用构造函数A(int)进行隐式转化,之后将引用传给operator=()
31 下面有关函数模板和类模板的说法正确的有?
函数模板的实例化是由编译程序在处理函数调用时自动完成的、类模板的实例化必须由程序员在程序中显式地指定、函数模板针对仅参数类型不同的函数、类模板针对仅数据成员和成员函数类型不同的类
32 下列关于模板的说法正确的是
A:下面列举的几种情况不能省略模板实参:
1)从模板函数实参表获得的信息有矛盾之处。
2)需要获得特定类型的返回值,而不管参数的类型如何。
3)虚拟类型参数没有出现在模板函数的形参表中。
4)函数模板含有常规形参。
B:类模板与模板类的概念

⑴ 什么是类模板 一个类模板(也称为类属类或类生成类)允许用户为类定义一种模式,使得类中的某些数据成员、默写成员函数的参数、某些成员函数的返回值,能够取任意类型(包括系统预定义的和用户自定义的)。

  如果一个类中数据成员的数据类型不能确定,或者是某个成员函数的参数或返回值的类型不能确定,就必须将此类声明为模板,它的存在不是代表一个具体的、实际的类,而是代表着一类类。

⑵ 模板类是类模板实例化后的一个产物。可以从类模板派生出新的类,既可以派生类模板,也可以派生非模板类。
类模板的重点是模板。表示的是一个模板,专门用于产生类的模子。模板类的重点是类。表示的是由一个模板生成而来的类。 
C:类模板有三种类型模板参数:类型模板参数、无类型模板参数和模板模板参数(以模板作为模板的参数)。并不局限于虚拟类型,非虚拟类型也可以作为类模板参数。
D,类模板是为了生成类的,所以其函数也是模板函数,用来在生成模板类的时候生成相应的函数

你可能感兴趣的:(C++习题记录-牛客网)