cc++笔试题面试题.docx
《cc++笔试题面试题.docx》由会员分享,可在线阅读,更多相关《cc++笔试题面试题.docx(105页珍藏版)》请在冰点文库上搜索。
cc++笔试题面试题
2010C、C++笔试题大全,被问的概率几乎100%。
很少有真正精通了C语言编程的学员,一般都有或多或少概念不是完全清楚的问题,特别是一些需要丰富的实战经验才能体会和明白的问题,如字符串,指针,类型转换,定义指向函数的指针类型,这也是导致学习C困难的一个原因。
下面有几个简单测试将能发现你对C语言的掌握情况。
1)intx=35;
charstr[10];
//问:
strlen(str)和sizeof(str)的值分别是多少?
答:
strlen(str)值不确定,strlen根据'\0'确定字符串是否结束。
sizeof(str)=10sizeof一个数组为数组长度
strcpy(str,"www.it315.org"/*共13个字母*/);
//问:
此时x和strlen(str)的值分别是多少?
答:
x为35
strcpy(char*dest,constchar*src)
根据src来复制dest,依照src的'\0'决定复制的长度,而dest必须要提供足够的长度,这里会引起溢出,strlen返回13,但是数组外部的数据已经被破坏
strlen的值为13,在VC++环境下,x的值是要改变的(其他编译器下没试,).虽然表面上看来,在程序中并没有修改x的值,但是实际运行的结果是上面的x的值发生了修改,这是因为strcpy以后,把多余的数据拷贝进了str的邻居(int类型的x)中,所以x的数据也就变了.这是一个曾让我刻骨铭心的问题,在我刚出道时遇到这个问题,虽然在朋友的帮助下解决了这个问题,但一直不明白x的值为何变了,只有最后走上培训教师的岗位,才开始梳理自己曾经的困惑,才开始总结以前的经验供学员们借鉴.我觉得这个题目的价值非常之大,它能引起学员对字符串拷贝越界问题的足够重视,并且通过这个问题更能明白字符串的处理是怎么回时,更能明白字符串与字符数组的关系:
字符串就是一个字符数组,只是把这个字符数组用在处理串的函数中时,这些函数不考虑数组的长度,只是记住数组的首地址,从首地址开始处理,并在遇到0时结束处理,
3)charstr[10];
str="it315.org";//alsocanuse:
memcpy(str,"it315.org")
//编译能通过吗?
答:
数组不能赋值,只能初始化。
charstr[10]="it315.org";
而且初始化时编译器会检查数组的长度与初始化串的长度是否匹配
4)char*pstr;
strcpy(pstr,"http:
//www.it315.org");//需要初始化并分配空间
//上句编译能通过吗?
运行时有问题吗?
答:
可以通过编译,但是pstr指向了常量区,运行时最好只做读操作,写操作不保险。
编译可以通过,但是pstr没有进行有效的初始化,它指向了一个不确定的内存区,运行时会出现内存不可写错误!
constchar*p1;
char*constp2;//const指针必须初始化
//上面两句有什么区别吗?
答:
constchar*和charconst*一样,都是表示指向常量的字符指针。
char*const表示指向字符的常量指针
p1=(constchar*)str;
//如果是p1=str;编译能够通过吗?
明白为什么要类型转换?
类型转换的本质是什么?
答:
可以通过编译。
关于常量与非常量指针的关系是这样的:
const指针可以指向const或者非const区域,不会造成什么问题。
非const指针不能指向const区域,会引起错误。
(呵呵,这个问题,很经典)
strcpy(p1,"abc");//编译能够通过吗?
答:
不能通过,strcpy(char*,constchar*);char*不能指向constchar*
注意:
非const指针不能指向const区域,会引起错误。
printf("%d",str);//有问题吗?
答:
没有问题,输出的是str的地址信息
Char*pstr;
pstr=3000;//编译能过吗?
如果不行,该如何修改以保证编译通过呢?
答:
不能通过,char*pstr表示pstr是个字符指针,不能指向3000的整形变量。
修改的话,可以这样:
pstr=(char*)3000,把pstr指向3000这个地址;
longy=(long)pstr;//可以这样做吗?
答:
可以,y的值为pstr所指的地址。
不过如果是纯粹要地址的话,最好是用unsignedlong。
int*p=str;
*p=0x00313200;
printf("%s",str);//会是什么效果?
提示0x31对应字符'1',0x32对应字符'2'。
答:
首先编译未必会过关,有些编译器可能不允许int*直接指向char*。
最好是改为int*p=(int*)str;
过关了效果就是什么东西都没有。
int*p=str;p为str所指的地址,*p表示修改了str所指向的内存。
由于sizeof(int)在32位机上,int有4个字节(其实具体要看编译器的配置文件,好像是limit.h,一般是4个字节)所以修改了str[0]-str[3]
由于0x00313200头尾都是0,所以字符串为'\0'开头,什么都打印不出来。
这里有个Big-endin和little-endin的问题。
以0x31323334为例
little-endin的机器上面,0x31323334在内存中排列顺序为34333231,输出为4321,如INTEL芯片的pc
big-endin机器上面为31323334,输出为1234,如IBMPOWERPC
p=3000;//p+1的结果会是多少?
答:
3000+sizeof(int);指针+1均为原来地址加上sizeof(指针所指的数据类型)
char*pc=newchar[100];//上述语句在内存中占据几个内存块,怎样的布局情况?
答:
本身pc会占用函数栈一个4字节的指针长度(具体是否为4个字节要看机器和编译器)。
new会在堆上申请100个字节sizeof(char)的连续空间。
voidtest(char**p)
{
*p=newchar[100];
}//这个编译函数有问题吗?
外面要调用这个函数,该怎样传递参数?
答:
该程序没有问题。
需要在函数中对指针所指的地址进行变化是必须传入指针的地址。
原因是这样的:
如果传入的为指针本身,在函数调用的时候,实参会被复制一个实例,这样就不是原来的指针了,对该指针本身进行的任何改变都不能传递回去了。
可以这样理解,如果传入的参数为int,那么对int本身的值的改变就传不回去啦,加个*也是一样的。
//能明白typedefint(*PFUN)(intx,inty)及其作用吗?
答:
定义了一个函数指针类型的宏,这样PFUN就表示指向返回值为int,且同时带2个int参数的函数指针类型了。
可以用来定义这样的变量:
比如有个函数为intfun(intx,inty);
PFUNp=fun;
补充:
:
函数指针最大的用处在于它可以被一个模板方法调用,这是我在学java的设计模式时领悟到的.例如,有两个函数的流程结构完全一致,只是内部调用的具体函数不同,如下所示:
voidfunc1()
{
//一段流程代码和面向方面的代理,如安全检查,日志记录等
intsum=add(x,y);
//一段流程代码和面向方面的代理,如安全检查,日志记录等
}
voidfunc2()
{
//与func1完全相同的一段流程代码和面向方面的代理,如安全检查,日志记录等
intdifference=sub(x,y);
//与func1完全相同的一段流程代码和面向方面的代理,如安全检查,日志记录等
}
那么,可以只定义一个函数,如下所示
voidfunc(PFUNCp)
{
//与func1完全相同的一段流程代码和面向方面的代理,如安全检查,日志记录等
intdifference=p(x,y);
//与func1完全相同的一段流程代码和面向方面的代理,如安全检查,日志记录等
}
调用程序在调用时,让参数p分别指向add和sub函数就可以了.
以下是腾讯的笔试面试题:
]请定义一个宏,比较两个数a、b的大小,不能使用大于、小于、if语句
2、如何输出源文件的标题和目前执行行的行数
3、两个数相乘,小数点后位数没有限制,请写一个高精度算法
4、写一个病毒
5、有A、B、C、D四个人,要在夜里过一座桥。
他们通过这座桥分别需要耗时1、2、5、10分钟,只有一支手电,并且同时最多只能两个人一起过桥。
请问,如何安排,能够在17分钟内这四个人都过桥?
2008年腾讯招聘
选择题(60)
c/c++oslinux方面的基础知识c的Sizeof函数有好几个!
程序填空(40)
1.(20)4空x5
不使用额外空间,将A,B两链表的元素交叉归并
2.(20)4空x5
MFC将树序列化转存在数组或链表中!
1,计算a^b<<2(运算符优先级问题)
2根据先序中序求后序
3a[3][4]哪个不能表示a[1][1]:
*(&a[0][0])*(*(a+1)+1)*(&a[1]+1)*(&a[0][0]+4)
4for(inti...)
for(intj...)
printf(i,j);
printf(j)
会出现什么问题
5for(i=0;i<10;++i,sum+=i);的运行结果
610个数顺序插入查找二叉树,元素62的比较次数
710个数放入模10hash链表,最大长度是多少
8fun((exp1,exp2),(exp3,exp4,exp5))有几个实参
9希尔冒泡快速插入哪个平均速度最快
10二分查找是顺序存储链存储按value有序中的哪些
11顺序查找的平均时间
12*p=NULL*p=newchar[100]sizeof(p)各为多少
13频繁的插入删除操作使用什么结构比较合适,链表还是数组
14enum的声明方式
151-20的两个数把和告诉A,积告诉B,A说不知道是多少,
B也说不知道,这时A说我知道了,B接着说我也知道了,问这两个数是多少
大题:
1把字符串转换为小写,不成功返回NULL,成功返回新串
char*toLower(char*sSrcStr)
{
char*sDest=NULL;
if(__1___)
{
intj;
sLen=strlen(sSrcStr);
sDest=new[_______2_____];
if(*sDest==NULL)
returnNULL;
sDest[sLen]='\0';
while(_____3____)
sDest[sLen]=toLowerChar(sSrcStr[sLen]);
}
returnsDest;
}
2把字符串转换为整数例如:
"-123"->-123
main()
{
.....
if(*string=='-')
n=____1______;
else
n=num(string);
.....
}
intnum(char*string)
{
for(;!
(*string==0);string++)
{
intk;
k=__2_____;
j=--sLen;
while(__3__)
k=k*10;
num=num+k;
}
returnnum;
}
附加题:
1linux下调试core的命令,察看堆栈状态命令
2写出socks套接字服务端客户端通讯程序
3填空补全程序,按照我的理解是添入:
win32调入dll的函数名
查找函数入口的函数名找到函数的调用形式
把formView加到singledoc的声明将singledoc加到app的声明
4有关系s(sno,sname)c(cno,cname)sc(sno,cno,grade)
1问上课程"db"的学生no
2成绩最高的学生号
3每科大于90分的人数
主要是c/c++、数据结构、操作系统等方面的基础知识。
好像有sizeof、树等选择题。
填空题是补充完整程序。
附加题有写算法的、编程的、数据库sql语句查询的。
还有一张开放性问题。
请定义一个宏,比较两个数a、b的大小,不能使用大于、小于、if语句
#defineMax(a,b)(a/b)?
a:
b
如何输出源文件的标题和目前执行行的行数
intline=__LINE__;
char*file=__FILE__;
cout<<"filenameis"<<(file)<<",lineis"<两个数相乘,小数点后位数没有限制,请写一个高精度算法
写一个病毒
while
(1)
{
int*p=newint[10000000];
}
不使用额外空间,将 A,B两链表的元素交叉归并
将树序列化 转存在数组或 链表中
struct st{
int i;
short s;
char c;
};
sizeof(struct st);
8
char * p1;
void * p2;
int p3;
char p4[10];
sizeof(p1...p4) =?
4,4,4,10
二分查找
快速排序
双向链表的删除结点
有12个小球,外形相同,其中一个小球的质量与其他11个不同
给一个天平,问如何用3次把这个小球找出来
并且求出这个小球是比其他的轻还是重
解答:
哈哈,据说这是微软前几年的一个面试题。
很经典滴啊!
三次一定能求出来,而且能确定是重还是轻。
数据结构的知识还没怎么学透,不过这个题我到是自己研究过,可以分析下。
将12个球分别编号为a1,a2,a3.......a10,a11,a12.
第一步:
将12球分开3拨,每拨4个,a1~a4第一拨,记为b1, a5~a6第2拨,记为b2,其余第3拨,记为b3;
第二步:
将b1和b2放到天平两盘上,记左盘为c1,右为c2;这时候分两中情况:
1.c1和c2平衡,此时可以确定从a1到a8都是常球;然后把c2拿空,并从c1上拿下a4,从a9到a12四球里随便取三球,假设为a9到a11,放到c2上。
此时c1上是a1到a3,c2上是a9到a11。
从这里又分三种情况:
A:
天平平衡,很简单,说明没有放上去的a12就是异球,而到此步一共称了两次,所以将a12随便跟11个常球再称一次,也就是第三次,马上就可以确定a12是重还是轻;
B:
若c1上升,则这次称说明异球为a9到a11三球中的一个,而且是比常球重。
取下c1所有的球,并将a8放到c1上,将a9取下,比较a8和a11(第三次称),如果平衡则说明从c2上取下的a9是偏重异球,如果不平衡,则偏向哪盘则哪盘里放的就是偏重异球;
C:
若c1下降,说明a9到a11里有一个是偏轻异球。
次种情况和B类似,所以接下来的步骤照搬B就是;
2.c1和c2不平衡,这时候又分两种情况,c1上升和c1下降,但是不管哪种情况都能说明a9到a12是常球。
这步是解题的关键。
也是这个题最妙的地方。
A:
c1上升,此时不能判断异球在哪盘也不能判断是轻还是重。
取下c1中的a2到a4三球放一边,将c2中的a5和a6放到c1上,然后将常球a9放到c2上。
至此,c1上是a1,a5和a6,c2上是a7,a8和a9。
此时又分三中情况:
1)如果平衡,说明天平上所有的球都是常球,异球在从c1上取下a2到a4中。
而且可以断定异球轻重。
因为a5到a8都是常球,而第2次称的时候c1是上升的,所以a2到a4里必然有一个轻球。
那么第三次称就用来从a2到a4中找到轻球。
这很简单,随便拿两球放到c1和c2,平衡则剩余的为要找球,不平衡则哪边低则哪个为要找球;
2)c1仍然保持上升,则说明要么a1是要找的轻球,要么a7和a8两球中有一个是重球(这步懂吧?
好好想想,很简单的。
因为a9是常球,而取下的a2到a4肯定也是常球,还可以推出换盘放置的a5和a6也是常球。
所以要么a1轻,要么a7或a8重)。
至此,还剩一次称的机会。
只需把a7和a8放上两盘,平衡则说明a1是要找的偏轻异球,如果不平衡,则哪边高说明哪个是偏重异球;
3)如果换球称第2次后天平平衡打破,并且c1降低了,这说明异球肯定在换过来的a5和a6两求中,并且异球偏重,否则天平要么平衡要么保持c1上升。
确定要找球是偏重之后,将a5和a6放到两盘上称第3次根据哪边高可以判定a5和a6哪个是重球;
B:
第1次称后c1是下降的,此时可以将c1看成c2,其实以后的步骤都同A,所以就不必要再重复叙述了。
至此,不管情况如何,用且只用三次就能称出12个外观手感一模一样的小球中有质量不同于其他11球的偏常的球。
而且在称的过程中可以判定其是偏轻还是偏重。
给一个奇数阶N幻方,填入数字1,2,3...N*N,使得横竖斜方向上的和都相同
答案:
#include
#include
#include
usingnamespacestd;
intmain()
{
intn;
cin>>n;
inti;
int**Matr=newint*[n];//动态分配二维数组
for(i=0;iMatr[i]=newint[n];//动态分配二维数组
//j=n/2代表首行中间数作为起点,即1所在位置
intj=n/2,num=1;//初始值
i=0;
while(num!
=n*n+1)
{
//往右上角延升,若超出则用%转移到左下角
Matr[(i%n+n)%n][(j%n+n)%n]=num;
//斜行的长度和n是相等的,超出则转至下一斜行
if(num%n==0)
i++;
else
{
i--;
j++;
}
num++;
}
for(i=0;i{
for(j=0;jcout<cout<}
for(i=0;idelete[]Matr[i];
return1;
}
腾讯的一道面试题:
(与XX相似,可惜昨天XX死在这方面了)////
在一个文件中有 10G 个整数,乱序排列,要求找出中位数。
内存限制为 2G。
只写出思路即可。
答案:
1, 把整数分成256M段,每段可以用64位整数保存该段数据个数,256M*8 = 2G内存,先清0
2,读10G整数,把整数映射到256M段中,增加相应段的记数
3,扫描256M段的记数,找到中位数的段和中位数的段前面所有段的记数,可以把其他段的内存释放
4,因中位数段的可能整数取值已经比较小(如果是32bit整数,当然如果是64bit整数的话,可以再次分段),对每个整数做一个记数,再读一次10G整数,只读取中位数段对应的整数,并设置记数。
5,对新的记数扫描一次,即可找到中位数。
如果是32bit整数,读10G整数2次,扫描256M记数一次,后一次记数因数量很小,可以忽略不记
(设是32bit整数,按无符号整数处理
整数分成256M段?
整数范围是0 - 2^32 - 1 一共有4G种取值,4G/256M = 16,每16个数算一段 0-15是1段,16-31是一段,...
整数映射到256M段中?
如果整数是0-15,则增加第一段记数,如果整数是16-31,则增加第二段记数,...
其实可以不用分256M段,可以分的段数少一写,这样在扫描记数段时会快一些,还能节省一些内存)
腾讯题二:
一个文件中有40亿个整数,每个整数为四个字节,内存为1GB,写出一个算法:
求出这个文件里的整数里不包含的一个整数
答:
方法一:
4个字节表示的整数,总共只有2^32约等于4G个可能。
为了简单起见,可以假设都是无符号整数。
分配500MB内存,每一bit代表一个整数,刚好可以表示完4个字节的整数,初始值为0。
基本思想每读入一个数,就把它对应的bit位置为1,处理完40G个数后,对500M的内存遍历,找出一个bit为0的位,输出对应的整数就是未出现的。
算法流程:
1)分配500MB内存buf,初始化为0
2)unsigned int x=0x1;
for each int j in file
buf=buf¦x< end
(3) for(unsigned int i=0; i <= 0xffffffff; i++)
if (!
(buf & x<
{
output(i);
break;
}
以上只是针对无符号的,有符号的整数可以依此类推。
方法二:
文件可以分段读啊,这个是O(2n)算法,应该是很快的了,而且空间也允许的。
不过还可以构造更快的方法的,更快的方法主要是针对定位输出的整数优化算法。
思路大概是这样的,把值空间等分成若干个值段,比如值为无符号数,则
00000000H-00000FFFH
00001000H-00001FFFH
......
0000F000H-0000FFFFH
.....
FFFFF000H-FFFFFFFFH
这样可以订立一个规则,在一个值段范围内的数第一次出现时,对应值段指示值Xn=Xn+1,如果该值段的所有整数都出现过,则Xn=1000H,这样后面输出定位时就可以直接跳过这个值段了,因为题目仅仅要求输出一个,这样可以大大减少后面对标志数值的遍历步骤。
理论上值段的划分有一定的算法可以快速的实现,比如利用位运算直接定位值段对应值进行计算。
腾讯面试题:
有1到10w这10w个数,去除2个并打乱次序,如何找出那两个数。
(不准用位图!
!
)
位图解决:
位图的方法如下
假设待处理数组