1.inline只适合函数体内代码简单的函数使用,不能包含复杂的结构控制语句例如while switch,并且内联函数本身不能是递归函数;
2,在C++中,对于有virtual的类,其sizeof会比正常情况多处4个字节。既在类的最开始四个字节,放的是VTABLE表的地址(void *类型)。而在VTABLE中,所有虚函数是以指针数组的形式存放。 对于派生的类,即使没有重载基类的虚函数,也会在其VTABLE占用一格。造成空间上的浪费。非虚基类没有VTABLE,VTABLE是在构造的时候编译器生成的。
3,线程和进程:进程是操作系统资源分配的最小单位,线程是CPU运行的最小单位。
4,static有什么用途:1.限制变量的作用域 2.设置变量的存储域;C/C++中Static的作用的第一条也是最重要的一条:隐藏。当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。如果加了static,就会对其它源文件隐藏。static的第二个作用是保持变量内容的持久。
5,引用与指针有什么区别?
引用就是某个目标变量的“别名”,对引用的操作就是对目标变量的操作。
1) 引用必须被初始化,指针不必。2) 引用初始化以后不能被改变,指针可以改变所指的对象。3)不存在指向空值的引用,但是存在指向空值的指针。
6,全局变量储存在静态数据区,局部变量在堆栈
7,什么是平衡二叉树:左右子树都是平衡二叉树 且左右子树的深度差值的绝对值不大于1;
8,堆栈溢出一般是由什么原因导致的:没有回收垃圾资源;
9,构造函数为什么不能声明为虚函数?1. 从存储空间角度,虚函数对应一个 指向vtable虚函数表的指针 ,这大家都知道,可是这个指向vtable的 指针 其实是 存储在对象的内存空间 的。问题出来 了,如果构造函数是虚的,就需要 通过 vtable来调用 ,可是对象还没有实例化,也就是 内存空间还没有 ,怎么找vtable呢?所以构造函数不能是虚函数。2. 从使用角度, 虚函数主要用于在信息不全 的情况下,能使 重写的函数 得到对应的调用。 构造函数本身就是要初始化实例 ,那使用 虚函数也没有实际意义 呀。所以构造函数没有必要是虚函数。虚函数的 作用 在于 通过父类的指针 或者引用来调用它的时候能够 变成调用子类的那个成员函数 。而构造函数 是在创建 对象时自动调用 的,不可能通过 父类的指针或者引用去调用 ,因此也就规定构造函数不能是虚函数。3. 构造函数不需要是虚函数,也不允许是虚函数,因为创建一个对象时我们总是要明确指定对象的类型,尽管我们可能通过实验室的基类的指针或引用去 访问它但析构却不一定,我们往往通过基类的指针来销毁对象。这时候如果析构函数不是虚函数,就不能正确识别对象类型从而不能正确调用析构函数。4. 从实现上看, vbtl在构造函数调用后才建立 ,因而构造函数不可能成为虚函数从实际含义上看,在调用构造函数时还不能确定对象的真实类型(因为子 类会调父类的构造函数);而且构造函数的作用是提供初始化,在对象生命期只执行一次,不是对象的动态行为,也没有必要成为虚函数。5. 当一个构造函数被调用时, 它做的首要的事情之一是初始化它的VPTR 。因此,它只能知道它是“当前”类的,而完全忽视这个对象后面是否还有继承者。 当编译器为这个构造函数产生代码时,它是为这个类的构造函数产生代码——既不是为基类,也不是为它的派生类(因为类不知道谁继承它)。所以它使用 的VPTR必须是对于这个类的VTABLE。而且,只要它是最后的构造函数调用,那么在这个对象的生命期内,VPTR将保持被初始化为指向这个VTABLE, 但 如果接着还有一个更晚派生的构造函数被调用,这个构造函数又将设置VPTR指向它的 VTABLE,等.直到最后的构造函数结束。VPTR的状态是由被最后调 用的构造函数确定的。这就是为什么构造函数调用是从基类到更加派生类顺序的另一个理由。但是,当这一系列构造函数调用正发生时,每个构造函数都已 经设置VPTR指向它自己的VTABLE。如果函数调用使用虚机制,它将只产生通过它自己的VTABLE的调用,而不是最后的VTABLE(所有构造函数被调用 后才会有最后的VTABLE)。10,为什么基类的析构函数是虚函数?在实现多态时,当用基类指针操作派生类,在析构时防止只析构基类而不析构派生类的状况发生。
11,冒泡排序算法的时间复杂度是O(n^2)12, 写出float x 与“零值”比较的if语句。 if(x>0.000001&&x<-0.000001)13, Internet采用哪种网络协议?该协议的主要层次结构? tcp/ip -----应用层/传输层/网络层/数据链路层/物理层;14, 由C/C++编译的程序占用的 内存分为以下几个部分 ;1、栈区(stack): 由编译器自动分配释放,存放函数的参数值,局部变量等。其操作方式类似于数据结构中的栈。
2、堆区(heap): 一般由程序员分配释放(malloc/free、new/delete), 若程序员不释放,程序结束时可能由操作系统回收。注意它与数据结构 中的堆是两回事,分配方式倒是类似于链表。
3、全局区(static): 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静 态变量在相邻的另一块区域,程序结束后由系统释放。
4、文字常量区: 常量字符串就是放在这里的, 程序结束后由系统释放。
5、程序代码区: 存放函数体的二进制代码。
15,char *strcpy(char *strDest, const char *strSrc)
{
if ( strDest == NULL || strSrc == NULL)
return NULL ;
if ( strDest == strSrc)
returnstrDest ;
char *tempptr = strDest ;
while( (*strDest++ = *strSrc++) != ‘’);
return tempptr ;}16, 面向对象的三个基本特征:1)封装:将客观事物抽象成类。2)继承:实现继承(指使用基类的属性和方法而无需额外编码的能力)、可视继承(子窗体使用父窗体的外观和实现代码)、接口继承(仅使用属性和方法,实现滞后到子类实现)。3)多态:允许将子类类型的指针赋值给父类类型的指针,通过基类指针调用子类函数。17,请说出const与#define 相比,有何优点:1) const 常量有数据类型,而宏常量没有数据类型。编译器可以对前者进行类型安全检查。而对后者只进行字符替换,没有类型安全检查,并且在字符替换可能会产生意料不到的错误。2) 有些集成化的调试工具可以对const 常量进行调试,但是不能对宏常量进行调试。18,头文件的作用是什么:1)通过头文件来调用库功能。2)头文件能加强类型安全检查。
char ss[] = “0123456789″;sizeof(ss) 结果 11 //ss是数组,计算到\0位置,因此是10+1,sizeof(*ss) 结果 1 //*ss是第一个字符
char ss[100] = “0123456789″;sizeof(ss) 结果是100 //ss表示在内存中的大小 100×1intss[100] = “0123456789″;sizeof(ss) 结果 400 //ss表示再内 存中的大小 100×4
char q[]=”abc”;char p[]=”a\n”;sizeof(q),sizeof(p),strlen(q),strlen(p); 结果是 4 3 3 2
1). 并行设备的硬件寄存器(如:状态寄存器)
2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3). 多线程应用中被几个任务共享的变量
list内部使用链表,访问速度慢,但是删除数据比较快
客户端:1.socket()建立套接字2.向服务器发出连接请求,(connect)2。和服务器进行通信,send()和recv(),在套接字上写读数据,直至数据交换完毕;4closesocket()关闭套接字。
UDP:服务器端:1.创建套接字(socekt)2.将套接字绑定到本地地址和端口上(bind);3.等待接收数据(recvfrom);4.closesocket()关闭套接字。
客户端:1.创建套接字(socekt)2,向服务器端发送数据(sendto)3.closesocket()关闭套接字。