IT公司笔试面试题系列(二)

来源:百度文库 编辑:神马文学网 时间:2021/12/01 05:19:50
IT公司笔试面试题系列(二)作者:邹博伟

1.假设现有一个单向的链表,但是只知道只有一个指向该节点的指针p,并且假设这个节点不是尾节点,试编程实现删除此节点
参考:将下一个节点的内容复制到本节点上,然后删除下一个节点。

2.字符指针、浮点数指针、以及函数指针这三种类型的变量哪个占用的内存最大?为什么?
答案:指针变量也占用内存单元,而且所有指针变量占用内存单元的数量都是相同的。就是说,不管是指向何种对象的指针变量,它们占用内存的字节数都是一样的,并且要足够把程序中所能用到的最大地址表示出来(通常是一个机器字长)。

3.类ClassB从ClassA派生,那么ClassA *a = new ClassB(…); 试问该表达是否合法?为什
么?
答案:派生类的指针指向基类的对象是错误的,不能通过编译的;基类的指针可以指向派生类的对象,调用派生类的函数。

4.如果ClassA中定义并实现虚函数int func(void),ClassB中也实现该函数,那么上述变量

a->func()将调用哪个类里面的函数?如果int func(void)不是虚函数,情况又如何?为什么?
答案:第一问调用的是B的。第二问调用A的。
虚函数的一个典型应用,虚函数只能借助于指针或者引用来达到多态的效果
如果没有定义成虚函数:------
class A{
public:
void print(){ cout<<”This is A”<};

class B:public A{
public:
void print(){ cout<<”This is B”<};

int main(){   //为了在以后便于区分,我这段main()代码叫做main1
A a;  B b;
A* p1=&a;
A* p2=&b;
p1->print();
p2->print();
}
结果是两个This is A
如果定义成虚函数:---------
class A{
public:
virtual void print(){ cout<<”This is A”< //现在成了虚函数了
};

class B:public A{
public:
void print(){ cout<<”This is B”< //这里不需要在前面加上关键字virtual,只需在把基类的成员函数设为virtual,其派生类的相应的函数也会自动变为虚函数
};
再运行main输出的结果就是This is A和This is B。

5.char **p, a[16][8];  问:p=a是否会导致程序在以后出现问题?为什么?
参考: 这个不会导致出现问题,但是要注意p的使用,如a[1][2] 等价的为 *(*(p+1)+2)而不是*(p+11),
会的,这样会出现编译错误  正确的是:char a[5][5]; char (*p)[5]; p=a;

6.应用程序在运行时的内存包括代码区和数据区,其中数据区又包括哪些部分?
参考:对于一个进程的内存空间而言,可以在逻辑上分成3个部份:代码区,静态数据区和动态数据区。动态数据区一般就是“堆栈”。栈是一种线性结构,堆是一种链式结构。进程的每个线程都有私有的“栈”。全局变量和静态变量分配在静态数据区,本地变量分配在动态数据区,即堆栈中。程序通过堆栈的基地址和偏移量来访问本地变量。
7.用<<,>>,|,&实现一个WORD(2个字节)的高低位交换
int main()
{
    unsigned short a = 0xABCD;
    unsigned short  ;
    unsigned short c, d;
    b = (a  <<  8)&0xff00;  
   (a  >>  8)&0x00ff;
   c;
    printf("n%x",b);
    printf("n%x",c);
    printf("n%x",d);
    return  0;
}
结果是  CDAB  2俩个字节是16位  前八位为高位  后八位为低位  然后结合

8.编写一个函数,函数接收一个字符串,是由十六进制数组成的一组字符串,函数的功能是把接到的这组字符串转换成十进制数字.并将十进制数字返回.
答案:
BOOL HexToDec( LPCTSTR shex, int& idec )   

  
    int i, mid;   
    int len lstrlen( shex );   
    if( len > 8   
         return FALSE;   
    mid 0; idec 0;   
    for( i=0;i  
      
        if( shex[i]>='0'&&shex[i]<='9'   
             mid = shex[i]-'0';   
        else if( shex[i]>='a'&&shex[i]<='f' )   
             mid shex[i] -'a' +10;   
        else if( shex[i]>='A'&&shex[i]<='F'   
             mid shex[i] -'A' +10;   
        else   
             return FALSE;   
        mid <<= ((len-i-1)<<2);   // 移位表示变为2的n次方倍
        idec =idc+mid;   
      
     return TRUE;   
}
9.写一算法检测单向链表中是否存在环(whether there is a loop in a link list), 要求算法复杂度(Algorithm's complexity是O(n)) 并只使用常数空间(space is O(c)).
注意,你只知道一个指向单向链表头的指针。链表的长度是不定的,而且环出现的地方也是不定的,环有可能在头,有可能在中间。而且要求是检测, 不能破坏环的结构.(MOTO)

答:用两个指针来遍历这个单向链表,第一个指针p1,每次走一步;第二个指针p2,每次走两步;当p2指针追上p1的时候,就表明链表当中有环路了。
int testLinkRing(Link *head)
{
  Link *t1=head,*t2=head;
  while( t1->next && t2->next)
  {
      t1 = t1->;next;
      if (NULL == (t2 = t2->next->next))
          return 0;   //无环
      if (t1 == t2)
          return 1;
   }
   return 0;
}
如果要定位环路在链表当中的开始点
发现p2和p1重合,确定了单向链表有环路了。接下来,让p2回到链表的头部,重新走,P1也继续走,每次步长都走1,那么当p1和p2再次相遇的时候,就是环路的入口了。
10.用最有效率的方法算出2乘以8等於几?
移位

11.#include “filename.h”和#include 的区别?
对于#include 编译器从标准库开始搜索filename.h;对于#include “filename.h”编译器从用户工作路径开始搜索filename.h。

12.头文件的作用是什么?
一、通过头文件来调用库功能。在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制的库即可。用户只需要按照头文件中的接口声明来调用库功能,而不必关心接口怎么实现的。编译器会从库中提取相应的代码。
二、头文件能加强类型安全检查。如果某个接口被实现或被使用时,其方式与头文件中的声明不一致,编译器就会指出错误,这一简单的规则能大大减轻程序员调试、改错的负担。

13.C++函数中值的传递方式有哪几种?
C++函数的三种传递方式为:值传递、指针传递和引用传递。

14.内存的分配方式的分配方式有几种?
答:一、从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量。
二、在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
三、从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。

15.C++里面是不是所有的动作都是main()引起的?如果不是,请举例.
比如全局变量的初始化,就不是由main函数引起的
举例: class A{};   
       a;   //a的构造函数限执行   
       int main() {}