您的位置:首页 > 职场人生

IT公司笔试面试题系列

2013-05-06 09:53 176 查看
原文地址:http://blog.sina.com.cn/s/blog_4ba5906a0100bejm.html

1.假设现有一个单向的链表,但是只知道只有一个指向该节点的指针p,并且假设这个节点不是尾节点,试编程实现删除此节点

参考:将下一个节点的内容复制到本节点上,然后把后面的节点内容统一向前移动,最后删除尾节点。

void deleteItem(Node *p)

{

While(NILL!=p->next)

{

p->item=p->next->item;

p=p->next;

}

Delete p;

P=NULL;

}

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”<<endl;}

};

class B:public A{

public:

void print(){ cout<<”This is B”<<endl;}

};

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”<<endl;} //现在成了虚函数了

};

class B:public A{

public:

void print(){ cout<<”This is B”<<endl;} //这里不需要在前面加上关键字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 b ;

unsigned short c, d;

b = (a << 8)&0xff00;

c = (a >> 8)&0x00ff;

d = b | 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<len;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 +=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 <filename.h>的区别?

对于#include <filename.h>编译器从标准库开始搜索filename.h;对于#include “filename.h”编译器从用户工作路径开始搜索filename.h。

12.头文件的作用是什么?

一、通过头文件来调用库功能。在很多场合,源代码不便(或不准)向用户公布,只要向用户提供头文件和二进制的库即可。用户只需要按照头文件中的接口声明来调用库功能,而不必关心接口怎么实现的。编译器会从库中提取相应的代码。

二、头文件能加强类型安全检查。如果某个接口被实现或被使用时,其方式与头文件中的声明不一致,编译器就会指出错误,这一简单的规则能大大减轻程序员调试、改错的负担。

13.C++函数中值的传递方式有哪几种?

C++函数的三种传递方式为:值传递、指针传递和引用传递。

14.内存的分配方式的分配方式有几种?

答:一、从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量。

二、在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

三、从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。

15.C++里面是不是所有的动作都是main()引起的?如果不是,请举例.

比如全局变量的初始化,就不是由main函数引起的

举例: class A{};

A a; //a的构造函数限执行

int main() {}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: