IT面试题目汇总

面试经典试题
silver6 | 02  一月 , 2007 11:41
面试经典试题
Author:Vince
————即使你是个编程高手,你在面试前也应该要看看这套题,她也许会给你带来好运,否则你有可能后悔当初为什么没有看而跳楼自杀,这样我会很内疚的。这套题看似简单,但你未必能得高分,即使你看不懂也要把她背下来!
欢迎转载此文,转载时请注明文章来源:文斯测试技术研究中心  http://blog.csdn.net/vincetest
1 编程基础
1.1 基本概念
1. const的理解:const char*, char const*, char*const的区别问题几乎是C++面试中每次 都会有的题目。 事实上这个概念谁都有只是三种声明方式非常相似很容易记混。 Bjarne在他的The C++ Programming Language里面给出过一个助记的方法: 把一个声明从右向左读。
char * const cp; ( * 读成 pointer to )
cp is a const pointer to char
const char * p;
p is a pointer to const char;
char const * p;
同上因为C++里面没有const*的运算符,所以const只能属于前面的类型。
 
2. c指针
int *p[n];-----指针数组,每个元素均为指向整型数据的指针。
int (*p)[n];------p为指向一维数组的指针,这个一维数组有n个整型数据。
int *p();----------函数带回指针,指针指向返回的值。
int (*p)();------p为指向函数的指针。
 
3.  数组越界问题  ( 这个题目还是有点小险的 )
下面这个程序执行后会有什么错误或者效果:
#define MAX 255
int main()
{
unsigned char A[MAX],i;
for (i=0;i<=MAX;i++)
A[i]=i;
}
解答:MAX=255,数组A的下标范围为:0..MAX-1,这是其一,其二 当i循环到255时,循环内执行: A[255]=255;这句本身没有问题,但是返回for (i=0;i<=MAX;i++)语句时,由于unsigned char的取值范围在(0..255),i++以后i又为0了.. 无限循环下去 .
注: char 类型为一个字节,取值范围是 [-128 127] unsigned char [0 ,255]
4. C++:memset ,memcpy 和strcpy 的根本区别?
答:#include "memory.h"
memset用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为' '或'';例:char a[100];memset(a, '', sizeof(a));
memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;例:char a[100],b[50]; memcpy(b, a, sizeof(b));注意如用sizeof(a),会造成b的内存地址溢出。
strcpy就只能拷贝字符串了,它遇到'\0'就结束拷贝;例:char a[100],b[50];strcpy(a,b);如用strcpy(b,a),要注意a中的字符串长度(第一个'\0'之前)是否超过50位,如超过,则会造成b的内存地址溢出。
strcpy
原型:extern char *strcpy(char *dest,char *src);
     {
        ASSERT((dest!=NULL)&&(src!=NULL));
        Char *address = dest;
        While((*dest++=*src++)!=’\0’)
           Continue;
        Return dest;
     }
用法:#include <string.h>
功能:把src所指由NULL结束的字符串复制到dest所指的数组中。
说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
返回指向dest的指针。
memcpy
原型:extern void *memcpy(void *dest, void *src, unsigned int count);
     {
      ASSERT((dest!=NULL)&&(src!=NULL));
      ASSERT((dest>src+count)||(src>dest+count));//防止内存重叠,也可以用restrict修饰指针
      Byte* bdest = (Byte*)dest;
      Byte* bsrc = (Byte*) src;
      While(count-->0)
        *bdest++ = **bsrc++;
      Return dest;
     }
用法:#include <memory.h>
功能:由src所指内存区域复制count个字节到dest所指内存区域。
说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。
Memset
原型:extern void *memset(void *buffer, char c, int count);
用法:#include
功能:把buffer所指内存区域的前count个字节设置成字符c。
说明:返回指向buffer的指针。
 
5. ASSERT()是干什么用的
答: ASSERT() 是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为 FALSE (0),  程序将报告错误,并终止执行。如果表达式不为 0 ,则继续执行后面的语句。这个宏通常原来判断程序中是否出现了明显非法的数据,如果出现了终止程序以免导致严重后果,同时也便于查找错误。例如,变量n在程序中不应该为0,如果为0可能导致错误,你可以这样写程序:
......
ASSERT( n != 0);
k = 10/ n;
......
ASSERT 只有在 Debug 版本中才有效,如果编译为 Release 版本则被忽略
assert() 的功能类似,它是ANSI C标准中规定的函数,它与ASSERT的一个重要区别是可以用在Release版本中。
 
6. system("pause");作用?
答:系统的暂停程序,按任意键继续,屏幕会打印,"按任意键继续。。。。。" 省去了使用getchar();
7. 请问C++的类和C里面的struct有什么区别?
答:c++中的类具有成员保护功能,并且具有继承,多态这类oo特点,而c里的struct没有
c里面的struct没有成员函数,不能继承,派生等等.
8.  请讲一讲析构函数和虚函数的用法和作用?
答:析构函数也是特殊的类成员函数,它没有返回类型,没有参数,不能随意调用,也没有重载。只是在类对象生命期结束的时候,由系统自动调用释放在构造函数中分配的资源。这种在运行时,能依据其类型确认调用那个函数的能力称为多态性,或称迟后联编。另: 析构函数一般在对象撤消前做收尾工作,比如回收内存等工作,
虚拟函数的功能是使子类可以用同名的函数对父类函数进行覆盖,并且在调用时自动调用子类覆盖函数,如果是纯虚函数,则纯粹是为了在子类覆盖时有个统一的命名而已。
注意 : 子类重新定义父类的虚函数的做法叫覆盖 ,override, 而不是 overload( 重载 ), 重载的概念不属于面向对象编程 , 重载指的是存在多个同名函数 , 这些函数的参数表不同 .. 重载是在编译期间就决定了的 , 是静态的 , 因此 , 重载与多态无关 . 与面向对象编程无关 .
含有纯虚函数的类称为抽象类,不能实例化对象,主要用作接口类//
 
9. 全局变量和局部变量有什么区别?是怎么实现的?操作系统和编译器是怎么知道的?
答;全局变量的生命周期是整个程序运行的时间,而局部变量的生命周期则是局部函数或过程调用的时间段。 其实现是由编译器在编译时采用不同内存分配方法。
全局变量在main函数调用后,就开始分配,
静态变量则是在main函数前就已经初始化了。
局部变量则是在用户栈中动态分配的(还是建议看编译原理中的活动记录这一块)
10. 8086是多少位的系统?在数据总线上是怎么实现的?
答:8086系统是16位系统,其数据总线是20位。
 
 
12 程序设计
1. 编写用C语言实现的求n阶阶乘问题的递归算法:
答:long int fact(int n)
{
If(n==0||n==1)
   Return 1;
Else
 Return n*fact(n-1);
}
2. 二分查找算法:
1) 递归方法实现:
int BSearch(elemtype a[],elemtype x,int low,int high)
/*在下届为low,上界为high的数组a中折半查找数据元素x*/
{
int mid;
if(low>high) return -1;
mid=(low+high)/2;
if(x==a[mid]) return mid;
if(x<a[mid]) return(BSearch(a,x,low,mid-1));
else return(BSearch(a,x,mid+1,high));
}
2) 非递归方法实现:
int BSearch(elemtype a[],keytype key,int n)
{
int low,high,mid;
low=0;high=n-1;
while(low<=high)
{
mid=(low+high)/2;
if(a[mid].key==key) return mid;
else if(a[mid].key<key) low=mid+1;
else high=mid-1;
}
return -1;
}
3. 递归计算如下递归函数的值(斐波拉契):
f(1)=1
f(2)=1
f(n)=f(n-1)+f(n-2) n>2
解:非递归算法:
int f(int n)
{
int i,s,s1,s2;
s1=1;/*s1用于保存f(n-1)的值*/
s2=1;/*s2用于保存f(n-2)的值*/
s=1;
for(i=3;i<=n;i++)
{
s=s1+s2;
s2=s1;
s1=s;
}
return(s);
}
递归算法:
Int f(int n)
{
 If(n==1||n==2)
   Rerurn 1;
 Else
   Rerutn f(n-1)+f(n-2);
}
4. 交换两个数,不用第三块儿内存:
答:int a = ……;
int b = ……;
a = a + b;
b = a - b;
a = a - b;
5.  冒泡排序:
答:void BubbleSort(elemtype x[],int n)   //时间复杂度为0(n*n);
{
int i,j;
elemtype temp;
for(i=1;i<n;i++)
for(j=0;j<n-i;j++)   
{
if(x[j].key>x[j+1].key)
{
temp=x[j];
x[j]=x[j+1];
x[j+1]=temp;
}
}
}
//补充一个改进的冒泡算法:
 void BubbleSort(elemtype x[],int n)
{
 Int i,j;
 BOOL exchange;  //记录交换标志
for(i=1;i<n;++i)    //最多做n-1趟排序
 {
Exchange = false;
For(j=n-1;j>=i;--j)
{
 If(x[j]>x[j+1])
 {
    x[0] = x[j];
    X[j] = x[j+1];
    X[j+1] = x[0];
    Exchange = true;   //发生了交换,设置标志为真.
 }
}
if (!Exchange )      //为发生替换,提前终止算法
return;
 
 }
}
6. c语言 文件读写
#include "stdio.h"
main()
{
FILE *fp;
char ch,filename[10];
scanf("%s",filename);
if((fp=fopen(filename,"w")==NULL)
{
printf("cann't open filen");
exit(0);
}
ch=getchar();
while(ch!='#')
{
fputc(ch,fp);
putchar(ch);
ch=getchar();
}
fclose(fp);
}
 
7. winsocket 编程    // 这个不错
//  服务器代码
#include <Winsock2.h>
#include <stdio.h>
void main()
{
WORD wVersionRequested; //版本号
WSADATA  wsaData;        //数据
int err;
wVersionRequested = MAKEWORD(1,1);
err = WSAStartup(wVersionRequested,&wsaData);
if( err != 0)
{
return;
}
if(LOBYTE( wsaData.wVersion ) != 1||
HIBYTE( wsaData.wVersion) != 1)
{
WSACleanup();
return;
}
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0); //建立套接字
SOCKADDR_IN addrSrv; 
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));  //绑定端口
listen(sockSrv,5);   //转换socket套接子为侦听套接子
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
while(1)   //无限循环
{
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
char sendBuf[100];
sprint(sendBuf,"Welcome %s to  http://www.sunxin.org",
inet_ntoa(addrClient.sin_addr));
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
char recvBuf[100];
recv(sockConn,recvBuf);
printf("%sn",recvBuf);
closesocket(sockConn);
WSACleanup();
}
}
注:这是Server端;File->New->Win32 Console Application,工程名:TcpSrv;然后,File->New->C++ Source File,文件名:TcpSrv;在该工程的Setting的Link的Object/library modules项要加入ws2_32.lib
#include <Winsock2.h>
#include <stdio.h>
void main()
{
WORD    wVersionRequested;
WSADATA   wsaData;
int err;
wVersionRequested = MAKEWORD(1,1);
err =  WSAStartup(wVersionRequested,&wsaData); //启动winsock Dll
if( err != 0)
{
return;
}
if(LOBYTE( wsaData.wVersion ) != 1||
HIBYTE( wsaData.wVersion) != 1)
{
WSACleanup();
return;
}
SOCKET sockClient= socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrSrv.sin_family=AF_INET;
addrSrv.sin_port = htons(6000);
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
char recvBuf[100];
recv(sockClient,recvBuf,100,0);
printf("%sn",recvBuf);
send(sockClient,"This is zhangsan",strlen("This is zhangsan")+1,0);
closesocket(sockClient);
WSACleanup();
}
注:这是Client端;File->New->Win32 Console Application,工程名:TcpClient;然后,File->New->C++ Source File,文件名:TcpClient;同理,在该工程的Setting的Link的Object/library modules项要加入ws2_32.lib
 
8.  类的知识  ( 非常不错的一道题目 )..
C++
#include <iostream.h>
class human
{
public:
human(){ human_num++;}; //默认构造函数
static int human_num;     //静态成员
~human()
{
human_num--;
print();
}
void print()             //
{
cout<<"human num is: "<<human_num<<endl;
}
protected:
private:
};
int human::human_num = 0;   //类中静态数据成员在外部定义,仅定义一次
human f1(human x)
{
x.print();
return x;
}
int main(int argc, char* argv[])
{
human h1; //调用默认构造函数,human_num变为1
h1.print(); // 打印Human_man:1
human h2 = f1(h1); //先调用函数f1(),输出human_num:1,而后输出human_num为0,
h2.print();//打印输出:human_num:0
return 0;
} //依次调用两个析构函数:输出:human_num:-1,human_num:-2;
输出:
1
1
0
0
-1
-2
----------------------------
分析:
human h1; //调用构造函数,---hum_num = 1;
h1.print(); //输出:"human is 1"
human h2 = f1(h1); //再调用f1(h1)的过程中,由于函数参数是按值传递对象, 调用默认的复制构造函数 , h2并没有调用定义的构造函数.
 
 
C/C++  程序设计员应聘常见面试试题深入剖析
silver6 | 25 九月, 2006 09:07
本文的写作目的并不在于提供C/C++程序员求职面试指导,而旨在从技术上分析面试题的内涵。文中的大多数面试题来自各大论坛,部分试题解答也参考了网友的意见。
  许多面试题看似简单,却需要深厚的基本功才能给出完美的解答。企业要求面试者写一个最简单的strcpy函数都可看出面试者在技术上究竟达到了怎样的程度,我们能真正写好一个strcpy函数吗?我们都觉得自己能,可是我们写出的strcpy很可能只能拿到10分中的2分。读者可从本文看到strcpy 函数从2分到10分解答的例子,看看自己属于什么样的层次。此外,还有一些面试题考查面试者敏捷的思维能力。 
  分析这些面试题,本身包含很强的趣味性;而作为一名研发人员,通过对这些面试题的深入剖析则可进一步增强自身的内功。
  2.找错题
  试题1:
void test1()
{
 char string[10];
 char* str1 = "0123456789";
 strcpy( string, str1 );
}

  试题2:
void test2()
{
 char string[10], str1[10];
 int i;
 for(i=0; i<10; i++)
 {
  str1[i] = 'a';
 }
 strcpy( string, str1 );
}

  试题3:
void test3(char* str1)
{
 char string[10];
 if( strlen( str1 ) <= 10 )
 {
  strcpy( string, str1 );
 }
}

  解答:
  试题1字符串str1需要11个字节才能存放下(包括末尾的’’),而string只有10个字节的空间,strcpy会导致数组越界;
  对试题2,如果面试者指出字符数组str1不能在数组内结束可以给3分;如果面试者指出strcpy(string, str1)调用使得从str1内存起复制到string内存起所复制的字节数具有不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10 分;

  对试题3,if(strlen(str1) <= 10)应改为if(strlen(str1) < 10),因为strlen的结果未统计’’所占用的1个字节。
  剖析:
  考查对基本功的掌握:
  (1)字符串以’\0’结尾;
  (2)对数组越界把握的敏感度;
  (3)库函数strcpy的工作方式,如果编写一个标准strcpy函数的总分值为10,下面给出几个不同得分的答案:

  2分
void strcpy( char *strDest, char *strSrc )
{
  while( (*strDest++ = * strSrc++) != '’ );
}

  4分
void strcpy( char *strDest, const char *strSrc ) 
//将源字符串加const,表明其为输入参数,加2分
{
  while( (*strDest++ = * strSrc++) != '’ );
}

  7分
void strcpy(char *strDest, const char *strSrc) 
{
 //对源地址和目的地址加非0断言,加3分
 assert( (strDest != NULL) && (strSrc != NULL) );
 while( (*strDest++ = * strSrc++) != '’ );
}

  10分
//为了实现链式操作,将目的地址返回,加3分!

char * strcpy( char *strDest, const char *strSrc ) 
{
 assert( (strDest != NULL) && (strSrc != NULL) );
 char *address = strDest; 
 while( (*strDest++ = * strSrc++) != '’ ); 
  return address;
}

  从2分到10分的几个答案我们可以清楚的看到,小小的strcpy竟然暗藏着这么多玄机,真不是盖的!需要多么扎实的基本功才能写一个完美的strcpy啊!

  (4)对strlen的掌握,它没有包括字符串末尾的''。

  读者看了不同分值的strcpy版本,应该也可以写出一个10分的strlen函数了,完美的版本为: int strlen( const char *str ) //输入参数const
{
 assert( strt != NULL ); //断言字符串地址非0
 int len;
 while( (*str++) != '' ) 
 { 
  len++; 
 } 
 return len;
}

  试题4:
void GetMemory( char *p )
{
 p = (char *) malloc( 100 );
}

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

  试题5:
char *GetMemory( void )

 char p[] = "hello world"; 
 return p; 
}

void Test( void )

 char *str = NULL; 
 str = GetMemory(); 
 printf( str ); 
}

  试题6:
void GetMemory( char **p, int num )
{
 *p = (char *) malloc( num );
}

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

  试题7:
void Test( void )
{
 char *str = (char *) malloc( 100 );
 strcpy( str, "hello" );
 free( str ); 
 ... //省略的其它语句
}

  解答:

  试题4传入中GetMemory( char *p )函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完
char *str = NULL;
GetMemory( str );

  后的str仍然为NULL;
  试题5中
char p[] = "hello world"; 
return p;

  的p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误, 其根源在于不理解变量的生存期。

  试题6的GetMemory避免了试题4的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句
*p = (char *) malloc( num );

  后未判断内存是否申请成功,应加上:
if ( *p == NULL )
{
 ...//进行申请内存失败处理
}

  试题7存在与试题6同样的问题,在执行
char *str = (char *) malloc(100);

  后未进行内存是否申请成功的判断;另外,在free(str)后未置str为空,导致可能变成一个“野”指针,应加上:
str = NULL;

  试题6的Test函数中也未对malloc的内存进行释放。
  剖析:
  试题4~7考查面试者对内存操作的理解程度,基本功扎实的面试者一般都能正确的回答其中50~60的错误。但是要完全解答正确,却也绝非易事。

  对内存操作的考查主要集中在:
  (1)指针的理解;
  (2)变量的生存期及作用范围;
  (3)良好的动态内存申请和释放习惯。
  再看看下面的一段程序有什么错误:
swap( int* p1,int* p2 )
{
 int *p;
 *p = *p1;
 *p1 = *p2;
 *p2 = *p;
}

  在swap函数中 p 是一个 指针,有可能指向系统区,导致程序运行的崩溃。在VC++中DEBUG运行时提示错误“Access Violation”。该程序应该改为:
swap( int* p1,int* p2 )
{
 int p;
 p = *p1;
 *p1 = *p2;
 *p2 = p;
}

  3.内功题

  试题1:分别给出BOOL,int,float,指针变量 与“零值”比较的 if 语句(假设变量名为var)
  解答:
   BOOL型变量:if(!var)
   int型变量: if(var==0)
   float型变量:
   const float EPSINON = 0.00001;

   if ((x >= - EPSINON) && (x <= EPSINON)

   指针变量:  if(var==NULL)

  剖析:

  考查对0值判断的“内功”,BOOL型变量的0判断完全可以写成if(var==0),而int型变量也可以写成if(!var),指针变量的判断也可以写成if(!var),上述写法虽然程序都能正确运行,但是未能清晰地表达程序的意思。 
  一般的,如果想让if判断一个变量的“真”、“假”,应直接使用if(var)、if(!var),表明其为“逻辑”判断;如果用if判断一个数值型变量(short、int、long等),应该用if(var==0),表明是与0进行“数值”上的比较;而判断指针则适宜用if(var==NULL),这是一种很好的编程习惯。

  浮点型变量并不精确,所以不可将float变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”形式。如果写成if (x == 0.0),则判为错,得0分。

  试题2:以下为Windows NT下的32位C++程序,请计算sizeof的值
void Func ( char str[100] )
{
 sizeof( str ) = ?
}

void *p = malloc( 100 );
sizeof ( p ) = ?

  解答:
sizeof( str ) = 4
sizeof ( p ) = 4

  剖析:

  Func ( char str[100] )函数中数组名作为函数形参时,在函数体内,数组名失去了本身的内涵,仅仅只是一个指针;在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。

  数组名的本质如下:

  (1 )数组名指代一种数据结构,这种数据结构就是数组;

  例如:
char str[10];
cout << sizeof(str) << endl;

  输出结果为10,str指代数据结构char[10]。

  (2) 数组名可以转换为指向其指代实体的指针,而且是一个指针常量,不能作自增、自减等操作,不能被修改;
char str[10]; 
str++; //编译出错,提示str不是左值 

  (3)数组名作为函数形参时,沦为普通指针。

  Windows NT 32位平台下,指针的长度(占用内存的大小)为4字节,故sizeof( str ) 、sizeof ( p ) 都为4。

  试题3:写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。另外,当你写下面的代码时会发生什么事?
least = MIN(*p++, b);

  解答:
#define MIN(A,B) ((A) <= (B) ? (A) : (B))

  MIN(*p++, b)会产生宏的副作用

  剖析:

  这个面试题主要考查面试者对宏定义的使用,宏定义可以实现类似于函数的功能,但是它终归不是函数,而宏定义中括弧中的“参数”也不是真的参数,在宏展开的时候对“参数”进行的是一对一的替换。

  程序员对宏定义的使用要非常小心,特别要注意两个问题:

  (1)谨慎地将宏定义中的“参数”和整个宏用用括弧括起来。所以,严格地讲,下述解答:
#define MIN(A,B) (A) <= (B) ? (A) : (B)
#define MIN(A,B) (A <= B ? A : B )

  都应判0分;
  (2)防止宏的副作用。
  宏定义#define MIN(A,B) ((A) <= (B) ? (A) : (B))对MIN(*p++, b)的作用结果是:
((*p++) <= (b) ? (*p++) : (*p++))
  这个表达式会产生副作用,指针p会作三次++自增操作。
  除此之外,另一个应该判0分的解答是:
#define MIN(A,B) ((A) <= (B) ? (A) : (B));

  这个解答在宏定义的后面加“;”,显示编写者对宏的概念模糊不清,只能被无情地判0分并被面试官淘汰。

  试题4:为什么标准头文件都有类似以下的结构?
#ifndef __INCvxWorksh
#define __INCvxWorksh 
#ifdef __cplusplus

extern "C" {
#endif 
/*...*/ 
#ifdef __cplusplus
}

#endif 
#endif /* __INCvxWorksh */

  解答:
  头文件中的编译宏
#ifndef __INCvxWorksh
#define __INCvxWorksh
#endif

  的作用是防止被重复引用。

  作为一种面向对象的语言,C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在symbol库中的名字与C语言的不同。例如,假设某个函数的原型为:
void foo(int x, int y);

  该函数被C编译器编译后在symbol库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。_foo_int_int这样的名字包含了函数名和函数参数数量及类型信息,C++就是考这种机制来实现函数重载的。
  为了实现C和C++的混合编程,C++提供了C连接交换指定符号extern "C"来解决名字匹配问题,函数声明前加上extern "C"后,则编译器就会按照C语言的方式将该函数编译为_foo,这样C语言中就可以调用C++的函数了。
 
 试题5:编写一个函数,作用是把一个char组成的字符串循环右移n个。比如原来是“abcdefghi”如果n=2,移位后应该是“hiabcdefgh” 

  函数头是这样的:
//pStr是指向以''结尾的字符串的指针
//steps是要求移动的n

void LoopMove ( char * pStr, int steps )
{
 //请填充...
}

  解答:

  正确解答1:
void LoopMove ( char *pStr, int steps )
{
 int n = strlen( pStr ) - steps;
 char tmp[MAX_LEN]; 
 strcpy ( tmp, pStr + n ); 
 strcpy ( tmp + steps, pStr); 
 *( tmp + strlen ( pStr ) ) = '';
 strcpy( pStr, tmp );
}

  正确解答2:
void LoopMove ( char *pStr, int steps )
{
 int n = strlen( pStr ) - steps;
 char tmp[MAX_LEN]; 
 memcpy( tmp, pStr + n, steps ); 
 memcpy(pStr + steps, pStr, n ); 
 memcpy(pStr, tmp, steps ); 
}

  剖析:
  这个试题主要考查面试者对标准库函数的熟练程度,在需要的时候引用库函数可以很大程度上简化程序编写的工作量。
  最频繁被使用的库函数包括:
  (1) strcpy
  (2) memcpy
  (3) memset
  试题6:已知WAV文件格式如下表,打开一个WAV文件,以适当的数据结构组织WAV文件头并解析WAV格式的各项信息。

  WAVE文件格式说明表
 
偏移地址
字节数
数据类型
内 容
文件头
 
00H
4
Char
"RIFF"标志
04H
4
int32
文件长度
08H
4
Char
"WAVE"标志
0CH
4
Char
"fmt"标志
10H
4
 
过渡字节(不定)
14H
2
int16
格式类别
16H
2
int16
通道数
18H
2
int16
采样率(每秒样本数),表示每个通道的播放速度
1CH
4
int32
波形音频数据传送速率
20H
2
int16
数据块的调整数(按字节算的)
22H
2
 
每样本的数据位数
24H
4
Char
数据标记符"data"
28H
4
int32
语音数据的长度

  解答:

  将WAV文件格式定义为结构体WAVEFORMAT:
typedef struct tagWaveFormat

 char cRiffFlag[4]; 
 UIN32 nFileLen; 
 char cWaveFlag[4]; 
 char cFmtFlag[4]; 
 char cTransition[4]; 
 UIN16 nFormatTag ; 
 UIN16 nChannels; 
 UIN16 nSamplesPerSec; 
 UIN32 nAvgBytesperSec; 
 UIN16 nBlockAlign; 
 UIN16 nBitNumPerSample; 
 char cDataFlag[4]; 
 UIN16 nAudioLength; 

} WAVEFORMAT;

  假设WAV文件内容读出后存放在指针buffer开始的内存单元内,则分析文件格式的代码很简单,为:
WAVEFORMAT waveFormat;
memcpy( &waveFormat, buffer,sizeof( WAVEFORMAT ) );

  直接通过访问waveFormat的成员,就可以获得特定WAV文件的各项格式信息。

  剖析:

  试题6考查面试者组织数据结构的能力,有经验的程序设计者将属于一个整体的数据成员组织为一个结构体,利用指针类型转换,可以将memcpy、memset等函数直接用于结构体地址,进行结构体的整体操作。 透过这个题可以看出面试者的程序设计经验是否丰富。

  试题7:编写类String的构造函数、析构函数和赋值函数,已知类String的原型为:
class String

 public: 
  String(const char *str = NULL); // 普通构造函数 
  String(const String &other); // 拷贝构造函数 
  ~ String(void); // 析构函数 
  String & operate =(const String &other); // 赋值函数 
 private: 
  char *m_data; // 用于保存字符串 
};

  解答:
//普通构造函数

String::String(const char *str) 
{
 if(str==NULL) 
 {
  m_data = new char[1]; // 得分点:对空字符串自动申请存放结束标志''的空
  //加分点:对m_data加NULL 判断
  *m_data = '\0'; 
 } 
 else
 {
  int length = strlen(str); 
  m_data = new char[length+1]; // 若能加 NULL 判断则更好 
  strcpy(m_data, str); 
 }
}

// String的析构函数

String::~String(void) 
{
 delete [] m_data; // 或delete m_data;
}

//拷贝构造函数

String::String(const String &other)    // 得分点:输入参数为const型

 int length = strlen(other.m_data); 
 m_data = new char[length+1];     //加分点:对m_data加NULL 判断
 strcpy(m_data, other.m_data); 
}

//赋值函数

String & String::operate =(const String &other) // 得分点:输入参数为const型

 if(this == &other)   //得分点:检查自赋值
  return *this; 
 delete [] m_data;     //得分点:释放原有的内存资源
 int length = strlen( other.m_data ); 
 m_data = new char[length+1];  //加分点:对m_data加NULL 判断
 strcpy( m_data, other.m_data ); 
 return *this;         //得分点:返回本对象的引用
}

  剖析:
  能够准确无误地编写出String类的构造函数、拷贝构造函数、赋值函数和析构函数的面试者至少已经具备了C++基本功的60%以上!
  在这个类中包括了指针类成员变量m_data,当类中包括指针类成员变量时,一定要重载其拷贝构造函数、赋值函数和析构函数,这既是对C++程序员的基本要求,也是《Effective C++》中特别强调的条款。
  仔细学习这个类,特别注意加注释的得分点和加分点的意义,这样就具备了60%以上的C++基本功!

   试题 8 :请说出 static const 关键字尽可能多的作用
  解答:
  static关键字至少有下列n个作用:
  (1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;
  (2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;
  (3)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;
  (4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
  (5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。
  const关键字至少有下列n个作用:
  (1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;
  (2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;
  (3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
  (4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;
  (5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。例如:
const classA operator*(const classA& a1,const classA& a2);

  operator*的返回结果必须是一个const对象。如果不是,这样的变态代码也不会编译出错:
classA a, b, c;
(a * b) = c; // 对a*b的结果赋值

  操作(a * b) = c显然不符合编程者的初衷,也没有任何意义。
  剖析:
  惊讶吗?小小的static和const居然有这么多功能,我们能回答几个?如果只能回答1~2个,那还真得闭关再好好修炼修炼。
  这个题可以考查面试者对程序设计知识的掌握程度是初级、中级还是比较深入,没有一定的知识广度和深度,不可能对这个问题给出全面的解答。大多数人只能回答出static和const关键字的部分功能。
  4.技巧题
  试题1:请写一个C函数,若处理器是Big_endian的,则返回0;若是Little_endian的,则返回1
  解答:
int checkCPU()
{
 {
  union w
  { 
   int a;
   char b;
  } c;
  c.a = 1;
  return (c.b == 1);
 }
}

  剖析:
 嵌入式系统开发者应该对Little-endian和Big-endian模式非常了解。采用Little-endian模式的CPU对操作数的存放方式是从低字节到高字节,而Big-endian模式对操作数的存放方式是从高字节到低字节。例如,16bit宽的数0x1234在Little- endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:
内存地址
存放内容
0x4000
0x34
0x4001
0x12

  而在Big-endian模式CPU内存中的存放方式则为:
内存地址
存放内容
0x4000
0x12
0x4001
0x34

  32bit宽的数0x12345678在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:
内存地址
存放内容
0x4000
0x78
0x4001
0x56
0x4002
0x34
0x4003
0x12

  而在Big-endian模式CPU内存中的存放方式则为:
内存地址
存放内容
0x4000
0x12
0x4001
0x34
0x4002
0x56
0x4003
0x78

  联合体union的存放顺序是所有成员都从低地址开始存放,面试者的解答利用该特性,轻松地获得了CPU对内存采用Little-endian还是Big-endian模式读写。如果谁能当场给出这个解答,那简直就是一个天才的程序员。

  试题2:写一个函数返回1+2+3+…+n的值(假定结果不会超过长整型变量的范围) 

  解答:
int Sum( int n )

 return ( (long)1 + n) * n / 2;  //或return (1l + n) * n / 2;
}

  剖析:
  对于这个题,只能说,也许最简单的答案就是最好的答案。下面的解答,或者基于下面的解答思路去优化,不管怎么“折腾”,其效率也不可能与直接return ( 1 l + n ) * n / 2相比!
int Sum( int n )
{
 long sum = 0;
 for( int i=1; i<=n; i++ )
 {
  sum += i;
 }
 return sum;
}

  所以程序员们需要敏感地将数学等知识用在程序设计中。
 
终于明白了: 按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本。因此,如果函数修改了该参数,仅改变副本,而原始值保持不变。按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本。因此,如果函数修改了该参数,调用代码中的原始值也随之改变。
不管是在c/c++中还是在java函数调用都是传值调用,.
当参数是对象的时候,传递的是对象的引用,这个和c/c++传递指针是一个道理,在函数中改变引用本身,不会改变引用所指向的对象.
华为面试题
4、SQL问答题
SELECT * FROM TABLE

SELECT * FROM TABLE 
WHERE NAME LIKE '%%' AND ADDR LIKE '%%' 
AND (1_ADDR LIKE '%%' OR 2_ADDR LIKE '%%' 
OR 3_ADDR LIKE '%%' OR 4_ADDR LIKE '%%' ) 
的检索结果为何不同?
答: 前者检索全部,后者有三种情况检索不出:NAME=null或ADDR=null或1_ADDR LIKE  2_ADDR 3_ADDR 4_ADDR其一为null.
前者检索所有记录,后者只能检索出 NAME 和ADDR中非Null的记录。
 
5、SQL问答题
表结构:
 1、 表名:g_cardapply
 字段(字段名/类型/长度):
 g_applyno varchar 8;//申请单号(关键字)
 g_applydate bigint 8;//申请日期
 g_state varchar 2;//申请状态
 2、 表名:g_cardapplydetail
 字段(字段名/类型/长度):
 g_applyno varchar 8;//申请单号(关键字)
 g_name varchar 30;//申请人姓名
 g_idcard varchar 18;//申请人身份证号
 g_state varchar 2;//申请状态
其中,两个表的关联字段为申请单号。
题目:
1、 查询身份证号码为440401430103082的申请日期
select A.g_applydate 
from g_cardapply A inner join g_cardapplydetail B on A.g_applyno = B.g_applyno
where B.g_idCard = '440401430103082'

2
、 查询同一个身份证号码有两条以上记录的身份证号码及记录个数
select g_idCard,count(*) as Cnt from g_cardapplydetail 
group by g_idcard
having count(*) > 1

3、 将身份证号码为440401430103082的记录在两个表中的申请状态均改为07
update g_cardapplydetail set g_state = '07'
where g_idcard = '440401430103082'

update A set g_state = '07'
from g_cardapply A inner join g_cardapplydetail B on A.g_applyno = B.g_applyno 
where B.g_idcard = '440401430103082'

4、 删除g_cardapplydetail表中所有姓李的记录
delete from g_cardapplydetail 
where g_name like '李%'
3、 将身份证号码为440401430103082的记录在两个表中的申请状态均改为07
update g_cardapplydetail set g_state = '07'
where g_idcard = '440401430103082'

update A set g_state = '07'
from g_cardapply A inner join g_cardapplydetail B on A.g_applyno = B.g_applyno
where B.g_idcard = '440401430103082'
5、SQL问答题:
/*Select g_cardapply. g_applydate
From g_cardapply, g_cardapplydetail
Where g_cardapply. g_applyno=g_cardapplydetail. g_applyno
And g_cardapplydetail.g_idcard='440401430103082'*/

/*Select *From (select count(*) g_count , g_idcard
From g_cardapplydetail 
Group by g_idcard ) a
Where a. g_count >= 2*/

/*Update g_cardapply 
set g_state='07' 
where g_applyno in (select distinct g_applyno 
from g_cardapplydetail 
where g_idcard ='440401430103082') 
update g_cardapplydetail
set g_state='07'
where g_idcard='440401430103082' */

/*Delete from g_cardapplydetail
Where g_name like '李%'*/
通过测试
PS:偶GF做的,自己先汗一下
金山公司几道面试题

4. In C++, there're four type of Casting Operators, please enumerate and explain them especially the difference.
解析: C++类型转换问题
答案: reinterpret_cast,static_cast,const_cast,dynamic_cast
static_cast 数制转换
dynamic_cast 用于执行向下转换和在继承之间的转换
const_cast 去掉const
reinterpret_cast 用于执行并不安全的orimplmentation_dependent类型转换


7 以下代码有什么问题,如何修改?
#include <iostream>
#include <vector>
using namespace std;
void print(vector<int>);
int main()
{
vector<int> array;
array.push_back(1);
array.push_back(6);
array.push_back(6);
array.push_back(3);
//删除array数组中所有的6
vector<int>::iterator itor;
vector<int>::iterator itor2;
itor=array.begin();

for(itor=array.begin(); itor!=array.end(); )
{
if(6==*itor) 
{
itor2=itor;
array.erase(itor2);

itor++; 
}
print(array);
return 0;

void print(vector<int> v)
{
cout << "n vector size is: " << v.size() << endl;
vector<int>::iterator p = v.begin();

我的答案是,迭代器问题,只能删除第一个6,以后迭代器就失效了,不能删除之后的元素。
但我不知道怎么改
void print(const vector<int>&);
int main()
{
vector<int> array;
array.push_back(1);
array.push_back(6);
array.push_back(6);
array.push_back(3);

//删除array数组中所有的6
array.erase( remove( array.begin(), array.end(), 6 ) , array.end() );

print(array);
return 0;

void print(const vector<int>& v)
{
cout << "n vector size is: " << v.size() << endl;
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " ") );
}
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> array;
array.push_back(1);
array.push_back(6);
array.push_back(6);
array.push_back(6);
array.push_back(6);
array.push_back(6);
array.push_back(3);
array.push_back(9);
array.push_back(8);
array.push_back(5);
//&Eacute;&frac34;&sup3;&yacute;array&Ecirc;&yacute;×é&Ouml;&ETH;&Euml;ù&Oacute;&ETH;&micro;&Auml;6
vector<int>::iterator itor;
itor=array.begin();
for(itor=array.begin(); itor!=array.end();++itor )
{
if(6==*itor) 
{
itor=array.erase(itor);
--itor;

}
cout << "vector size is: " << array.size() << endl;
for(itor=array.begin(); itor!=array.end();++itor )
{
cout<<*itor<<" ";
}
system("pause");
return 0;
}
答案:  执行itor=array.erase(itor);这句话后,itor不会移动,而只是把删除的数后面的数都往前移一位,所以删除了第一个6后,指针指向第2个6,然后在来个itor++,指针就指向array.end()了,给你画个草图:
1 6 6 3 array.end() //最开始指针itor指向第一个6;
1 6 3 array.end() //删除第一个6后,指向第二个6
1 6 3 array.end() //itor++后,就指向3了,所以不能删除
 
2. What are three ways in which a thread can enter the waiting state?
答:
CPU调度给优先级更高的thread,原先thread进入waiting
阻塞的thread获得资源或者信号,进入waiting
还有什么
面试与被面试总结
我从事技术工作,
这几年的面试与被面试总结
先说我去被面试的经验吧。
回答清楚了2个问题,就能顺利过关了。
1。为什么要离开上一家公司。
2。公司为什么要雇佣你。
问第一个问题的是hr(或老板),呵呵 ,即使你技术过关,hr那里没有好的影响,结果是一个字,难!
如何回答呢? hr想推论出你在他的公司能呆多久。这个时候,你甚至可以明确告诉他,我在贵公司至少能呆n(n>=1)年----当然,你没有把握的话,绝对不能乱说,社会上混,要讲信用的。
有一次,我就在这个问题上吃了大亏,我看公司环境还不错,就我自做主张回答1年,结果,hr心目中是m(m>=2)年,呵呵,结果可想而知了。要知道,技术面试都过关了,Hr面试是2选1,在回家的路上,我只能祈祷对手自动放弃或找到了其他更好的工作。:)
问第二个问题的是技术官。你要让他知道你已经做过哪些商业作品。一定要是商业作品。在里面负责哪方面具体工作,对于你熟悉的地方要多说。最好就是能争取笔试或上机,因为用用口说的话,大家理解都不一样,误差可能很大,结果对你相当不利。在这个问题上我也吃过亏的,曾有一个我很看好的职位,认为把握很大,业务理解上也很有优势,和技术官一谈,结果是game over。要知道,在其他公司的上机和笔试中,我都能在应聘者中取得高分。
再说我去面试别人的经验吧。
当时,我的任务是出题,给分。若你觉得题很难,那么,请千万不要放弃,显然,你的对手也觉得难。只要坚持,我会认为这人有耐心很毅力,在以后的工作中也是好的合作者。题一定要做完,表现出认真的态度,若有疑问或卡壳,还可以寻求面试官的帮助,这些不会减分,相反,会增加你和他们的接触机会,面试官会评估你的沟通能力。
有一次,有1个人来面试,题没有完全ok,但很规范,态度很认真,他把他知道的都做上去了,我给了他技术类的高分。后来,顺利进入公司,再后来进步很快,成了重要角色。
若文章对你有帮助的话,请在此讨论。
祝你成功
面试题
1.链表和数组的区别在哪里? 
2.编写实现链表排序的一种算法。说明为什么你会选择用这样的方法? 
3.编写实现数组排序的一种算法。说明为什么你会选择用这样的方法? 
4.请编写能直接实现strstr()函数功能的代码。 
5.编写反转字符串的程序,要求优化速度、优化空间。 
6.在链表里如何发现循环链接? 
7.给出洗牌的一个算法,并将洗好的牌存储在一个整形数组里。 
8.写一个函数,检查字符是否是整数,如果是,返回其整数值。(或者:怎样只用4行代码 ,编写出一个从字符串到长整形的函数?) 
9.给出一个函数来输出一个字符串的所有排列。 
10.请编写实现malloc()内存分配函数功能一样的代码。 
11.给出一个函数来复制两个字符串A和B。字符串A的后几个字节和字符串B的前几个字节重叠。 
12.怎样编写一个程序,把一个有序整数数组放到二叉树中? 
13.怎样从顶部开始逐层打印二叉树结点数据?请编程。 
14.怎样把一个链表掉个顺序(也就是反序,注意链表的边界条件并考虑空链表)? 
另外:
一、单项选择题:(共12题,每题2分,共24分) 
1. 下面哪一个不是C++的标准数据类型? ( D) 
A. int B. char
C. bool D. real
2. break关键字在哪一种语法结构中不能使用? (C) 
A. for语句 B. switch语句
C. if语句 D. while语句 
3. 类的继承方式有几种? (B ) 
A. 两种 B. 三种
C. 四种 D. 六种
4. extern关键字的作用是什么? (D)
A. 声明外部链接 B. 声明外部头文件引用
C. 声明使用扩展C++语句 D. 声明外部成员函数、成员数据。
5. C库函数strstr的功能是? (A )
A. 查找子串 B. 计算字符串长度
C. 字符串比较 D. 连结字符串 
6. stl::deque是一种什么数据类型? (A )
A. 动态数组 B. 链表
C. 堆栈 D. 树 
7. STL库里含有下面的哪一种泛型算法? (D )
A. KMP查找 B. 折半查找
C. 冒泡排序 D. 快速排序 
8. 现在最快且最通用的排序算法是什么? (A )
A. 快速排序 B. 冒泡排序
C. 选择排序 D. 外部排序
9. Win32下的线程的哪一种优先级最高? ( C)
A. THREAD_PRIORITY_HIGHEST 高优先级
B. THREAD_PRIORITY_IDLE      最低优先级,仅在系统空闲时执行
C. THREAD_PRIORITY_TIME_CRITICAL 最高优先级
D. THREAD_PRIORITY_ABOVE_NORMAL 高于普通优先级
10. 下面四个选项中,哪一个不是WinMain函数的参数? (D )
A. HINSTANCE B. INT
C. LPSTR D. WPARAM 
11. VC++的编译器中,运算符new底层的实现是什么? ( B )
A. VirtualAlloc() B. HeapAlloc()
C. GlobalAlloc() D. AllocateUserPhysicalPages() 
12. 下面哪一本C++参考书最厚? ( C)
A. 《Think in C++》 B. 《深入浅出MFC》
C. 《C++ Primer》 D. 《Effective C++》
13. 当调用Windows API函数InvalidateRect,将会产生什么消息(A) 
A. WM_PAINT                      B. WM_CREATE   
C. WM_NCHITTEST               D. WM_SETFOCUS 
14. 关于virtual void Draw()=0,下面说法正确的有几个(C) 
(1)它是纯虚函数(对)
(2)它在定义它的类中不能实现(对)
(3)定义它的类不可实例化(对)
(4)如果一个类要继承一个ADT类,必须要实现其中的所有纯虚函数(错)//可以不实现,派生之后的类仍旧作为一个抽象类.
A. 1                                B. 2
C. 3                                D. 4
二、不定项选择题:(共6题,每题3分,共18分,多选、错选、漏选均不给分)
1. vector::iterator重载了下面哪些运算符? (ACD) 
A. ++ B. >>
C. *(前置) D. == 
2. CreateFile( )的功能有哪几个? (AB )
A. 打开文件 B. 创建新文件
C. 文件改名 D. 删除文件
3. 下面哪些是句柄(HANDLE)? (ABCD )
A. HINSTANCE 实例句柄B. HWND 窗口句柄
C. HDC 设备描述符号句柄  D. HFONT  字体句柄
4. 下面哪些不是OpenGL标准几何元素的绘制模式? (A )
A. GL_FOG B. GL_LINE_STRIP
C. GL_POINTS D. GL_TRIANGLE_FAN 
5. 下面哪些运算符不能被重载? (ABD )
A. 做用域运算符“::” B. 对象成员运算符“.”
C. 指针成员运算符“->” D. 三目运算符“? :” 
6. 下面哪些人曾参与了世界上第一个C++编译器的开发? ( )
A. Bill Gates B. Stanley Lippman
C. Anderson Hejlsberg D. Bjarne Stroustrup
7. 以下说法正确的是? ( ABC)
A. 头文件中的 ifndef/define/endif 是为了防止该头文件被重复引用。
B. 对于#include  <filename.h> ,编译器从标准库路径开始搜索 filename.h
   对于#include  “filename.h” ,编译器从用户的工作路径开始搜索 filename.h
C. C++语言支持函数重载,C语言不支持函数重载。函数被C++编译后在库中的名字与C    语言的不同。假设某个函数的原型为: void foo(int x, int y); 该函数被C编译器编译后在库 中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。C++提供了C连接交换指定符号extern“C”来解决名字匹配问题。
D. fopen函数只是把文件目录信息调入内存。//错,fopen是把整个文件读入内存
三、填空题:(共8题,每题3分,共24分)
1. 一个大小为320 X 192,颜色为灰度索引色的设备相关位图有______字节。如果此位图颜色为24位真彩色,则它的大小有______字节。
2. Windows API的中文意义是____  windows 应用程序接口___。
3. 计算反正弦的库函数是__ asin()____;计算浮点数绝对值的库函数是__ fabs()____;计算浮点数n次方的库函数是_ _pow()____;将浮点数转化为字符串的库函数是___ fcvt()___
4. 如果i等于5,那么( ++i ) - -的返回值是__ 6__
5. API LoadBitmap()的功能是从__ 指定的模块和或应用程序实例__中读取位图数据到内存。
6. new和_ _delete___对应,malloc和_ free___对应,他们之间_ 不能__交叉混用。calloc的功能是__ 为数组动态分配内存___,realloc的功能是_ 改变原有内存区域的大小_。
7. SendMessage和PostMessage都会向窗体发送一个消息,但SendMessage__ 将一条消息发送到指定窗口 , 立即处理__而PostMessage__ 将一条消息投递到指定窗口的消息队列 , 不需要立即处理 ___
8. 输出指定圆心、半径、边数的圆上的点:
const int nCount = 12;
const double dOrgX = 5.0,
dOrgY = 3.0;
const double dRadius = 2.0;
for( int i = 0; i < nCount; i++ )
{
double dAngle = M_PI * 2.0 / (double)nCount * i;
cout << "第" << i << "点:X = " << ________; cout << ", Y = " << __________ << endl;
}
三、判断题:(共12题,每题2分,共24分)
1. 一个类必须要有一个不带参数的构造函数。 错
2. 你不能写一个虚的构造函数。 对
3. 类里面所有的函数都是纯虚函数时才是纯虚类。 错
4. const成员函数对于任何本类的数据成员都不能进行写操作。 对
5. 函数中带默认值的参数必须位于不带默认值的参数之后。 对
6. char *p = "Test"; p[0] = 'R'; 错
7. cout << "Test"; 对
8. stl::list不支持随机访问叠代器。 对
9. stl::vector的效率比stl::list高。 错
10. VC和VC++是一回事,而VC++是一种比C++更难一些的语言。 错
11. 理论上,new和malloc造成的内存泄露都会由操作系统回收。 错 
12. 在C++中struct和class的差别很大,所以从语法上不能混用。对
四、简述题(共3题,每题5分,共15分) 
1. 请简述PeekMessage和GetMessage的区别。
答: Peekmessage和Getmessage都是向系统的消息队列中取得消息,两个函数的不同在于取不到消息的时候,若Getmessage()向消息队列中取不到消息,则程序的主线程会被OS(操作系统)挂起,等到有合适的消息时才返回;若是用Peekmessage()在消息队列中取不到消息,则程序会取得OS控制权,运行一段时间。
另外,在处理消息的时候,GetMessag()会将消息从队列中删除,而PeekMessage()可以设置最后一个参数wRemoveMsg来决定是否将消息保留在队列中。
2. 请列出你所知道的在Windows SDK平台上,实现计时功能的方法。
答:可以使用SetTimer函数创建一个计时器,SetTimer的函数原型如下:
UINT_PTR  SetTimer( HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc 
3. 请简述你所知道的const的各种用法。
答: const 常量
const 修饰类的数据成员
const 修饰指针
const 应用在函数声明中
const 应用在类成员函数
五、编程题:(共3题,第1小题7分,第2小题14分,第3小题24分)
1. 深度遍历二叉树。
struct Node
{
Node *Parent;

Node *Left, *Right;

};
void Through(Node *Root)
{
}
2. 二分法查找。

int DicFind( int *Array, int Count, int Value )
{

}
3. 写出字符串类String的默认构造函数、析构函数和重载赋值运算符。
已知类String的原型为:
class String
{
public:
String( const char *pStr = NULL ); // 默认构造函数
~String( void ); // 析构函数
String &operate = ( const String &Source ); // 重载赋值运算符
private:
char *m_pData; // 指向字符串的指针
};
 
 
今天下午的两道面试题
1。 一人岁数的3次方是四位数,四次方是六位数,并知道此人岁数的3次方和4次方用遍了0~9十个数字。编写一程序求此人的岁数。

2。对1,2,3, 4, 5 这五个数任意取出两个数,列出他们的所有组合。
public static int getAge() {
int age;
int third;
int fourth;

for (int i = 11; true; i++) {
if (i < 200) {
third = (int) Math.pow(i, 3);
fourth = (int) Math.pow(i, 4);
if (getLength(third, fourth) == 10) {
age = i;
break;
}

}
}
return age;
}

public static int getLength(int args1, int args2) {
String str1 = String.valueOf(args1);
String str2 = String.valueOf(args2);
String str = str1 + str2;
if (str.length() != 10) {
return -1;
}
int[] intarray = new int[10];
for (int i = 0; i < str.length(); i++) {
intarray[i] = Integer.parseInt(str.substring(i,i+1));
}
Arrays.sort(intarray);
if(intarray[0]!=0 && intarray[9]!=9)
return -1;

return 10;
}
第二题还更简单了

for(int i=1; i<6; i++){
for(int j=1; j<6; j++){
if(i==j){
System.out.println(j+""+j);
}else{
System.out.println(i+""+j);
System.out.println(j+""+i);
}
}
}
public class A {
// http://community.csdn.net/Expert/topic/4667/4667929.xml?temp=.57922
public static void main(String[] args) {
String t;
String[] s = new String[5];
int j = s.length;
for(int i=0; i<j; i++) {
s[i] = new Integer(i+1).toString();
}

for(int i=0; i<j; i++) {
t = s[i];
for(int a=0; a<j; a++) {
t += s[i];
System.out.println(t); 
}
System.out.println();
}
}
}
第二题还更简单了

for(int i=1; i<6; i++){
for(int j=1; j<6; j++){
if(i==j){
System.out.println(j+""+j);
}else{
System.out.println(i+""+j);
System.out.println(j+""+i);
}
}
}
============================================================
楼上的没看清题目,它是让你对1,2,3, 4, 5 这五个数任意取出两个数,列出他们的所有组合,所以重复的数字不应该算在里面。
第二题应该改为:
for(int i=1; i<6; i++){
for(int j=1; j<6; j++){
if(i==j){
break;
}else{
System.out.println(i+""+j);
System.out.println(j+""+i);
}
}
}
public class B {
public static void main(String[] args) {
for (int i = 1; i < 6; i++) {
int t = i;
for(int a = 0; a<5; a++) {
int c = a+1;
if(c == t) {
continue;
}else {
System.out.println(t*10+c);
}
}
System.out.println();
}
}
}
第二题
public class Test
{
public static void main(String[] args)
{
int[][] a=new int[5][];
for(int i=0;i<a.length;i++)
{
a[i]=new int[i+1];
}
for(int i=1;i<=a.length;i++)
{

for(int j=i+1;j<=a.length;j++)
{
System.out.print(i);
System.out.print(j+" ");
}
System.out.print(" ");
}

for(int i=a.length;i>0;i--)
{

for(int j=i-1;j>0;j--)
{
System.out.print(i);
System.out.print(j+" ");
}
System.out.print(" ");
}
}
}
 
public class Test {

public static int getDigits(String str) {
int[] intarr = new int[10];
for (int i = 0; i < 10; i++)
intarr[i] = 0;
for (int i = 0; i < str.length(); i++) {
int j = Integer.parseInt(str.substring(i, i + 1));
intarr[j] = 1;
}
int num = 0;
for (int i = 0; i < 10; i++)
num = num + intarr[i];
return num;
}

private static int getAge() {
int age;
int third;
int fourth;
for (age = 1; age < 100; age++) {
third = (int) Math.pow(age, 3);
fourth = (int) Math.pow(age, 4);
if (third < 1000 || third >= 10000)
continue;
if (fourth < 100000 || fourth >= 1000000)
continue;
String str = String.valueOf(third) + String.valueOf(fourth);
if (getDigits(str) == 10)
return age;
}
return 0;
}
}
第二道题
class Combine
{
public static void main(String[] args)
{
for(int i=1; i<5; i++)
{
for(int j=i+1; j<6; j++)

System.out.println(i+""+j);
System.out.println(j+""+i); 
}
}
}
public class Age
{
public static void main(String [] args)
{
String str1 = null;
String str2 = null;
String str3 = null;
String str4 = "0123456789";
for(int i=10;i<50;i++)
{
str1 = Integer.toString(i*i*i);
str2 = Integer.toString(i*i*i*i);
str3 = str1+str2;
if((str1.length() == 4) && (str2.length() ==6))
{
boolean flag = true;
for(int j=0;j<10;j++)
if(str3.indexOf(str4.charAt(j))==-1)
flag = false;
if(flag){
System.out.println(">>>"+i);
System.out.println(str3);
}
}
}

}
}

比赛贴 ~ 微软又一道笔试题
silver6 | 04  四月 , 2006 09:48
怎样只用 4 行代码编写出一个从字符串到长整形的转换函数?
我的方法,不过好象比 4 行多  *_#!~
long atol(char *str)
{
char c = *str;
if( !isdigit(c) ) str++;
for(long value = 0; *str != ''; value = value * 10 + (*str -'0'),str++);
return c == '-' ? -value : value ;
}
void stol(const char * des, long& num)
{
for (int base = 1, i = 0; des[i] != ''; base = 10, ++i)
{
num *= base;
num += (int)(des[i] - '0');
}
}
num 
要初始化为 0

void stol(const char * des, long& num)
{
for (int i=num=0; des[i] != ''; i++)
{
num *= 10;
num += (int)(des[i] - '0');
}
}
void stol(char *str, long &num)
{
while(*str != '')
{
num = num * 10 + (*str - '0');
str++;
}
}
void stol(const char * des, long& num)
{
char p = des[0];
for (int b = 1, pos = 1, base = 1; des[pos] != ''; b = 10, ++pos, base *= 10)
{
(num *= b) += (int)(des[pos] - '0');
}
p == '-' ? (num *= -1) : (num = (int)(des[0] - '0') * base + num);
}
改了一下
真的是微软的笔试题么?
我只用了一行。
#include <iostream>
using namespace std;

long str2long(char* p,long xxx=0L)
{
return *p==''?xxx:str2long(p,xxx*10+(*p+++0-'0'));
}

int main()
{
char *str="123456789",*p=str;
cout<<str2long(p);
getchar();
return 0;
}
STL ,四行
#include <sstream>
#include <iostream>
#include <string>

using namespace std;

long ToLong(string& s)
{
long l;
istringstream iss(s);
iss>>l;
return l;
}
int main(int argc, _TCHAR* argv[])
{
string s = "-12356";
cout<<ToLong(s);
return 0;
}
谢谢刚才上面的帖子提醒负数的问题,我更正了,还是只用一行:
#include <iostream>
using namespace std;

long str2long(char* p,long xxx=0L,bool IsPositive=true)
{
return *p==''?(IsPositive?xxx:xxx*(-1)):(*p=='-'?str2long(++p,0L,false):str2long(p,xxx*10+*p+++0-'0',IsPositive));
}

int main()
{
char *str="-123456789",*p=str;
cout<<str2long(p);
getchar();
return 0;
}

你可能感兴趣的:(C++,c,面试题)