上海贝尔面试题(经典)

一、请填写BOOL , float, 指针变量 与“零值”比较的 if 语句。(10分)

请写出 BOOL flag 与“零值”比较的 if 语句。(3分)
标准答案:
    if ( flag )
    if ( !flag )如下写法均属不良风格,不得分。
if (flag == TRUE)
if (flag == 1 )
if (flag == FALSE)
    if (flag == 0)
请写出 float x 与“零值”比较的 if 语句。(4分)
标准答案示例:
const float EPSINON = 0.00001;
if ((x >= - EPSINON) && (x <= EPSINON)
不可将浮点变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”此类形式。
   
如下是错误的写法,不得分。
if (x == 0.0)
if (x != 0.0)

请写出 char *p 与“零值”比较的 if 语句。(3分)
标准答案:
    if (p == NULL)
    if (p != NULL)如下写法均属不良风格,不得分。
if (p == 0)
if (p != 0)
if (p)
    if (!)

二、以下为Windows NT下的32位C++程序,请计算sizeof的值(10分)

char str[] = “Hello” ;
char   *p = str ;
int     n = 10;
请计算
sizeof (str ) = 6   (2分)
        
sizeof ( p ) =   4   (2分)
         
sizeof ( n ) =   4   (2分)void Func ( char str[100])
{
请计算
sizeof( str ) =   4     (2分)
}

void *p = malloc( 100 );
请计算
sizeof ( p ) = 4      (2分)


三、简答题(25分)

1、头文件中的 ifndef/define/endif 干什么用?(5分)
答:防止该头文件被重复引用。

2、#i nclude <filename.h>   和 #i nclude “filename.h” 有什么区别?(5分)
答:对于#i nclude <filename.h> ,编译器从标准库路径开始搜索 filename.h
    对于#i nclude “filename.h” ,编译器从用户的工作路径开始搜索 filename.h

3、const 有什么用途?(请至少说明两种)(5分)
答:(1)可以定义 const 常量
(2)const可以修饰函数的参数、返回值,甚至函数的定义体。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。

4、在C++ 程序中调用被 C编译器编译后的函数,为什么要加 extern “C”? (5分)
答:C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C语言的不同。假设某个函数的原型为: void foo(int x, int y);
该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。
C++提供了C连接交换指定符号extern“C”来解决名字匹配问题。
       
5、请简述以下两个for循环的优缺点(5分)

for (i=0; i<N; i++)
{
if (condition)
    DoSomething();
else
    DoOtherthing();
}if (condition)
{
for (i=0; i<N; i++)
    DoSomething();
}
else
{
    for (i=0; i<N; i++)
    DoOtherthing();
}
优点:程序简洁

缺点:多执行了N-1次逻辑判断,并且打断了循环“流水线”作业,使得编译器不能对循环进行优化处理,降低了效率。优点:循环的效率高

缺点:程序不简洁



四、有关内存的思考题(每小题5分,共20分)

void GetMemory(char *p)
{
p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}

请问运行Test函数会有什么样的结果?
答:程序崩溃。
因为GetMemory并不能传递动态内存,
Test函数中的 str一直都是 NULL。
strcpy(str, "hello world");将使程序崩溃。
char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}

请问运行Test函数会有什么样的结果?
答:可能是乱码。
因为GetMemory返回的是指向“栈内存”的指针,该指针的地址不是 NULL,但其原现的内容已经被清除,新内容不可知。
void GetMemory2(char **p, int num)
{
*p = (char *)malloc(num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}
请问运行Test函数会有什么样的结果?
答:
(1)能够输出hello
(2)内存泄漏

void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str, “hello”);
free(str);   
if(str != NULL)
{
strcpy(str, “world”);
printf(str);
}
}
请问运行Test函数会有什么样的结果?
答:篡改动态内存区的内容,后果难以预料,非常危险。
因为free(str);之后,str成为野指针,
if(str != NULL)语句不起作用。


27 费波那其数列,1,1,2,3,5……编写程序求第十项。可以用递归,也可以用其他方法,但要说明你选择的理由。
-------------------------------------------------------------------------------------

#i nclude <stdio.h>
#i nclude <cstdlib>

int Pheponatch(int);
int Pheponatch2(int);

int main()

{
   printf("The 10th is %d",Pheponatch2(20));
   system("pause");
   return 0;
}

//递归算法
int Pheponatch(int N)
{
    if( N == 1 || N == 2)
    {
        return 1;
    }   
    else
        return Pheponatch( N -1 ) + Pheponatch( N -2 );
}

//非递归算法
int Pheponatch2(int N)
{
    int x = 1, y = 1, temp;
    int i = 2;
    while(true)
    {
        temp = y;
        y = x + y;
        x = temp;
        i++;
        if( i == N )
        break;
    }   
    return y;
}

 


25.完成下列程序

*

*.*.

*..*..*..

*...*...*...*...

*....*....*....*....*....

*.....*.....*.....*.....*.....*.....

*......*......*......*......*......*......*......

*.......*.......*.......*.......*.......*.......*.......*.......

#i nclude <stdio.h>

#define N 8

int main()

{

   int i;

   int j;

   int k;

   ---------------------------------------------------------

   |                                     |

   |                                     |

   |                                     |

   ---------------------------------------------------------

   return 0;

}


#i nclude <stdio.h>
#i nclude <iostream.h>

#define N 8

int main()

{
   int i;
   int j;
   int k;

   for(i=N; i>=1; i--)
   {
   for(j=0; j<N-i+1; j++)
   {
   cout<<"*";
       for(k=1; k<N-i+1; k++)
   cout<<".";
   }
   cout<<"/n";
   }

   return 0;
}

 

"28 下列程序运行时会崩溃,请找出错误并改正,并且说明原因。"
// void append(int N) ;
//指针没有初始化:
//NewNode->left=NULL;
//NewNode->right=NULL;

#i nclude <stdio.h>

#i nclude <malloc.h>

 

typedef struct TNode{

TNode* left;

TNode* right;

int value;

} TNode;

 

TNode* root=NULL;

 

void append(int N);

 

int main()

{

append(63);

append(45);

append(32);

append(77);

append(96);

append(21);

append(17); // Again, 数字任意给出
return 0;

}

 

void append(int N)

{

TNode* NewNode=(TNode *)malloc(sizeof(TNode));

NewNode->value=N;

NewNode->left=NULL;
NewNode->right=NULL;

if(root==NULL)

{

root=NewNode;

return;

}

else

{

TNode* temp;

temp=root;

while((N>=temp->value && temp->left!=NULL) || (N<temp->value && temp->right!=NULL))

{

while(N>=temp->value && temp->left!=NULL)

temp=temp->left;

while(N<temp->value && temp->right!=NULL)

temp=temp->right;

}

if(N>=temp->value)

temp->left=NewNode;

else

temp->right=NewNode;

return;       

}

}

 


算法:
1.什么是NPC,NP-Hard?
2.起泡排序的时间复杂度是多少?
说出至少一个比它更快的算法;
排序的极限时间复杂度是多少?
3.有一个链表,如何判断它是一个循环链表?
如果链表是单向的呢?
如果出现循环的点可能在任意位置呢?
如果缓存空间是有限的,比如是一个常数呢?
如果只能使用2个缓存呢?
4.有一个文件,保存了若干个整数,如何以平均的概率随机得到其中的一个整数?
如果整数的个数是未知的呢?
如果整数是以字符串形式存放,如:(即如何得到随机的一个字符串)
123<enter>
-456<enter>

如果只允许便历文件一次呢?
5.用两组数据,都在内存中,对它们排序分别需要1和2分钟;那么使用两个线程一起排序,大概需要多少时间?

C/C++:
1.C与C++的异同,优劣;
2.C,C++,VC,BC,TC的区别;
3.C++中try…catch关键字的用法与优点;
4.枚举的用法,以及它与宏的区别;
5.const的用法,以及声明const变量与宏的区别;
   const的用法有四种:
   区别:const常量有数据类型, 而宏常量没有数据类型。编译器可以对前者进行类型安全检查,而对后者只能进行字符替换,没有类型
   安全检查。而且字符替换可能会带来料想不到的边界效应。
   有些集成化工具可以对const常量进行调试, 但不能对宏量进行调试。
6.C++中引用与指针的区别;
     答:1 引用实际上是所引用的对象或变量的别名,而指针是包含所指向对象或变量的地址的变量。
            2 引用在定义时必须初始化,而指针在定义时不初始化。
            3 不可以有努NULL的引用,而可以有指向NULL的指针。
            4 引用在初始化后不可以改变引用关系,而指针可以随时指向其他对象(非const指针)。
7.C++中virtual与inline的含义分别是什么?
   答:在基类成员函数的声明前加上virtual关键字,意味着将该成员函数声明为虚函数。
       inline与函数的定义体放在一起,使该函数称为内联。inline是一种用于实现的关键字,而不是用于声明的关键字。
虚函数的特点;如果希望派生类能够重新定义基类的方法,则在基类中将该方法定义为虚方法,这样可以启用动态联编。
内联函数的特点;使用内联函数的目的是为了提高函数的运行效率。内联函数体的代码不能过长,因为内联函数省去调用函数
的时间是以代码膨胀为代价的。内联函数不能包含循环语句,因为执行循环语句要比调用函数的开销大。
一个函数能否即是虚函数又是内联函数?
8.以下关键字的含义与用法:
extern,extern “C”,static,explicit,register,#undef,#ifndef
9.什么是函数重载与覆盖?
为什么C不支持函数重载?
为什么C++能支持函数重载?
10.VC中,编译工具条内的Debug与Release选项是什么含义?
11.编写my_memcpy函数,实现与库函数memcpy类似的功能,不能使用任何库函数;
   void* mymemcpy(void* pvTo, const char* pvFrom, size_t size)
   {
      assert((dest != NULL) && (src != NULL));
      byte* psTo = (byte*)pvTo;
      byte* psFrom = (byte*)pvFrom;
      while (size-- > 0)
      {
         *psTo++ = *psFrom++;
      }
      return pvTo;
   }
12.编写my_strcpy函数,实现与库函数strcpy类似的功能,不能使用任何库函数;
   答:char* my_strcpy(char* strdest, const char* strsrc)
          {
              assert(strdest != NULL) && (strsrc != NULL))
              char* address = strdest;
              while((*strdest++ = *strsrc++) != NULL)
               return address;
           }
             
13.编写gbk_strlen函数,计算含有汉字的字符串的长度,汉字作为一个字符处理;
已知:汉字编码为双字节,其中首字节<0,尾字节在0~63以外;(如果一个字节是-128~127)
14.函数assert的用法?
答:断言assert是仅在debug版本起作用的宏,用于检查“不应该“发生的情况。程序员可以把assert看成一个
在任何系统状态下都可以安全使用的无害测试手段。
15.为什么在头文件的最前面都会看到这样的代码:
#ifndef _STDIO_H_
#define _STDIO_H_
16.为什么数组名作为参数,会改变数组的内容,而其它类型如int却不会改变变量的值?
答:当数组名作为参数时,传递的实际上是地址。而其他类型如int作为参数时,由于函数参数值实质上是实参的一份拷贝,被调
函数内部对形参的改变并不影响实参的值。
1.实现双向链表删除一个节点P,在节点P后插入一个节点,写出这两个函数。
  2.写一个函数,将其中的/t都转换成4个空格。
  3.Windows程序的入口是哪里?写出Windows消息机制的流程。
  4.如何定义和实现一个类的成员函数为回调函数?
  5.C++里面是不是所有的动作都是main()引起的?如果不是,请举例。
  6.C++里面如何声明const void f(void)函数为C程序中的库函数?
  7.下列哪两个是等同的
  int b;
  A const int* a = &b;
  B const* int a = &b;
  C const int* const a = &b;
  D int const* const a = &b;
  8.内联函数在编译时是否做参数类型检查?
  void g(base & b){
   b.play;
  }
  void main(){
   son s;
   g(s);
   return;
  }
3、WinMain
     while( (bRet = GetMessage( &msg, NULL, 0, 0 )) != 0)
    {
        if (bRet == -1)
        {
            // handle the error and possibly exit
        }
        else
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }


MSRA Interview Written Exam(December 2003,Time:2.5 Hours)


1写出下列算法的时间复杂度。
(1)冒泡排序;
(2)选择排序;
(3)插入排序;
(4)快速排序;
(5)堆排序;
(6)归并排序;

2写出下列程序在X86上的运行结果。

struct mybitfields
{
unsigned short a : 4;
unsigned short b : 5;
unsigned short c : 7;
}test

void main(void)
{
int i;
test.a=2;
test.b=3;
test.c=0;

i=*((short *)&test);
printf("%d/n",i);
}

3写出下列程序的运行结果。

unsigned int i=3;
cout<<i * -1;

4写出下列程序所有可能的运行结果。

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);
}

5考察了一个CharPrev()函数的作用。

6对 16 Bits colors的处理,要求:
(1)Byte转换为RGB时,保留高5、6bits;
(2)RGB转换为Byte时,第2、3位置零。

7一个链表的操作,注意代码的健壮和安全性。要求:
(1)增加一个元素;
(2)获得头元素;
(3)弹出头元素(获得值并删除)。

8一个给定的数值由左边开始升位到右边第N位,如
0010<<1 == 0100
或者
0001 0011<<4 == 0011 0000
请用C或者C++或者其他X86上能运行的程序实现。

附加题(只有在完成以上题目后,才获准回答)
In C++, what does "explicit" mean? what does "protected" mean?

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值